薛广山 发表于 2023-7-25 14:49:11

给C#新增一个时间类型: YearMonth

在.Net Framework中,我们常用的时间类型是DateTime。直到.Net6微软加入了两个新的时间类型:DateOnly和TimeOnly,才弥补了之前的不足。DateOnly:表示仅日期。比如:某人的生日,我只关心日期,就适合用DateOnly。
TimeOnly:表示仅时间。比如:每天定时执行某个任务,我只关心时间,就适合用TimeOnly。
由此可见,DateOnly和TimeOnly都有相应的应用场景。可小编在实际项目中遇到了这样的业务场景:需要每月给客户生成月账单。这里我所关心的是某个月份,于是我首先想到用DateOnly表示(不考虑字符串)。
var date = new DateOnly(2023, 2, 1);    // 代表2023年2月1日 虽然DateOnly可用,但从字面理解和表现形式上还是略显尴尬。 DateOnly真正表达的是某一天并不是某个月, 在代码层面也容易混淆,所以并不符合小编的心理期望。经过一番纠结和思考,小编决定自己动手创建一个表示年/月的时间类型:YearMonth。
var ym = new YearMonth(2023, 2);// 代表2023年2月 YearMonth的源码如下:
1/// <summary>
2/// 表示年/月的时间类型
3/// </summary>
4
5public readonly struct YearMonth
6{
7      public int Year { get; }
8
9      public int Month { get; }
10
11      public YearMonth(int year, int month)
12      {
13          Year = year;
14          Month = month;
15      }
16         
17      public YearMonth AddMonths(int value)
18      {
19          var date = new DateOnly(Year, Month, 1);
20          return FromDateOnly(date.AddMonths(value));
21      }
22
24      public YearMonth AddYears(int value)
25      {
26          var date = new DateOnly(Year, Month, 1);
27          return FromDateOnly(date.AddYears(value));
28      }
29
30      public DateOnly FirstDay()
31      {
32          return new DateOnly(Year, Month, 1);
33      }
34
35      public DateOnly LastDay()
36      {
37          var nextMonth = AddMonths(1);
38          var date = new DateOnly(nextMonth.Year, nextMonth.Month, 1);
39          return date.AddDays(-1);
40      }
41
42      public int DaysInMonth()
43      {
44          return DateTime.DaysInMonth(Year, Month);
45      }
46
47      public static YearMonth Current
48      {
49          get { return FromDateTime(DateTime.Now); }
50      }
51
52      public static YearMonth UtcCurrent
53      {
54          get { return FromDateTime(DateTime.UtcNow); }
55      }
56
57      public static YearMonth FromDateOnly(DateOnly dateOnly)
58      {
59          return new YearMonth(dateOnly.Year, dateOnly.Month);
60      }
61
62      public static YearMonth FromDateTime(DateTime dateTime)
63      {
64          return new YearMonth(dateTime.Year, dateTime.Month);
65      }
66         
67      public static YearMonth FromString(string s)
68      {
69          if (DateTime.TryParse(s, out var date))
70          {
71            return FromDateTime(date);
72          }
73          throw new ArgumentException("format is error", nameof(s));
74      }
75
76      public override string ToString()
77      {
78          return $"{Year.ToString().PadLeft(4, '0')}-{Month.ToString().PadLeft(2, '0')}";
79      }
80
81      public static bool operator ==(YearMonth left, YearMonth right)
82      {
83          return left.Year == right.Year && left.Month == right.Month;
84      }
85
86      public static bool operator !=(YearMonth left, YearMonth right)
87      {
88          return !(left.Year == right.Year && left.Month == right.Month);
89      }
90
91      public static bool operator >=(YearMonth left, YearMonth right)
92      {
93          return (left.Year > right.Year) || (left.Year == right.Year && left.Month >= right.Month);
94      }
95
96      public static bool operator <=(YearMonth left, YearMonth right)
97      {
98          return (left.Year < right.Year) || (left.Year == right.Year && left.Month <= right.Month);
99      }
100
101      public static bool operator >(YearMonth left, YearMonth right)
102      {
103          return (left.Year > right.Year) || (left.Year == right.Year && left.Month > right.Month);
104      }
105
106      public static bool operator <(YearMonth left, YearMonth right)
107      {
108          return (left.Year < right.Year) || (left.Year == right.Year && left.Month < right.Month);
109      }
110               
111      public override bool Equals(object obj)
112      {
113          return base.Equals(obj);
114      }
115
116      public override int GetHashCode()
117      {
118          return base.GetHashCode();
119      }      
120 }  至此,上面的YearMonth时间类型已经满足小编的开发需要,当然也可以根据需求继续扩展其它功能。

 
 
本文已同步至作者的微信公众号:玩转DotNet
感谢点赞并关注


来源:https://www.cnblogs.com/fengjq/archive/2023/07/25/17578772.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 给C#新增一个时间类型: YearMonth