using System; using System.Collections.Generic; using System.Text; namespace Apewer { /// System.DateTime 实用工具。 public class DateTimeUtility { #region Private Methods private static DateTime GetOrigin() { return new DateTime(1970, 1, 1, 0, 0, 0, 0); } private static string FormatDate(DateTime datetime, bool lucid) { var sb = new StringBuilder(); var y = NumberUtility.RestrictValue(datetime.Year, 0, 9999); var m = NumberUtility.RestrictValue(datetime.Month, 1, 12); var d = NumberUtility.RestrictValue(datetime.Day, 1, GetDays(y, m)); if (y < 10) sb.Append("000"); else if (y < 100) sb.Append("00"); else if (y < 1000) sb.Append("0"); sb.Append(y.ToString()); if (lucid) sb.Append("-"); if (m < 10) sb.Append("0"); sb.Append(m.ToString()); if (lucid) sb.Append("-"); if (d < 10) sb.Append("0"); sb.Append(d.ToString()); var date = sb.ToString(); return date; } private static string FormatTime(DateTime datetime, bool lucid, bool seconds, bool milliseconds) { var sb = new StringBuilder(); var h = NumberUtility.RestrictValue(datetime.Hour, 0, 23); var m = NumberUtility.RestrictValue(datetime.Minute, 0, 59); var s = NumberUtility.RestrictValue(datetime.Second, 0, 59); var ms = NumberUtility.RestrictValue(datetime.Millisecond, 0, 999); if (h < 10) sb.Append("0"); sb.Append(h.ToString()); if (lucid) sb.Append(":"); if (m < 10) sb.Append("0"); sb.Append(m.ToString()); if (seconds) { if (lucid) sb.Append(":"); if (s < 10) sb.Append("0"); sb.Append(s.ToString()); if (milliseconds) { if (lucid) sb.Append("."); if (ms < 10) sb.Append("00"); else if (ms < 100) sb.Append("0"); sb.Append(ms.ToString()); } } var time = sb.ToString(); return time; } #endregion #region Public Properties /// 获取当前本地时间的易读格式文本。 public static string NowLucid { get { return ToLucid(DateTime.Now); } } /// 获取当前 UTC 的易读格式文本。 public static string NowUtcLucid { get { return ToLucid(DateTime.UtcNow); } } /// 获取当前本地时间的毫秒时间戳。 public static long NowStamp { get { return GetStamp(DateTime.Now); } } /// 获取当前 UTC 的毫秒时间戳。 public static long NowUtcStamp { get { return GetStamp(DateTime.UtcNow); } } /// 获取 1970-01-01 00:00:00.000 的时间对象。 public static DateTime Origin { get { return GetOrigin(); } } #endregion #region Public Methods /// 获取安全的 DateTime 对象。 public static DateTime GetDateTime(DateTime datetime) { var origin = GetOrigin(); var span = datetime - origin; var stemp = span.TotalMilliseconds; var safely = origin.AddMilliseconds(stemp); return safely; } /// 获取安全的 DateTime 对象。 public static DateTime ToDateTime(DateTime datetime) { return GetDateTime(datetime); } /// 从毫秒时间戳获取 DateTime 对象。发生异常且不允许异常时将返回 1970-01-01 00:00:00.000。 /// public static DateTime GetDateTime(long stamp, bool exceptable = true) { var origin = GetOrigin(); try { var datetime = origin.AddMilliseconds(Convert.ToDouble(stamp)); return datetime; } catch { if (exceptable) throw new ArgumentOutOfRangeException(); return origin; } } /// 从毫秒时间戳获取 DateTime 对象。发生异常且不允许异常时将返回 1970-01-01 00:00:00.000。 /// public static DateTime ToDateTime(long stamp, bool exceptable = true) { var origin = GetOrigin(); try { var datetime = origin.AddMilliseconds(Convert.ToDouble(stamp)); return datetime; } catch { if (exceptable) throw new ArgumentOutOfRangeException(); return origin; } } /// 获取毫秒时间戳。 public static long GetStamp(DateTime datetime) { var origin = GetOrigin(); var span = datetime - origin; var milliseconds = span.TotalMilliseconds; var result = Convert.ToInt64(milliseconds); return result; } /// 获取毫秒时间戳。 public static long ToStamp(DateTime datetime) { return GetStamp(datetime); } /// 判断是否为闰年。 public static bool IsLeapYear(int year) { if (year % 400 == 0) return true; if (year % 100 == 0) return false; if (year % 4 == 0) return true; return false; } /// 获取指定月份中的天数。 public static int GetDays(int year, int month) { switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: return 31; case 4: case 6: case 9: case 11: return 30; case 2: return IsLeapYear(year) ? 29 : 28; default: return 0; } } /// 转换 DateTime 对象到易于阅读的文本。 public static string ToLucid(DateTime datetime, bool date = true, bool time = true, bool seconds = true, bool milliseconds = true) { var safely = GetDateTime(datetime); var sb = new StringBuilder(); if (date) sb.Append(FormatDate(safely, true)); if (time) { if (date) sb.Append(" "); sb.Append(FormatTime(safely, true, seconds, milliseconds)); } var lucid = sb.ToString(); return lucid; } /// 转换 DateTime 对象到易于阅读的文本。 public static string GetLucid(DateTime datetime, bool date = true, bool time = true, bool seconds = true, bool milliseconds = true) { return GetLucid(datetime, date, time, seconds, milliseconds); } /// 转换 DateTime 对象到紧凑的文本。 public static string ToCompact(DateTime datetime, bool date = true, bool time = true, bool seconds = true, bool milliseconds = true) { var safely = GetDateTime(datetime); var sb = new StringBuilder(); if (date) sb.Append(FormatDate(safely, false)); if (time) { // if (date) sb.Append(" "); sb.Append(FormatTime(safely, false, seconds, milliseconds)); } var lucid = sb.ToString(); return lucid; } /// 转换 DateTime 对象到紧凑的文本。 public static string GetCompact(DateTime datetime, bool date = true, bool time = true, bool seconds = true, bool milliseconds = true) { return ToCompact(datetime, date, time, seconds, milliseconds); } /// 解析 Lucid 文本。 public static Nullable ParseLucid(string lucid) { var failed = new Nullable(); if (lucid.IsEmpty()) return failed; int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, milli = 0; if (lucid.Length < 10) return failed; if (lucid[4] != '-' || lucid[7] != '-') return failed; year = TextUtility.GetInt32(lucid.Substring(0, 4)); month = TextUtility.GetInt32(lucid.Substring(5, 2)); day = TextUtility.GetInt32(lucid.Substring(8, 2)); if (year < 1) return failed; if (month < 1 || month > 12) return failed; if (day < 1 || day > DateTime.DaysInMonth(year, month)) return failed; if (lucid.Length >= 16) { if (lucid[10] != ' ' || lucid[13] != ':') return failed; hour = TextUtility.GetInt32(lucid.Substring(11, 2)); minute = TextUtility.GetInt32(lucid.Substring(14, 2)); if (hour < 0 || hour > 23) return failed; if (minute < 0 || minute > 59) return failed; if (lucid.Length >= 19) { if (lucid[16] != ':') return failed; second = TextUtility.GetInt32(lucid.Substring(17, 2)); if (second < 0 || second > 59) return failed; if (lucid.Length >= 23) { if (lucid[19] != '.') return failed; milli = TextUtility.GetInt32(lucid.Substring(20, 3)); if (milli < 0 || milli > 999) return failed; } } } var entity = new DateTime(year, month, day, hour, minute, second, milli); return new Nullable(entity); } /// 创建新的零值 DateTime 对象。 public static DateTime Zero() => new DateTime(0L, DateTimeKind.Utc); #endregion } }