zoukankan      html  css  js  c++  java
  • 一个代表年月的类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);
        }
    }
    

  • 相关阅读:
    2021牛客暑期多校训练营5
    二分图知识点温习
    Codeforces Round #735 (Div. 2)
    牛客比赛订正(3,4)
    Harbour.Space Scholarship Contest 2021-2022 (Div. 1 + Div. 2) Editorial题解
    关于球的相关知识
    AtCoder Beginner Contest 210题解
    P7077 [CSP-S2020] 函数调用
    偏序问题学习笔记
    P1606 [USACO07FEB]Lilypad Pond G
  • 原文地址:https://www.cnblogs.com/deerchao/p/1717228.html
Copyright © 2011-2022 走看看