// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 // // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 // // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! using System.Globalization; namespace Admin.NET.Core; /// /// DateTime 扩展方法 /// public static class DateTimeFormatExtensions { /// /// 获取 Unix 时间戳 /// /// /// public static long GetUnixTimeStamp(this DateTime dateTime) { return ((DateTimeOffset)dateTime).ToUnixTimeMilliseconds(); } /// /// 获取 Unix 时间戳 /// /// /// public static long GetUnixTimeStamp(this DateTimeOffset dateTime) { return dateTime.ToUnixTimeMilliseconds(); } /// /// 获取当前时间的时间戳 /// /// /// public static long GetDateToTimeStamp(this DateTime dateTime) { var ts = dateTime - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(ts.TotalSeconds); } /// /// 获取日期天的最小时间 /// /// /// public static DateTime GetDayMinDate(this DateTime dateTime) { return new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 0, 0, 0); } /// /// 获取日期天的最大时间 /// /// /// public static DateTime GetDayMaxDate(this DateTime dateTime) { return new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 23, 59, 59); } /// /// 获取一天的范围 /// /// /// public static List GetDayDateRange(this DateTime dateTime) { return [ dateTime.GetDayMinDate(), dateTime.GetDayMaxDate() ]; } /// /// 获取日期开始时间 /// /// /// /// public static DateTime GetBeginTime(this DateTime? dateTime, int days = 0) { return dateTime == DateTime.MinValue || dateTime is null ? DateTime.Now.AddDays(days) : (DateTime)dateTime; } /// /// 获取星期几 /// /// /// public static string GetWeekByDate(this DateTime dateTime) { string[] day = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]; return day[Convert.ToInt32(dateTime.DayOfWeek.ToString("d"))]; } /// /// 获取这个月的第几周 /// /// /// public static int GetWeekNumInMonth(this DateTime daytime) { var dayInMonth = daytime.Day; // 本月第一天 var firstDay = daytime.AddDays(1 - daytime.Day); // 本月第一天是周几 var weekday = firstDay.DayOfWeek == 0 ? 7 : (int)firstDay.DayOfWeek; // 本月第一周有几天 var firstWeekEndDay = 7 - (weekday - 1); // 当前日期和第一周之差 var diffDay = dayInMonth - firstWeekEndDay; diffDay = diffDay > 0 ? diffDay : 1; // 当前是第几周,若整除7就减一天 return (diffDay % 7 == 0 ? (diffDay / 7) - 1 : diffDay / 7) + 1 + (dayInMonth > firstWeekEndDay ? 1 : 0); } /// /// 时间转换字符串 /// /// /// public static string FormatDateTimeToString(this DateTime dateTime) { return dateTime.ToString(dateTime.Year == DateTime.Now.Year ? "MM-dd HH:mm" : "yyyy-MM-dd HH:mm"); } /// /// 时间转换字符串 /// /// /// /// public static string FormatDateTimeToString(this DateTime dateTimeBefore, DateTime dateTimeAfter) { if (dateTimeBefore >= dateTimeAfter) { throw new Exception("开始日期必须小于结束日期"); } var timeSpan = dateTimeAfter - dateTimeBefore; return timeSpan.FormatTimeSpanToString(); } /// /// 毫秒转换字符串 /// /// /// public static string FormatMilliSecondsToString(this long milliseconds) { var timeSpan = TimeSpan.FromMilliseconds(milliseconds); return timeSpan.FormatTimeSpanToString(); } /// /// 时刻转换字符串 /// /// /// public static string FormatTimeTicksToString(this long ticks) { var timeSpan = TimeSpan.FromTicks(ticks); return timeSpan.FormatTimeSpanToString(); } /// /// 毫秒转换字符串 /// /// /// public static string FormatTimeMilliSecondToString(this long ms) { const int Ss = 1000; const int Mi = Ss * 60; const int Hh = Mi * 60; const int Dd = Hh * 24; var day = ms / Dd; var hour = (ms - (day * Dd)) / Hh; var minute = (ms - (day * Dd) - (hour * Hh)) / Mi; var second = (ms - (day * Dd) - (hour * Hh) - (minute * Mi)) / Ss; var milliSecond = ms - (day * Dd) - (hour * Hh) - (minute * Mi) - (second * Ss); // 天 var sDay = day < 10 ? "0" + day : string.Empty + day; // 小时 var sHour = hour < 10 ? "0" + hour : string.Empty + hour; // 分钟 var sMinute = minute < 10 ? "0" + minute : string.Empty + minute; // 秒 var sSecond = second < 10 ? "0" + second : string.Empty + second; // 毫秒 var sMilliSecond = milliSecond < 10 ? "0" + milliSecond : string.Empty + milliSecond; sMilliSecond = milliSecond < 100 ? "0" + sMilliSecond : string.Empty + sMilliSecond; return $"{sDay} 天 {sHour} 小时 {sMinute} 分 {sSecond} 秒 {sMilliSecond} 毫秒"; } /// /// 时间跨度转换字符串 /// /// /// public static string FormatTimeSpanToString(this TimeSpan timeSpan) { var day = timeSpan.Days; var hour = timeSpan.Hours; var minute = timeSpan.Minutes; var second = timeSpan.Seconds; var milliSecond = timeSpan.Milliseconds; // 天 var sDay = day < 10 ? "0" + day : string.Empty + day; // 小时 var sHour = hour < 10 ? "0" + hour : string.Empty + hour; // 分钟 var sMinute = minute < 10 ? "0" + minute : string.Empty + minute; // 秒 var sSecond = second < 10 ? "0" + second : string.Empty + second; // 毫秒 var sMilliSecond = milliSecond < 10 ? "0" + milliSecond : string.Empty + milliSecond; sMilliSecond = milliSecond < 100 ? "0" + sMilliSecond : string.Empty + sMilliSecond; return $"{sDay} 天 {sHour} 小时 {sMinute} 分 {sSecond} 秒 {sMilliSecond} 毫秒"; } /// /// 将 TimeSpan 格式化为 y年M月d天h小时m分钟 的字符串,值为0的单位不显示 /// 注意:此方法对年、月的计算是基于近似值(1年≈365.25天,1月≈30.44天),适用于显示目的,不保证绝对精确 /// /// 要格式化的 TimeSpan /// 保留的最大时间单位数量 /// 格式化后的字符串 public static string FormatTimeSpanText(this TimeSpan timeSpan, int maxUnits = int.MaxValue) { if (timeSpan < TimeSpan.Zero) timeSpan = TimeSpan.Zero; // 确保非负 if (maxUnits <= 0) throw new ArgumentException("maxUnits 必须大于0", nameof(maxUnits)); long totalMinutes = (long)timeSpan.TotalMinutes; if (totalMinutes == 0) return "0分钟"; // 计算年、月、日、小时、分钟 // 使用近似值进行计算 const double minutesInYear = 365 * 24 * 60; const double minutesInMonth = 30 * 24 * 60; // 平均每月天数 const long minutesInDay = 24 * 60; const long minutesInHour = 60; int years = (int)(totalMinutes / minutesInYear); totalMinutes %= (long)minutesInYear; int months = (int)(totalMinutes / minutesInMonth); totalMinutes %= (long)minutesInMonth; int days = (int)(totalMinutes / minutesInDay); totalMinutes %= minutesInDay; int hours = (int)(totalMinutes / minutesInHour); int minutes = (int)(totalMinutes % minutesInHour); var parts = new List(); if (years > 0) parts.Add($"{years}年"); if (months > 0) parts.Add($"{months}个月"); if (days > 0) parts.Add($"{days}天"); if (hours > 0) parts.Add($"{hours}小时"); if (minutes > 0) parts.Add($"{minutes}分钟"); // 如果指定了最大单位数量,则截取前 maxUnits 个非零单位 if (maxUnits < int.MaxValue && parts.Count > maxUnits) { parts = parts.Take(maxUnits).ToList(); } return parts.Count == 0 ? "0分钟" : string.Join("", parts); } /// /// 时间转换简易字符串 /// /// /// public static string FormatDateTimeToEasyString(this DateTime value) { var now = DateTime.Now; if (now < value) { var strDate = value.ToString("yyyy-MM-dd HH:mm:ss"); return strDate; } var dep = now - value; return dep.TotalSeconds < 10 ? "刚刚" : dep.TotalSeconds is >= 10 and < 60 ? (int)dep.TotalSeconds + "秒前" : dep.TotalMinutes is >= 1 and < 60 ? (int)dep.TotalMinutes + "分钟前" : dep.TotalHours < 24 ? (int)dep.TotalHours + "小时前" : dep.TotalDays < 7 ? (int)dep.TotalDays + "天前" : dep.TotalDays is >= 7 and < 30 ? ((int)dep.TotalDays / 7) + "周前" : dep.TotalDays is >= 30 and < 365 ? ((int)dep.TotalDays / 30) + "个月前" : now.Year - value.Year + "年前"; } /// /// 字符串转日期 /// /// /// public static DateTime FormatStringToDate(this string thisValue) { try { if (string.IsNullOrWhiteSpace(thisValue)) { return DateTime.MinValue; } if (thisValue.Contains('-') || thisValue.Contains('/')) { return DateTime.Parse(thisValue); } var length = thisValue.Length; return length switch { 4 => DateTime.ParseExact(thisValue, "yyyy", CultureInfo.CurrentCulture), 6 => DateTime.ParseExact(thisValue, "yyyyMM", CultureInfo.CurrentCulture), 8 => DateTime.ParseExact(thisValue, "yyyyMMdd", CultureInfo.CurrentCulture), 10 => DateTime.ParseExact(thisValue, "yyyyMMddHH", CultureInfo.CurrentCulture), 12 => DateTime.ParseExact(thisValue, "yyyyMMddHHmm", CultureInfo.CurrentCulture), _ => DateTime.ParseExact(thisValue, "yyyyMMddHHmmss", CultureInfo.CurrentCulture) }; } catch { return DateTime.MinValue; } } }