|
在.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 [JsonConverter(typeof(YearMonthJsonConverter))]
- 5 public 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】 我们会及时删除侵权内容,谢谢合作! |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|