You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

283 lines
10 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace Apewer
  5. {
  6. /// <summary>System.DateTime 实用工具。</summary>
  7. public class DateTimeUtility
  8. {
  9. #region Private Methods
  10. private static DateTime GetOrigin()
  11. {
  12. return new DateTime(1970, 1, 1, 0, 0, 0, 0);
  13. }
  14. private static string FormatDate(DateTime datetime, bool lucid)
  15. {
  16. var sb = new StringBuilder();
  17. var y = NumberUtility.RestrictValue(datetime.Year, 0, 9999);
  18. var m = NumberUtility.RestrictValue(datetime.Month, 1, 12);
  19. var d = NumberUtility.RestrictValue(datetime.Day, 1, GetDays(y, m));
  20. if (y < 10) sb.Append("000");
  21. else if (y < 100) sb.Append("00");
  22. else if (y < 1000) sb.Append("0");
  23. sb.Append(y.ToString());
  24. if (lucid) sb.Append("-");
  25. if (m < 10) sb.Append("0");
  26. sb.Append(m.ToString());
  27. if (lucid) sb.Append("-");
  28. if (d < 10) sb.Append("0");
  29. sb.Append(d.ToString());
  30. var date = sb.ToString();
  31. return date;
  32. }
  33. private static string FormatTime(DateTime datetime, bool lucid, bool seconds, bool milliseconds)
  34. {
  35. var sb = new StringBuilder();
  36. var h = NumberUtility.RestrictValue(datetime.Hour, 0, 23);
  37. var m = NumberUtility.RestrictValue(datetime.Minute, 0, 59);
  38. var s = NumberUtility.RestrictValue(datetime.Second, 0, 59);
  39. var ms = NumberUtility.RestrictValue(datetime.Millisecond, 0, 999);
  40. if (h < 10) sb.Append("0");
  41. sb.Append(h.ToString());
  42. if (lucid) sb.Append(":");
  43. if (m < 10) sb.Append("0");
  44. sb.Append(m.ToString());
  45. if (seconds)
  46. {
  47. if (lucid) sb.Append(":");
  48. if (s < 10) sb.Append("0");
  49. sb.Append(s.ToString());
  50. if (milliseconds)
  51. {
  52. if (lucid) sb.Append(".");
  53. if (ms < 10) sb.Append("00");
  54. else if (ms < 100) sb.Append("0");
  55. sb.Append(ms.ToString());
  56. }
  57. }
  58. var time = sb.ToString();
  59. return time;
  60. }
  61. #endregion
  62. #region Public Properties
  63. /// <summary>获取当前本地时间的易读格式文本。</summary>
  64. public static string NowLucid { get { return ToLucid(DateTime.Now); } }
  65. /// <summary>获取当前 UTC 的易读格式文本。</summary>
  66. public static string NowUtcLucid { get { return ToLucid(DateTime.UtcNow); } }
  67. /// <summary>获取当前本地时间的毫秒时间戳。</summary>
  68. public static long NowStamp { get { return GetStamp(DateTime.Now); } }
  69. /// <summary>获取当前 UTC 的毫秒时间戳。</summary>
  70. public static long NowUtcStamp { get { return GetStamp(DateTime.UtcNow); } }
  71. /// <summary>获取 1970-01-01 00:00:00.000 的时间对象。</summary>
  72. public static DateTime Origin { get { return GetOrigin(); } }
  73. #endregion
  74. #region Public Methods
  75. /// <summary>获取安全的 DateTime 对象。</summary>
  76. public static DateTime GetDateTime(DateTime datetime)
  77. {
  78. var origin = GetOrigin();
  79. var span = datetime - origin;
  80. var stemp = span.TotalMilliseconds;
  81. var safely = origin.AddMilliseconds(stemp);
  82. return safely;
  83. }
  84. /// <summary>获取安全的 DateTime 对象。</summary>
  85. public static DateTime ToDateTime(DateTime datetime)
  86. {
  87. return GetDateTime(datetime);
  88. }
  89. /// <summary>从毫秒时间戳获取 DateTime 对象。发生异常且不允许异常时将返回 1970-01-01 00:00:00.000。</summary>
  90. /// <exception cref="System.ArgumentOutOfRangeException"></exception>
  91. public static DateTime GetDateTime(long stamp, bool exceptable = true)
  92. {
  93. var origin = GetOrigin();
  94. try
  95. {
  96. var datetime = origin.AddMilliseconds(Convert.ToDouble(stamp));
  97. return datetime;
  98. }
  99. catch
  100. {
  101. if (exceptable) throw new ArgumentOutOfRangeException();
  102. return origin;
  103. }
  104. }
  105. /// <summary>从毫秒时间戳获取 DateTime 对象。发生异常且不允许异常时将返回 1970-01-01 00:00:00.000。</summary>
  106. /// <exception cref="System.ArgumentOutOfRangeException"></exception>
  107. public static DateTime ToDateTime(long stamp, bool exceptable = true)
  108. {
  109. var origin = GetOrigin();
  110. try
  111. {
  112. var datetime = origin.AddMilliseconds(Convert.ToDouble(stamp));
  113. return datetime;
  114. }
  115. catch
  116. {
  117. if (exceptable) throw new ArgumentOutOfRangeException();
  118. return origin;
  119. }
  120. }
  121. /// <summary>获取毫秒时间戳。</summary>
  122. public static long GetStamp(DateTime datetime)
  123. {
  124. var origin = GetOrigin();
  125. var span = datetime - origin;
  126. var milliseconds = span.TotalMilliseconds;
  127. var result = Convert.ToInt64(milliseconds);
  128. return result;
  129. }
  130. /// <summary>获取毫秒时间戳。</summary>
  131. public static long ToStamp(DateTime datetime)
  132. {
  133. return GetStamp(datetime);
  134. }
  135. /// <summary>判断是否为闰年。</summary>
  136. public static bool IsLeapYear(int year)
  137. {
  138. if (year % 400 == 0) return true;
  139. if (year % 100 == 0) return false;
  140. if (year % 4 == 0) return true;
  141. return false;
  142. }
  143. /// <summary>获取指定月份中的天数。</summary>
  144. public static int GetDays(int year, int month)
  145. {
  146. switch (month)
  147. {
  148. case 1: case 3: case 5: case 7: case 8: case 10: case 12: return 31;
  149. case 4: case 6: case 9: case 11: return 30;
  150. case 2: return IsLeapYear(year) ? 29 : 28;
  151. default: return 0;
  152. }
  153. }
  154. /// <summary>转换 DateTime 对象到易于阅读的文本。</summary>
  155. public static string ToLucid(DateTime datetime, bool date = true, bool time = true, bool seconds = true, bool milliseconds = true)
  156. {
  157. var safely = GetDateTime(datetime);
  158. var sb = new StringBuilder();
  159. if (date) sb.Append(FormatDate(safely, true));
  160. if (time)
  161. {
  162. if (date) sb.Append(" ");
  163. sb.Append(FormatTime(safely, true, seconds, milliseconds));
  164. }
  165. var lucid = sb.ToString();
  166. return lucid;
  167. }
  168. /// <summary>转换 DateTime 对象到易于阅读的文本。</summary>
  169. public static string GetLucid(DateTime datetime, bool date = true, bool time = true, bool seconds = true, bool milliseconds = true)
  170. {
  171. return GetLucid(datetime, date, time, seconds, milliseconds);
  172. }
  173. /// <summary>转换 DateTime 对象到紧凑的文本。</summary>
  174. public static string ToCompact(DateTime datetime, bool date = true, bool time = true, bool seconds = true, bool milliseconds = true)
  175. {
  176. var safely = GetDateTime(datetime);
  177. var sb = new StringBuilder();
  178. if (date) sb.Append(FormatDate(safely, false));
  179. if (time)
  180. {
  181. // if (date) sb.Append(" ");
  182. sb.Append(FormatTime(safely, false, seconds, milliseconds));
  183. }
  184. var lucid = sb.ToString();
  185. return lucid;
  186. }
  187. /// <summary>转换 DateTime 对象到紧凑的文本。</summary>
  188. public static string GetCompact(DateTime datetime, bool date = true, bool time = true, bool seconds = true, bool milliseconds = true)
  189. {
  190. return ToCompact(datetime, date, time, seconds, milliseconds);
  191. }
  192. /// <summary>解析 Lucid 文本。</summary>
  193. public static Nullable<DateTime> ParseLucid(string lucid)
  194. {
  195. var failed = new Nullable<DateTime>();
  196. if (lucid.IsEmpty()) return failed;
  197. int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, milli = 0;
  198. if (lucid.Length < 10) return failed;
  199. if (lucid[4] != '-' || lucid[7] != '-') return failed;
  200. year = TextUtility.GetInt32(lucid.Substring(0, 4));
  201. month = TextUtility.GetInt32(lucid.Substring(5, 2));
  202. day = TextUtility.GetInt32(lucid.Substring(8, 2));
  203. if (year < 1) return failed;
  204. if (month < 1 || month > 12) return failed;
  205. if (day < 1 || day > DateTime.DaysInMonth(year, month)) return failed;
  206. if (lucid.Length >= 16)
  207. {
  208. if (lucid[10] != ' ' || lucid[13] != ':') return failed;
  209. hour = TextUtility.GetInt32(lucid.Substring(11, 2));
  210. minute = TextUtility.GetInt32(lucid.Substring(14, 2));
  211. if (hour < 0 || hour > 23) return failed;
  212. if (minute < 0 || minute > 59) return failed;
  213. if (lucid.Length >= 19)
  214. {
  215. if (lucid[16] != ':') return failed;
  216. second = TextUtility.GetInt32(lucid.Substring(17, 2));
  217. if (second < 0 || second > 59) return failed;
  218. if (lucid.Length >= 23)
  219. {
  220. if (lucid[19] != '.') return failed;
  221. milli = TextUtility.GetInt32(lucid.Substring(20, 3));
  222. if (milli < 0 || milli > 999) return failed;
  223. }
  224. }
  225. }
  226. var entity = new DateTime(year, month, day, hour, minute, second, milli);
  227. return new Nullable<DateTime>(entity);
  228. }
  229. #endregion
  230. }
  231. }