书接上回,我们继续来分享一些关于特殊时间获取的常用扩展方法。

01、获取当天的开始时间

当天的开始时间指00:00:00时刻,因此只需要获取DateTime的Date属性只获取时间即可,具体代码如下:

//获取当天的开始时间
public static DateTime GetStartDateTimeOfDay(this DateTime dateTime)
{
return dateTime.Date;
}

我们进行一个简单的单元测试,具体代码如下:

[Fact]
public void GetStartDateTimeOfDay()
{
var datetime = new DateTime(2024, 11, 7, 14, 10, 10);
var start = datetime.GetStartDateTimeOfDay();
Assert.Equal(new DateTime(2024, 11, 7), start);
}

02、获取当天的结束时间

该方法时候获取一天中最后一刻,也就是第二天的前一刻,我们可以用第二天的开始时间减去最小时间单位得到当天的结束时间,具体代码如下:

//获取当天的结束时间
public static DateTime GetEndDateTimeOfDay(this DateTime dateTime)
{
return dateTime.Date.AddDays(1).AddTicks(-1);
}

下面我们通过单元测试验证,时间部分是否为“23:59:59 9999999”,具体代码如下:

[Fact]
public void GetEndDateTimeOfDay()
{
var date4 = new DateTime(2024, 11, 7, 14, 10, 10);
var end = date4.GetEndDateTimeOfDay();
Assert.Equal("2024-11-07 23:59:59 9999999", end.ToString("yyyy-MM-dd HH:mm:ss fffffff"));
}

03、获取当前日期所在周的第一天(周一)

要想获得当前日期所在周的周一,只需要知道当前是周几,然后计算出和周一相差几天,最后使用AddDays方法即可。

首先我们可以通过DayOfWeek获取到日期是周几枚举值,但是这个枚举值对应的int值是

0 = Sunday 周日, 1 = Monday 周一, ..., 6 = Saturday 周六。其中周日的0就显得很异类,处理起来也就比较麻烦。

因此如果当前日期是周日那么就会出现周日减周一等于0减1等于-1的情况,所有我们需要加7来保证结果为正数。

同样如果当前日期是周六那么就会出现周六减周一等于6减1加7等于12的情况,所以我们需要同取余%7,来保证两者相差在一周天数之内。

具体代码如下:

//获取当前日期所在周的第一天(周一)
public static DateTime GetFirstDayDateTimeOfWeek(this DateTime dateTime)
{
//0 = Sunday 周日, 1 = Monday 周一, ..., 6 = Saturday 周六
//首先获取当前日期星期枚举值,然后计算其和周一枚举值差值
//结果+7,保证结果为正数
//结果%7,保证结果在0-6之间,对于一周七天,从而表示要回退多少天到周一
//+7 %7 巧妙的把周日当7处理,最后再转为0
var diff = ((int)dateTime.DayOfWeek - (int)DayOfWeek.Monday + 7) % 7;
return dateTime.AddDays(-diff).Date;
}

下面我们需要进行详细的单元测试,我们进行了四种情况的测试分别是:

(1) 验证当前日期是周五,而周一在上一个月的情况;

(2) 验证当前日期就是周一的情况;

(3) 验证当前日期是周四,而周一在当月的情况

(4) 验证当前日期是周日,而周一在当月的情况

具体代码如下:

[Fact]
public void GetFirstDayDateTimeOfWeek()
{
//验证当前日期是周五,而周一在上一个月的情况
var friday = new DateTime(2024, 11, 1, 14, 10, 10);
var day_friday = friday.GetFirstDayDateTimeOfWeek();
Assert.Equal(new DateTime(2024, 10, 28), day_friday);
//验证当前日期就是周一的情况
var monday = new DateTime(2024, 11, 4, 4, 10, 10);
var day_monday = monday.GetFirstDayDateTimeOfWeek();
Assert.Equal(new DateTime(2024, 11, 4), day_monday);
//验证当前日期是周四的情况
var thursday = new DateTime(2024, 11, 7, 4, 10, 10);
var day_thursday = thursday.GetFirstDayDateTimeOfWeek();
Assert.Equal(new DateTime(2024, 11, 4), day_thursday);
//验证当前日期是周日的情况
var sunday = new DateTime(2024, 11, 10, 4, 10, 10);
var day_sunday = sunday.GetFirstDayDateTimeOfWeek();
Assert.Equal(new DateTime(2024, 11, 4), day_sunday);
}

04、获取当前日期所在周的最后一天(周日)

该方法和上面获取周一的思想一样,我们可以把周日枚举值就当作7来处理,具体代码如下:

//获取当前日期所在周的最后一天(周日)
public static DateTime GetLastDayDateTimeOfWeek(this DateTime dateTime)
{
//0 = Sunday 周日, 1 = Monday 周一, ..., 6 = Saturday 周六
//首先计算还差几天到周日
//结果%7,保证结果在0-6之间
//当周日时dateTime.DayOfWeek为0,(7-0)% 7 = 0
//巧妙的把周日当7处理,最后再转为0
var diff = (7 - (int)dateTime.DayOfWeek) % 7;
return dateTime.AddDays(diff).Date;
}

同样的我们做类似获取周一的四种情况单元测试,具体代码如下:

[Fact]
public void GetLastDayDateTimeOfWeek()
{
//验证当前日期是周六,而周日在下一个月的情况
var sunday = new DateTime(2024, 11, 30, 14, 10, 10);
var day_sunday = sunday.GetLastDayDateTimeOfWeek();
Assert.Equal(new DateTime(2024, 12, 1), day_sunday);
//验证当前日期就是周一的情况
var monday = new DateTime(2024, 11, 4, 4, 10, 10);
var day_monday = monday.GetLastDayDateTimeOfWeek();
Assert.Equal(new DateTime(2024, 11, 10), day_monday);
//验证当前日期是周四的情况
var thursday = new DateTime(2024, 11, 7, 4, 10, 10);
var day_thursday = thursday.GetLastDayDateTimeOfWeek();
Assert.Equal(new DateTime(2024, 11, 10), day_thursday);
//验证当前日期是周日的情况
var sunday1 = new DateTime(2024, 11, 10, 4, 10, 10);
var day_thursday1 = sunday1.GetLastDayDateTimeOfWeek();
Assert.Equal(new DateTime(2024, 11, 10), day_thursday1);
}

05、获取当前日期所在月的第一天

这个方法比较简单,只需要使用当前日期的年份和月份,然后直接构建当月第一天,具体代码如下:

//获取当前日期所在月的第一天
public static DateTime GetFirstDayDateTimeOfMonth(this DateTime dateTime)
{
return new DateTime(dateTime.Year, dateTime.Month, 1, 0, 0, 0, 0, DateTimeKind.Local);
}

这个方法太简单了,我们就不列出单元测试代码了。

06、获取当前日期所在月的最后一天

该方便也不复杂,可以先通过DaysInMonth获取当前月的总天数,然后再构建当月最后一天,具体代码如下:

//获取当前日期所在月的最后一天
public static DateTime GetLastDayDateTimeOfMonth(this DateTime dateTime)
{
//获取当前月的总天数
var days = DateTime.DaysInMonth(dateTime.Year, dateTime.Month);
return new DateTime(dateTime.Year, dateTime.Month, days, 0, 0, 0, 0, DateTimeKind.Local);
}

同样的我们这个方法也不复杂,我们就不列举单元测试了。

07、获取当前日期所在季度的第一天

如果想要获取当前日期所在季度的第一天那么首先需要获取当前日期所在季度的第一个月是多少。

我们知道三个月为一季度,因此我们可以使用当前月份除以3,如果这样直接除就会得到:1/3=0,2/3=0,3/3=1,这样1月到3月就不在同一个季度里,所以我们使用(moth - 1)/ 3,计算出0、1、2、3表示4个季度,这样就可以计算出当前日期所在第几个季度。

计算出所在季度后我们还需要计算出当前季度的第一个月即1月、4月、7月、10月,然后找出这4个月份与上面表示4个季度值的关系即可,最终得到如下公式:(moth - 1)/ 3 * 3 +1,即为当前日期所在季度的第一个月。

最后就是直接构建日期,具体代码如下:

//获取当前日期所在季度的第一天
public static DateTime GetFirstDayDateTimeOfQuarter(this DateTime dateTime)
{
//计算当前日期所在季度的起始月
var firstMonth = (dateTime.Month - 1) / 3 * 3 + 1;
return new DateTime(dateTime.Year, firstMonth, 1, 0, 0, 0, 0, DateTimeKind.Local);
}

然后我们分别对这个方法做以下三种情况的单元测试:

(1) 一个季度第一个月取第一天的情况;

(2) 一个季度第二个月取中间的一天的情况;

(3) 一个季度第三个月取最后一天的情况;

[Fact]
public void GetFirstDayDateTimeOfQuarter()
{
//一个季度第一个月取第一天的情况
var month1 = new DateTime(2024, 10, 1, 14, 10, 10);
var day_month1 = month1.GetFirstDayDateTimeOfQuarter();
Assert.Equal(new DateTime(2024, 10, 1), day_month1);
//一个季度第二个月取中间的一天的情况
var month2 = new DateTime(2024, 11, 17, 4, 10, 10);
var day_month2 = month2.GetFirstDayDateTimeOfQuarter();
Assert.Equal(new DateTime(2024, 10, 1), day_month2);
//一个季度第三个月取最后一天的情况
var month3 = new DateTime(2024, 12, 31, 4, 10, 10);
var day_month3 = month3.GetFirstDayDateTimeOfQuarter();
Assert.Equal(new DateTime(2024, 10, 1), day_month3);
}

08、获取当前日期所在季度的最后一天

该方法和上面获取季度的第一天思想一样,只是此方法获取当前日期所在季度的最后月份的计算公式有所差异,公式为:(moth + 2)/ 3 * 3,具体代码如下:

//获取当前日期所在季度的最后一天
public static DateTime GetLastDayDateTimeOfQuarter(this DateTime dateTime)
{
//计算当前日期所在季度的最后月
var lastMonth = (dateTime.Month + 2) / 3 * 3;
//获取当前月的总天数
var days = DateTime.DaysInMonth(dateTime.Year, lastMonth);
return new DateTime(dateTime.Year, lastMonth, days, 0, 0, 0, 0, DateTimeKind.Local);
}

同样的我们对其进行三种情况单元测试,具体代码如下:

[Fact]
public void GetLastDayDateTimeOfQuarter()
{
//一个季度第一个月取第一天的情况
var month1 = new DateTime(2024, 10, 1, 14, 10, 10);
var day_month1 = month1.GetLastDayDateTimeOfQuarter();
Assert.Equal(new DateTime(2024, 12, 31), day_month1);
//一个季度第二个月取中间的一天的情况
var month2 = new DateTime(2024, 11, 17, 4, 10, 10);
var day_month2 = month2.GetLastDayDateTimeOfQuarter();
Assert.Equal(new DateTime(2024, 12, 31), day_month2);
//一个季度第三个月取最后一天的情况
var month3 = new DateTime(2024, 12, 31, 4, 10, 10);
var day_month3 = month3.GetLastDayDateTimeOfQuarter();
Assert.Equal(new DateTime(2024, 12, 31), day_month3);
}

09、获取当前日期所在年的第一天

该方法比较简单,直接用当前日期所在年份和1月1号直接构建即可,代码如下:

//获取当前日期所在年的第一天
public static DateTime GetFirstDayDateTimeOfYear(this DateTime dateTime)
{
return new DateTime(dateTime.Year, 1, 1, 0, 0, 0, 0, DateTimeKind.Local);
}

10、获取当前日期所在年的最后一天

该方法也比较简单,直接用当前日期所在年份和12月31号直接构建即可,代码如下:

//获取当前日期所在年的最后一天
public static DateTime GetLastDayDateTimeOfYear(this DateTime dateTime)
{
return new DateTime(dateTime.Year, 12, 31, 0, 0, 0, 0, DateTimeKind.Local);
}

稍晚些时候我会把库上传至Nuget,大家可以直接使用Ideal.Core.Common。

:测试方法代码以及示例源码都已经上传至代码库,有兴趣的可以看看。https://gitee.com/hugogoos/Ideal

开源 - Ideal库 - 特殊时间扩展方法(三)的更多相关文章

  1. Rails时间扩展方法

    1.时间扩展方法: beginning_of_day,end_of_day等等 Time.now.end_of_day 2.ruby类型判断 is_a?(类型) 如:b.is_a?(Array)

  2. [C#技术] .NET平台开源JSON库LitJSON的使用方法

    一个简单示例: String str = "{’name’:’cyf’,’id’:10,’items’:[{’itemid’:1001,’itemname’:’hello’},{’itemi ...

  3. .NET平台开源JSON库LitJSON的使用方法

    下载地址:LitJson.dll下载 一个简单示例: String str = "{'name':'cyf','id':10,'items':[{'itemid':1001,'itemnam ...

  4. (转).NET平台开源JSON库LitJSON的使用方法

    一个简单示例: String str = "{’name’:’cyf’,’id’:10,’items’:[{’itemid’:1001,’itemname’:’hello’},{’itemi ...

  5. .NET中那些所谓的新语法之二:匿名类、匿名方法与扩展方法

    开篇:在上一篇中,我们了解了自动属性.隐式类型.自动初始化器等所谓的新语法,这一篇我们继续征程,看看匿名类.匿名方法以及常用的扩展方法.虽然,都是很常见的东西,但是未必我们都明白其中蕴含的奥妙.所以, ...

  6. 扩展方法(深入理解c#)

    1. 静态类到扩展方法: 许多方法可能都适合转为扩展方法,只要具有以下特征: 1)你想为一个类型添加一些成员: 2)你不需要为类型的实例添加更多的数据: 3)你不能改变类型本身,因为是别人的代码 2. ...

  7. 【开源】OSharp框架解说系列(3):扩展方法

    OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...

  8. Farseer.net轻量级开源框架 中级篇:常用的扩展方法

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: BasePage.BaseController.BaseHandler.BaseM ...

  9. [Swift通天遁地]五、高级扩展-(3)日期和时间类型的扩展方法

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  10. 【原创】开源Math.NET基础数学类库使用(12)C#随机数扩展方法

                   本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新  开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...

随机推荐

  1. 为什么要加 REQUIRE8 and PRESERVE8? 栈的8字节对齐

    REQUIRE8 and PRESERVE8   The REQUIRE8 and PRESERVE8 directives specify that the current file require ...

  2. Linux驱动 | 从0写一个设备树节点实例

    一.前言 设备树是每一个Linux驱动工程师都必须掌握的一个知识点,有很多之前做单片机的朋友刚接触Linux驱动时,会一脸懵! 其实设备树的使用并没有大家想像的那么复杂,对于大部分工程师来说,只要会修 ...

  3. 如何用AI抠图助手进行直播--新手指南

    如何用AI抠图助手进行直播 因AI抠图助手目前还没有提供推流直播,所以,可以采用抖音的"手游直播"方式,即抖音开启手游直播后会录制你手机屏幕画面,进行录屏直播:所以我们只要打开AI ...

  4. 我的微服务项目之IdentityServer4

     2021,祝大家新年快乐!!! 2021年了,新的一年应该有新的计划,我的计划是准备去学习微服务,所以我将我自己的博客项目拆分成了一个微服务项目,用来给自己学习,项目地址:http://www.tt ...

  5. 《SpringBoot事务》单机mybatis事务控制

    一.场景再现 我们同时操作两张表及以上,一张表操作成功后,第二张表操作失败,此时需要回滚上一次的操作. 或者两次操作都成功,但后续业务处理的时候异常,此时需要回滚前面的所有数据库操作. 二.代码 1 ...

  6. 游戏AI行为决策——Behavior Tree(行为树)

    游戏AI行为决策--行为树 前言 行为树,是目前游戏中应用较为广泛的一种行为决策模型.这离不开它成熟的可视化编辑工具,例如Unity商城中的「Behaviour Designer」,甚至是虚幻引擎也自 ...

  7. ASP.NET Core – Upload and Download Files (上传和下载文件)

    前言 以前得文章 Asp.net core 学习笔记 ( upload/download files 文件上传与下载 ), 这篇是修订版. Handle Upload File (处理上传文件) 我的 ...

  8. CSS – 管理

    前言 CSS 有好几种写法. 它们最终出来的效果是一样的, 区别只是在你如何 "写" 和 "读" 或者说开发和维护. 这已经不是如何"实现" ...

  9. IOI2000 邮局 加强版 题解

    [IOI2000] 邮局 加强版 题解 考虑动态规划,设 \(f_{i,j}\) 为经过了 \(i\) 个村庄,正在建第 \(j\)​ 个邮局的最优距离. 以及 \(w_{i,j}\) 表示区间 \( ...

  10. 【赵渝强老师】MongoDB管理用户的认证机制

    一.MongoDB用户认证机制简介 为了认证客户端,你必须要添加一个对应的用户到MongoDB.基本的步骤分为以下几步: 用户管理接口:db.createUser()方法可以创建一个用户,添加完成后可 ...