当前位置: 首页 > news >正文

C#自定义工具类-时间日期工具类

目录

时间日期工具类DateTimeHelper

功能说明

日期格式化

时间戳转换

时间间隔计算

日期边界与调整

时区转换

日期解析

时间相等性判断

时间范围与先后判断

日期合法性与特殊判断

截断时间到指定精度

完整代码


     本篇文章分享一下时间日期工具类DateTimeHelper,包含了时间日期的常用操作,使用该类更便捷地完成时间相关的操作。

时间日期工具类DateTimeHelper

功能说明

日期格式化

       提供多种日期字符串转换方法,包括纯数字格式(如20240101)、日志格式(如[yyyy/MM/dd HH:mm:ss])、自定义格式转换,以及带星期的日期格式(如2024年01月01日 星期一)。

时间戳转换

       实现 DateTime 与 Unix 时间戳的双向转换,支持秒级和毫秒级精度,包括直接转换和安全转换(异常时返回 null)。

时间间隔计算

       计算两个时间的间隔,支持秒、毫秒、天数(忽略时间部分)和月份差(按自然月计算),结果可为负数。

日期边界与调整

       获取指定日期的天 / 月起始与结束时间(如2024-01-01 00:00:00和2024-01-31 23:59:59.999),并支持对日期进行年、月、日、时、分、秒的加减调整。

时区转换

       提供本地时间与 UTC 时间的双向转换,自动处理不同DateTimeKind的时间类型。

日期解析

       支持按指定格式或多个可能格式将字符串转换为 DateTime,转换失败时返回 null。

时间相等性判断

       可判断两个时间是否完全相同(精确到毫秒),或按指定精度(年、月、日等)判断是否相同,还提供同年、同月、同日的快捷判断。

时间范围与先后判断

       判断时间是否在指定范围内(含边界),比较两个时间的先后关系(早于、晚于),并返回比较结果(1/-1/0)。

日期合法性与特殊判断

       验证日期是否为有效 DateTime 实例,判断年份是否为闰年,以及指定日期是否为当月第一天或最后一天。

截断时间到指定精度

       按指定精度(年、月、日、时等)截断时间,忽略更低精度的部分(如截断到 “小时” 则分钟和秒设为 0)。

完整代码

using System;
using System.Globalization;/// <summary>
/// 日期时间工具类,提供格式化、转换等常用操作
/// </summary>
public static class DateTimeHelper
{#region 日期格式化/// <summary>/// 日期 仅数字格式(如20240101)/// </summary>public static string DateOnlyNum(DateTime dateTime){return dateTime.ToString("yyyy/MM/dd").Replace("/", "");}/// <summary>/// 格式化日志时间 [yyyy/MM/dd HH:mm:ss]/// </summary>public static string DateLogFormat(DateTime dateTime){return $"[{dateTime:yyyy/MM/dd HH:mm:ss}] ";}/// <summary>/// 根据格式返回日期字符串(默认格式:yyyy/MM/dd HH:mm:ss)/// </summary>/// <param name="dateTime">待格式化的时间</param>/// <param name="format">格式字符串(如"yyyy-MM-dd")</param>/// <returns>格式化后的字符串</returns>public static string GetDateTimeStringByFormat(DateTime dateTime, string format = "yyyy/MM/dd HH:mm:ss"){return dateTime.ToString(format);}/// <summary>/// 将日期转换为带星期的格式(如:2024年01月01日 星期一)/// </summary>/// <param name="dateTime">待格式化的日期</param>/// <returns>带星期的日期字符串</returns>public static string GetDateWithWeek(DateTime dateTime){//中文星期名称映射(默认CultureInfo为中文时,DayOfWeek对应的值可直接转换)var weekNames = new[] { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };return $"{dateTime:yyyy年MM月dd日} {weekNames[(int)dateTime.DayOfWeek]}";}#endregion#region 时间戳转换/// <summary>/// DateTime转秒级时间戳(Unix时间戳:1970-01-01 00:00:00 UTC起的秒数)/// </summary>public static long DateTimeToTimestampSeconds(DateTime dateTime){DateTime unixStartTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);DateTime targetUtcTime = dateTime.ToUniversalTime();return (long)(targetUtcTime - unixStartTime).TotalSeconds;}/// <summary>/// DateTime转毫秒级时间戳(Unix时间戳:1970-01-01 00:00:00 UTC起的毫秒数)/// </summary>public static long DateTimeToTimestampMilliseconds(DateTime dateTime){DateTime unixStartTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);DateTime targetUtcTime = dateTime.ToUniversalTime();return (long)(targetUtcTime - unixStartTime).TotalMilliseconds;}/// <summary>/// 秒级时间戳转DateTime(直接返回本地时间,不处理异常)/// </summary>public static DateTime SecondsTimestampToDateTime(long timestampSeconds){DateTime unixStartTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);return unixStartTime.AddSeconds(timestampSeconds).ToLocalTime();}/// <summary>/// 毫秒级时间戳转DateTime(直接返回本地时间,不处理异常)/// </summary>public static DateTime MillisecondsTimestampToDateTime(long timestampMilliseconds){DateTime unixStartTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);return unixStartTime.AddMilliseconds(timestampMilliseconds).ToLocalTime();}/// <summary>/// 秒级时间戳转DateTime(安全转换,异常时返回null)/// </summary>public static DateTime? SecondsTimestampToDateTimeNull(long seconds){if (seconds <= 0) return null;try{DateTime unixStartTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);return unixStartTime.AddSeconds(seconds).ToLocalTime();}catch (ArgumentOutOfRangeException)//时间戳过大导致溢出{return null;}}/// <summary>/// 毫秒级时间戳转DateTime(安全转换,异常时返回null)/// </summary>public static DateTime? MillisecondsTimestampToDateTimeNull(long milliseconds){if (milliseconds <= 0) return null;try{DateTime unixStartTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);return unixStartTime.AddMilliseconds(milliseconds).ToLocalTime();}catch (ArgumentOutOfRangeException)//时间戳过大导致溢出{return null;}}#endregion#region 时间间隔计算/// <summary>/// 获取两个时间的间隔秒数(dateTime1 - dateTime2的秒数差,可为负数)/// </summary>public static long GetTimestampSecondsInterval(DateTime dateTime1, DateTime dateTime2){return (long)(dateTime1 - dateTime2).TotalSeconds;}/// <summary>/// 获取两个时间的间隔毫秒数(dateTime1 - dateTime2的毫秒数差,可为负数)/// </summary>public static long GetTimestampMillisecondsInterval(DateTime dateTime1, DateTime dateTime2){return (long)(dateTime1 - dateTime2).TotalMilliseconds;}/// <summary>/// 获取两个日期之间的总天数(忽略时间部分,dateTime1 - dateTime2的天数差)/// </summary>/// <param name="dateTime1">结束日期</param>/// <param name="dateTime2">开始日期</param>/// <returns>天数差(可为负数)</returns>public static int GetDayInterval(DateTime dateTime1, DateTime dateTime2){//截断时间部分,仅保留日期DateTime date1 = dateTime1.Date;DateTime date2 = dateTime2.Date;return (int)(date1 - date2).TotalDays;}/// <summary>/// 获取两个日期之间的月份差(按自然月计算,如2024-03-01与2024-01-15的差为2)/// </summary>/// <param name="dateTime1">结束日期</param>/// <param name="dateTime2">开始日期</param>/// <returns>月份差(可为负数)</returns>public static int GetMonthInterval(DateTime dateTime1, DateTime dateTime2){int months = (dateTime1.Year - dateTime2.Year) * 12 + dateTime1.Month - dateTime2.Month;//若结束日期的天数小于开始日期,需减1(如2024-02-28与2024-01-31,实际不足1个月)if (dateTime1.Day < dateTime2.Day){months--;}return months;}#endregion#region 日期边界与调整/// <summary>/// 获取指定日期所在天的开始时间(如2024-01-01 00:00:00.000)/// </summary>public static DateTime GetDayStart(DateTime dateTime){return new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 0, 0, 0, 0);}/// <summary>/// 获取指定日期所在天的结束时间(如2024-01-01 23:59:59.999)/// </summary>public static DateTime GetDayEnd(DateTime dateTime){return new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 23, 59, 59, 999);}/// <summary>/// 获取指定日期所在月的开始时间(如2024-01-01 00:00:00.000)/// </summary>public static DateTime GetMonthStart(DateTime dateTime){return new DateTime(dateTime.Year, dateTime.Month, 1, 0, 0, 0, 0);}/// <summary>/// 获取指定日期所在月的结束时间(如2024-01-31 23:59:59.999)/// </summary>public static DateTime GetMonthEnd(DateTime dateTime){// 获取当月最后一天(下个月1号减1天)DateTime nextMonthFirstDay = new DateTime(dateTime.Year, dateTime.Month, 1).AddMonths(1);return nextMonthFirstDay.AddDays(-1).AddTicks(-1); //减1 tick确保是当月最后一刻}/// <summary>/// 调整日期(加减年/月/日/时/分/秒)/// </summary>/// <param name="dateTime">原日期</param>/// <param name="years">年数(正数加,负数减)</param>/// <param name="months">月数(正数加,负数减)</param>/// <param name="days">天数(正数加,负数减)</param>/// <param name="hours">小时数(正数加,负数减)</param>/// <param name="minutes">分钟数(正数加,负数减)</param>/// <param name="seconds">秒数(正数加,负数减)</param>/// <returns>调整后的日期</returns>public static DateTime AddDateTime(DateTime dateTime, int years = 0, int months = 0, int days = 0, int hours = 0, int minutes = 0, int seconds = 0){return dateTime.AddYears(years).AddMonths(months).AddDays(days).AddHours(hours).AddMinutes(minutes).AddSeconds(seconds);}#endregion#region 时区转换/// <summary>/// 将本地时间转换为UTC时间/// </summary>/// <param name="localTime">本地时间</param>/// <returns>UTC时间(带DateTimeKind.Utc标记)</returns>public static DateTime LocalTimeToUtc(DateTime localTime){if (localTime.Kind == DateTimeKind.Utc)//若已是UTC时间,直接返回{return localTime;}return TimeZoneInfo.ConvertTimeToUtc(localTime, TimeZoneInfo.Local);}/// <summary>/// 将UTC时间转换为本地时间/// </summary>/// <param name="utcTime">UTC时间</param>/// <returns>本地时间(带DateTimeKind.Local标记)</returns>public static DateTime UtcToLocalTime(DateTime utcTime){if (utcTime.Kind == DateTimeKind.Local)//若已是本地时间,直接返回{return utcTime;}return TimeZoneInfo.ConvertTimeFromUtc(utcTime, TimeZoneInfo.Local);}#endregion#region 日期解析/// <summary>/// 将字符串按指定格式转换为DateTime(失败返回null)/// </summary>/// <param name="dateTimeString">日期字符串(如"2024/01/01 12:30:45")</param>/// <param name="format">解析格式(如"yyyy/MM/dd HH:mm:ss")</param>/// <returns>转换后的DateTime?,失败返回null</returns>public static DateTime? GetDateTimeByFormat(string dateTimeString, string format = "yyyy/MM/dd HH:mm:ss"){if (string.IsNullOrWhiteSpace(dateTimeString)) return null;//调用单格式重载:TryParseExact(string s, string format, ...)bool success = DateTime.TryParseExact(dateTimeString, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime result);if (success) return result;return null;}/// <summary>/// 将字符串按多个可能格式尝试转换为DateTime(失败返回null)/// </summary>/// <param name="dateTimeString">日期字符串(如"20240101"或"2024-01-01")</param>/// <param name="formats">可能的解析格式列表,/// 不填为 "yyyy-MM-dd", "yyyy/MM/dd", "yyyy.MM.dd", "yyyy-MM-dd HH:mm:ss", "yyyy/MM/dd HH:mm:ss", "yyyy.MM.dd HH:mm:ss", "yyyyMMdd", "yyyyMMddHHmmss"</param>/// <returns>转换后的DateTime?,所有格式均失败则返回null</returns>public static DateTime? GetDateTimeByFormats(string dateTimeString, string[] formats = null){if (string.IsNullOrWhiteSpace(dateTimeString) || formats == null || formats.Length == 0) return null;if (formats == null) formats = new string[] { "yyyy-MM-dd", "yyyy/MM/dd", "yyyy.MM.dd", "yyyy-MM-dd HH:mm:ss", "yyyy/MM/dd HH:mm:ss", "yyyy.MM.dd HH:mm:ss", "yyyyMMdd", "yyyyMMddHHmmss" };//调用多格式重载:TryParseExact(string s, string[] formats, ...)bool success = DateTime.TryParseExact(dateTimeString, formats, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime result);if (success) return result;return null;}#endregion#region 时间相等性判断/// <summary>/// 判断两个时间是否完全相同(精确到毫秒,基于Ticks值)/// </summary>/// <param name="dateTime1">第一个时间</param>/// <param name="dateTime2">第二个时间</param>/// <returns>true=完全相同;false=不同</returns>public static bool IsSameDateTime(DateTime dateTime1, DateTime dateTime2){//Ticks以100纳秒为单位,可精确到毫秒级(1毫秒=10000 Ticks)return dateTime1.Ticks == dateTime2.Ticks;}/// <summary>/// 判断两个时间是否相同(可指定比较精度,忽略更低精度部分)/// </summary>/// <param name="dateTime1">第一个时间</param>/// <param name="dateTime2">第二个时间</param>/// <param name="precision">比较精度(如Year/Month/Day等)</param>/// <returns>true=指定精度下相同;false=不同</returns>public static bool IsSameDateTime(DateTime dateTime1, DateTime dateTime2, DateTimePrecision precision){DateTime truncated1 = TruncateDateTime(dateTime1, precision);DateTime truncated2 = TruncateDateTime(dateTime2, precision);return truncated1 == truncated2;}/// <summary>/// 判断两个时间是否同年/// </summary>/// <param name="dateTime1">第一个时间</param>/// <param name="dateTime2">第二个时间</param>/// <returns>true=同年;false=不同年</returns>public static bool IsSameYear(DateTime dateTime1, DateTime dateTime2){return dateTime1.Year == dateTime2.Year;}/// <summary>/// 判断两个时间是否同月(含同年判断)/// </summary>/// <param name="dateTime1">第一个时间</param>/// <param name="dateTime2">第二个时间</param>/// <returns>true=同年同月;false=不同</returns>public static bool IsSameMonth(DateTime dateTime1, DateTime dateTime2){return dateTime1.Year == dateTime2.Year && dateTime1.Month == dateTime2.Month;}/// <summary>/// 判断两个时间是否同日(含同年同月判断)/// </summary>/// <param name="dateTime1">第一个时间</param>/// <param name="dateTime2">第二个时间</param>/// <returns>true=同年同月同日;false=不同</returns>public static bool IsSameDay(DateTime dateTime1, DateTime dateTime2){return dateTime1.Year == dateTime2.Year && dateTime1.Month == dateTime2.Month && dateTime1.Date == dateTime2.Date;//Date属性自动截断时分秒}#endregion#region 时间范围与先后判断/// <summary>/// 判断日期是否在指定时间范围内(含边界值)/// </summary>/// <param name="dateTime">待判断日期</param>/// <param name="minDateTime">范围最小值(下界)</param>/// <param name="maxDateTime">范围最大值(上界)</param>/// <returns>true=在范围内;false=超出范围</returns>public static bool DateTimeIsInRange(DateTime dateTime, DateTime minDateTime, DateTime maxDateTime){//先校验min和max的合法性(避免min > max导致逻辑错误)if (minDateTime > maxDateTime){(minDateTime, maxDateTime) = (maxDateTime, minDateTime); //交换值,确保min <= max}return dateTime >= minDateTime && dateTime <= maxDateTime;}/// <summary>/// 判断dateTime1是否早于dateTime2/// </summary>/// <param name="dateTime1">待比较时间</param>/// <param name="dateTime2">基准时间</param>/// <returns>true=dateTime1早于dateTime2;false=否则</returns>public static bool IsDateTimeBefore(DateTime dateTime1, DateTime dateTime2){return dateTime1 < dateTime2;}/// <summary>/// 判断dateTime1是否晚于dateTime2/// </summary>/// <param name="dateTime1">待比较时间</param>/// <param name="dateTime2">基准时间</param>/// <returns>true=dateTime1晚于dateTime2;false=否则</returns>public static bool IsDateTimeAfter(DateTime dateTime1, DateTime dateTime2){return dateTime1 > dateTime2;}/// <summary>/// 比较两个时间的先后关系/// </summary>/// <param name="dateTime1">第一个时间</param>/// <param name="dateTime2">第二个时间</param>/// <returns>1=dateTime1晚于dateTime2;-1=dateTime1早于dateTime2;0=两者相等</returns>public static int CompareDateTime(DateTime dateTime1, DateTime dateTime2){return DateTime.Compare(dateTime1, dateTime2);}#endregion#region 日期合法性与特殊判断/// <summary>/// 判断日期是否为有效DateTime实例(避免极端值)/// </summary>/// <param name="dateTime">待判断日期</param>/// <returns>true=有效;false=无效(如超出DateTime支持的范围)</returns>public static bool DateTimeIsValid(DateTime dateTime){//DateTime.MinValue=0001-01-01,MaxValue=9999-12-31,超出此范围为无效return dateTime >= DateTime.MinValue && dateTime <= DateTime.MaxValue;}/// <summary>/// 判断指定年份是否为闰年/// </summary>/// <param name="year">年份(如2024)</param>/// <returns>true=闰年;false=平年</returns>public static bool IsLeapYear(int year){//闰年规则:能被4整除且不能被100整除,或能被400整除return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);}/// <summary>/// 判断指定日期是否为当月第一天/// </summary>/// <param name="dateTime">待判断日期</param>/// <returns>true=当月第一天;false=否则</returns>public static bool IsFirstDayOfMonth(DateTime dateTime){return dateTime.Day == 1;}/// <summary>/// 判断指定日期是否为当月最后一天/// </summary>/// <param name="dateTime">待判断日期</param>/// <returns>true=当月最后一天;false=否则</returns>public static bool IsLastDayOfMonth(DateTime dateTime){//当月最后一天 = 下月第一天减1天DateTime nextMonthFirstDay = new DateTime(dateTime.Year, dateTime.Month, 1).AddMonths(1);DateTime lastDayOfMonth = nextMonthFirstDay.AddDays(-1);return dateTime.Date == lastDayOfMonth.Date;}#endregion#region 截断时间到指定精度/// <summary>/// 截断时间到指定精度(忽略更低精度的部分)/// </summary>/// <param name="dateTime">待截断时间</param>/// <param name="precision">截断精度</param>/// <returns>截断后的时间</returns>private static DateTime TruncateDateTime(DateTime dateTime, DateTimePrecision precision){return precision switch{DateTimePrecision.Year => new DateTime(dateTime.Year, 1, 1),DateTimePrecision.Month => new DateTime(dateTime.Year, dateTime.Month, 1),DateTimePrecision.Day => dateTime.Date, //Date属性直接返回"年-月-日 00:00:00"DateTimePrecision.Hour => new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, 0, 0),DateTimePrecision.Minute => new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, 0),DateTimePrecision.Second => new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, dateTime.Second),DateTimePrecision.Millisecond => dateTime, //保留毫秒级精度_ => dateTime //默认返回原时间};}#endregion
}
/// <summary>
/// 时间比较精度枚举
/// </summary>
public enum DateTimePrecision
{Year,       // 年Month,      // 月Day,        // 日Hour,       // 时Minute,     // 分Second,     // 秒Millisecond // 毫秒
}

       还可以参考Unity、C#常用的时间处理类

       好了,本次的分享到这里就结束啦,希望对你有所帮助~

http://www.dtcms.com/a/344672.html

相关文章:

  • 【python与生活】如何用Python写一个简单的自动整理文件的脚本?
  • 常用 CMake 内置变量合集与说明
  • Python 环境变量:从基础到实战的灵活配置之道
  • Logstash——输出(Output)
  • Jenkins自动化部署服务到Kubernetes环境
  • 云计算学习100天-第27天
  • python程序函数计时
  • unity资源领取反作弊工具加密器
  • 递归思路:从DFS到二叉树直径的实战(通俗易懂)
  • redis设置密码及配置conf
  • OpenSCA开源社区每日安全漏洞及投毒情报资讯|21th Aug. , 2025
  • 异常值检测:孤立森林模型(IsolationForest)总结
  • 并发编程:浅析LockSupport工具
  • 大数据世界的开拓者:深入浅出MapReduce分布式计算经典范式
  • MyBatis-Flex
  • 【中微半导体】嵌入式C语言,函数指针表驱动状态机( 代码风格抽象,在 C 里模拟了“对象“、“多态“的效果)
  • 【日常学习】2025-8-22 类属性和实例属性+小白学调试
  • 数据结构 -- 树
  • Vue3+Ant-design-vue+SSE实现实时进度条
  • 前端快讯看这里
  • 基于导频的OFDM系统的信道估计(使用LS估计算法)
  • 突击复习清单(高频核心考点)
  • 【C++高阶六】哈希与哈希表
  • 线程池拒绝策略踩坑
  • uniappx与uniapp的区别
  • 【UniApp打包鸿蒙APP全流程】如何配置并添加UniApp API所需的鸿蒙系统权限
  • MySQL B+树索引使用
  • QT之QSS的使用方法和常用控件的样式设置
  • Qt 的事件类QEvent及其他子类事件的开发详解:从基础到实践的全方位指南
  • 高并发用户数峰值对系统架构设计有哪些影响?