• 一个代表年月的类YearMonth


    测试(VS自带框架):

    using System;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    /// <summary>
    ///This is a test class for YearMonthTest and is intended
    ///to contain all YearMonthTest Unit Tests
    ///</summary>
    [TestClass()]
    public class YearMonthTest
    {
    
        /// <summary>
        ///A test for YearMonth Constructor
        ///</summary>
        [TestMethod()]
        public void YearMonthConstructorTest()
        {
            var date = new DateTime(2000, 1, 1);
            var target = new YearMonth(date);
            Assert.AreEqual(2000, target.Year);
            Assert.AreEqual(1, target.Month);
        }
    
        /// <summary>
        ///A test for YearMonth Constructor
        ///</summary>
        [TestMethod()]
        public void YearMonthConstructorTest1()
        {
            YearMonth target = new YearMonth(2010, 4);
            Assert.AreEqual(2010, target.Year);
            Assert.AreEqual(4, target.Month);
        }
    
        /// <summary>
        ///A test for GetDate
        ///</summary>
        [TestMethod()]
        public void GetDateTest()
        {
            var target = new YearMonth(2010, 5);
            var expected = new DateTime(2010, 5, 3);
            var actual = target.GetDate(3);
            Assert.AreEqual(expected, actual);
        }
    
        [TestMethod]
        public void GetDateThrows()
        {
            Assert.IsTrue(Throws(typeof(ArgumentOutOfRangeException), () => new YearMonth(2012, 12).GetDate(32)));
        }
    
        /// <summary>
        ///A test for ToString
        ///</summary>
        [TestMethod()]
        public void ToStringTest()
        {
            var target = new YearMonth(2008, 3);
    
            Assert.AreEqual("200803", target.ToString());
        }
    
        /// <summary>
        ///A test for IsValid
        ///</summary>
        [TestMethod()]
        public void IsValidTest()
        {
            Assert.IsTrue(new YearMonth(2008, 12).IsValid);
    
            Assert.IsFalse(new YearMonth(2010, 13).IsValid);
            Assert.IsFalse(new YearMonth(2010, 0).IsValid);
            Assert.IsFalse(new YearMonth(2010, -3).IsValid);
    
            Assert.IsFalse(new YearMonth(0, 3).IsValid);
            Assert.IsFalse(new YearMonth(-2, 3).IsValid);
            Assert.IsTrue(new YearMonth(9999, 12).IsValid);
            Assert.IsFalse(new YearMonth(10000, 1).IsValid);
    
            Assert.IsFalse(new YearMonth(-2, -3).IsValid);
        }
    
        /// <summary>
        ///A test for Equals
        ///</summary>
        [TestMethod()]
        public void EqualsTest()
        {
            var target = new YearMonth(2010, 4);
            Assert.IsTrue(target.Equals(new YearMonth(2010, 4)));
            Assert.IsFalse(target.Equals(new YearMonth(2010, 3)));
    
            Assert.IsFalse(target.Equals(string.Empty));
        }
    
        /// <summary>
        ///A test for TryParse
        ///</summary>
        [TestMethod()]
        public void TryParseTest()
        {
            YearMonth result;
            var success = YearMonth.TryParse("201012", out result);
            Assert.IsTrue(success);
            Assert.AreEqual(new YearMonth(2010, 12), result);
    
            success = YearMonth.TryParse("", out result);
            Assert.IsFalse(success);
            Assert.AreEqual(result, null);
        }
    
        /// <summary>
        ///A test for Parse
        ///</summary>
        [TestMethod()]
        public void ParseTest()
        {
            Assert.AreEqual(new YearMonth(2008, 12), YearMonth.Parse("200812"));
        }
    
        [TestMethod]
        public void ParseThrows()
        {
            Assert.IsTrue(Throws(typeof(ArgumentNullException), () => YearMonth.Parse(null)));
            Assert.IsTrue(Throws(typeof(ArgumentException), () => YearMonth.Parse("")));
            Assert.IsTrue(Throws(typeof(ArgumentException), () => YearMonth.Parse("aaaaaa")));
            Assert.IsTrue(Throws(typeof(ArgumentException), () => YearMonth.Parse("20121221")));
        }
    
    
    
        /// <summary>
        ///A test for AddYears
        ///</summary>
        [TestMethod()]
        public void AddYearsTest()
        {
            Assert.AreEqual(new YearMonth(2011, 11), new YearMonth(2008, 11).AddYears(3));
            Assert.AreEqual(new YearMonth(2011, 11), new YearMonth(2011, 11).AddYears(0));
            Assert.AreEqual(new YearMonth(2011, 11), new YearMonth(2012, 11).AddYears(-1));
        }
    
        /// <summary>
        ///A test for AddMonths
        ///</summary>
        [TestMethod()]
        public void AddMonthsTest()
        {
            Assert.AreEqual(new YearMonth(2010, 4), new YearMonth(2010, 3).AddMonths(1));
            Assert.AreEqual(new YearMonth(2010, 4), new YearMonth(2010, 4).AddMonths(0));
            Assert.AreEqual(new YearMonth(2010, 4), new YearMonth(2010, 8).AddMonths(-4));
    
            Assert.AreEqual(new YearMonth(2010, 1), new YearMonth(2009, 11).AddMonths(2));
            Assert.AreEqual(new YearMonth(2009, 11), new YearMonth(2010, 1).AddMonths(-2));
    
            Assert.AreEqual(new YearMonth(2009, 12), new YearMonth(2010, 1).AddMonths(-1));
            Assert.AreEqual(new YearMonth(2010, 1), new YearMonth(2009, 12).AddMonths(1));
        }
        
        static bool Throws(Type exceptionType, Action action)
        {
            try
            {
                action();
            }
            catch (Exception ex)
            {
                if (ex.GetType() == exceptionType || ex.GetType().IsSubclassOf(exceptionType))
                    return true;
    
                throw;
            }
            return false;
        }
    }
    


    代码:

    using System;
    using System.Linq;
    
    /// <summary>
    /// 代表一个年份中的某个指定月份. 如:2008年10月.
    /// </summary>
    public sealed class YearMonth
    {
        private readonly int _year;
        private readonly int _month;
    
        /// <summary>
        /// 用指定的年份和月份构造一个 YearMonth 对象.
        /// </summary>
        /// <param name="year">年号,如2012.</param>
        /// <param name="month">月份,1代表1月,12代表12月.</param>
        public YearMonth(int year, int month)
        {
            _year = year;
            _month = month;
        }
    
        /// <summary>
        /// 根据指定日期所在的月份构造一个 YearMonth 对象.
        /// </summary>
        /// <param name="date">指定的日期.它的年份和月份部分会作为构造的YearMonth的值使用.</param>
        public YearMonth(DateTime date)
        {
            _year = date.Year;
            _month = date.Month;
        }
    
        public int Year
        {
            get { return _year; }
        }
    
        public int Month
        {
            get { return _month; }
        }
    
        /// <summary>
        /// 是否是有效的值.无效的值可能是年份小于1, 或年份大于9999, 或月份小于1, 或月份大于12.
        /// </summary>
        public bool IsValid
        {
            get
            {
                return 0 < Year && Year < 10000
                       && 0 < Month && Month < 13;
            }
        }
    
        /// <summary>
        /// 获取代表该月指定日期的 DateTime 对象
        /// </summary>
        /// <param name="day">日期,范围1到31.</param>
        /// <exception cref="ArgumentOutOfRangeException">day大于本月的天数.</exception>
        public DateTime GetDate(int day)
        {
            return new DateTime(Year, Month, day);
        }
    
        /// <summary>
        /// 返回一个新YearMonth对象,其值为当前对象的值加上指定个年份
        /// </summary>
        /// <param name="value">要在当前年月上增加多少年</param>
        public YearMonth AddYears(int value)
        {
            return new YearMonth(Year + value, Month);
        }
    
        /// <summary>
        /// 返回一个新YearMonth对象,其值为当前对象的值加上指定个月份
        /// </summary>
        /// <param name="value">要在当前年月上增加多少个月</param>
        public YearMonth AddMonths(int value)
        {
            var totalMonths = Year * 12 + Month + value;
    
            var year = totalMonths / 12;
            var month = totalMonths % 12;
            if (month == 0)
            {
                month = 12;
                year--;
            }
    
            return new YearMonth(year, month);
        }
    
        /// <summary>
        /// 返回数字代表的年月份值,共6位数字,前4位代表年份,后两位代表月份,如:200805
        /// </summary>
        public override string ToString()
        {
            return "{0:D4}{1:D2}".FormatWith(Year, Month);
        }
    
        /// <summary>
        /// 判断一个是否与当前对象代表相同的值的YearMonth对象.
        /// </summary>
        public override bool Equals(object obj)
        {
            return Equals(obj as YearMonth);
        }
    
        /// <summary>
        ///判断另一个YearMonth对象是否与当前对象代表相同的值. 
        /// </summary>
        public bool Equals(YearMonth rhs)
        {
            if (ReferenceEquals(null, rhs))
                return false;
            if (ReferenceEquals(this, rhs))
                return true;
    
            return _year == rhs._year &&
                _month == rhs._month;
        }
    
        public override int GetHashCode()
        {
            unchecked
            {
                return (_year * 397) ^ _month;
            }
        }
    
        public static bool operator ==(YearMonth lhs, YearMonth rhs)
        {
            return Object.Equals(lhs, rhs);
        }
    
        public static bool operator !=(YearMonth lhs, YearMonth rhs)
        {
            return !(lhs == rhs);
        }
    
        public static bool TryParse(string s, out YearMonth result)
        {
            try
            {
                result = Parse(s);
                return true;
            }
            catch (ArgumentException)
            {
                result = null;
                return false;
            }
        }
    
        /// <summary>
        /// 通过解析字符串构造一个YearMonth对象.
        /// </summary>
        /// <param name="s">要解析的字符串.</param>
        /// <exception cref="ArgumentNullException">s为null.</exception>
        /// <exception cref="ArgumentException">s包含非数字字符,或s的长度不为6.</exception>
        public static YearMonth Parse(string s)
        {
            if (s == null)
                throw new ArgumentNullException("s");
            if (s.Length != 6 || s.Any(x => x < '0' || x > '9'))
                throw new ArgumentException("s应该是6位数字.");
    
            var year = int.Parse(s.Substring(0, 4));
            var month = int.Parse(s.Substring(4));
    
            return new YearMonth(year, month);
        }
    }
    

    辅助方法:

    public static class StringExtensions
    {
        public static string FormatWith(this string format, object arg0)
        {
            return string.Format(format, arg0);
        }
    
        public static string FormatWith(this string format, object arg0, object arg1)
        {
            return string.Format(format, arg0, arg1);
        }
    
        public static string FormatWith(this string format, object arg0, object arg1, object arg2)
        {
            return string.Format(format, arg0, arg1, arg2);
        }
    }
    

  • 相关阅读:
    day 66 crm(3) 自创组件stark界面展示数据
    day 65 crm(2) admin源码解析,以及简单的仿造admin组件
    用 Python+nginx+django 打造在线家庭影院
    django -admin 源码解析
    day 64 crm项目(1) admin组件的初识别以及应用
    云链接 接口不允许 情况 解决方法 mysql Host is not allowed to connect to this MySQL server解决方法
    day 56 linux的安装python3 ,虚拟环境,mysql ,redis
    day55 linux 基础以及系统优化
    Codeforces 989 P循环节01构造 ABCD连通块构造 思维对云遮月参考系坐标轴转换
    Codeforces 990 调和级数路灯贪心暴力 DFS生成树两子树差调水 GCD树连通块暴力
  • 原文地址:https://www.cnblogs.com/deerchao/p/1717228.html
Copyright © 2020-2023  润新知