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

这篇具有很好参考价值的文章主要介绍了给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  [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 }

其中特性 [JsonConverter(typeof(YearMonthJsonConverter))]用于Json序列化和反序列化。

 1 public class YearMonthJsonConverter : JsonConverter<YearMonth>
 2 {
 3      public override YearMonth Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
 4      {
 5          return YearMonth.FromString(reader.GetString());
 6      }
 7 
 8      public override void Write(Utf8JsonWriter writer, YearMonth value, JsonSerializerOptions options)
 9      {
10          writer.WriteStringValue(value.ToString());
11      }
12 }

 YearMonth的一些用法示例:

1 var ym = new YearMonth(2023, 2);
2 int n = ym.DaysInMonth();     //n:28
3 DateOnly d1 = ym.FirstDay();  //d1:2023/2/1
4 DateOnly d2 = ym.LastDay();   //d2:2023/2/28
5 string str = ym.ToString();   //str:2023-02
6 YearMonth ym2 = ym.AddMonths(1);  //ym2: 2023-03
7 YearMonth ym3 = YearMonth.FromDateOnly(new DateOnly(2023, 2, 8)); //ym3: 2023-02 
8 YearMonth ym4 = YearMonth.FromDateTime(new DateTime(2023, 2, 8, 12, 23, 45)); //ym4: 2023-02
9 bool b = new YearMonth(2023, 3) > new YearMonth(2023, 2);  //b: true

  至此,上面的YearMonth时间类型已经满足小编的开发需要,当然也可以根据需求继续扩展其它功能。文章来源地址https://www.toymoban.com/news/detail-602060.html

到了这里,关于给C#新增一个时间类型: YearMonth的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C#】.Net Framework框架使用JWT

    2023年,第31周,第2篇文章。给自己一个目标,然后坚持总会有收货,不信你试试! 本篇文章主要简单讲讲,.Net Framework框架下使用JWT的代码例子,以及他们的基本概念。 2002年微软发布了.net framework 1.0,那个时候博主刚开始玩传奇游戏,接触电脑的时间还是挺早的。 JWT(JS

    2024年02月15日
    浏览(53)
  • Activity的5种启动模式详解(新增singleInstancePerTask类型)

    看到这个标题的时候,也许你会认为我写错了,Activity不是只有四种启动模式吗?分别为startard,singleTop,singleTask,singleInstance这四种。 一般来说是四种,但是android12的时候新加入了singleInstancePerTask类型,所以就有5种了。 介绍这五种类型之前,我们先略微介绍一下这五种类型在源

    2023年04月21日
    浏览(26)
  • C#安装“Windows 窗体应用(.NET Framework)”

    目录 背景: 第一步: 第二步: 第三步: 总结: 如下图所示:在Visual Studio Installer创建新项目的时候,想要添加windows窗体应用程序,发现里面并没有找到Windows窗体应用(.NET Framework)模板,快捷搜索也没有发现,那么为什么没有找到这个模板,可能程序未曾安装这个模板,那接下来就

    2024年02月10日
    浏览(41)
  • 【c#,.NET】Entity Framework Core基础详解

    目录   一、EF Core概述 1.1 什么是ORM?  1.2 EF Core的性能怎么样  二、EF Core入门 2.1 什么是Migration数据库迁移: 2.2  EF Core数据的增删改查 2.2.1 增加数据 2.2.2 查询数据  2.2.3 修改和删除数据 三、EF Core的实体类配置 3.1 约定大于配置 3.2 EF Core两种配置方式 3.2.1 Data Annotation 3.2.2 

    2024年02月04日
    浏览(63)
  • [C#]vs2022安装后C#创建winform没有.net framework4.8

    问题,我已经在visualstudio安装程序中安装了.net框架4.8的SDK和运行时。 然而,我在visual studio 2022中找不到已安装的框架。 我已经检查了我的VS 2019,它可以很好地定位网络框架4.8,它可以构建我的项目。但VS 2022不能。 我已经重新安装了VS 2022和VS 2019,但VS 2022仍然找不到我的框

    2024年02月07日
    浏览(55)
  • 【C#】.Net Framework框架下的Authorize权限类

    2023年,第31周,第3篇文章。给自己一个目标,然后坚持总会有收货,不信你试试! 在C#的.NET Framework中,你可以使用 Authorize 类来处理权限认证。 Authorize 类位于 System.Web.Mvc 命名空间中,它提供了一种简单的方式来限制对控制器中的操作方法的访问。 要在控制器中使用权限认

    2024年02月13日
    浏览(52)
  • 【C#】.Net Framework框架下使用SQLike以及基本概念

    2023年,第32周,第2篇文章。给自己一个目标,然后坚持总会有收货,不信你试试! 在C#的.NET Framework框架下,有很多轻量级数据库选择,比如:SQLike就是其中一款,一起来了解SQLike的简单使用吧。 轻量级数据库是指具有较小的存储需求、资源消耗较低、易于部署和使用的数据

    2024年02月11日
    浏览(76)
  • ASP.NET Website 项目 .NET Framework 4.0 ~ .NET Framework 4.8支持c#哪些版本(Website)

    本文讲的是Website网站项目,由于维护老项目Website .net framework4.0,遇到c#6.0语法不支持。便做了点记录 下面是关于 ASP.NET Website 项目在不同版本的 .NET Framework 下支持的 C# 版本的总结: ASP.NET Website 项目在 .NET Framework 4.0 中,默认使用 C# 4.0 版本。该版本不支持 C# 6.0 及更高版本

    2024年02月16日
    浏览(39)
  • 一个网卡怎么新增一个跨网段ip地址?

    有时候笔记本只有一个网卡,但是有一个设备连接了内网但是ip不是内网IP,这是我们就要增加一个跨网段IP,能够使笔记本电脑与设备通信 1、单击网络和共享中心 2、单击更改适配器设置 3、找到正在使用的网卡 4、右击选择属性 5、双击IPV4选项 6、如图是一般的内网地址 7、

    2024年02月08日
    浏览(55)
  • C# .NET 7.0和Framework 4.8两个框架的区别

    .NET 7.0和Framework 4.8是微软开发的两个不同版本的框架,用于构建和运行应用程序。虽然它们都是用于C#编程语言的,但它们在功能和性能方面有一些区别。 首先,让我们来看一下.NET 7.0的一些新功能和改进。.NET 7.0是.NET的最新版本,它引入了许多新的功能和改进,以提高开发

    2024年02月13日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包