DateTimeHelper.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Globalization;
  5. using System.Linq;
  6. using System.Runtime.InteropServices;
  7. using Masuit.Tools.Models;
  8. namespace Masuit.Tools.DateTimeExt
  9. {
  10. /// <summary>
  11. /// 日期操作工具类
  12. /// </summary>
  13. public static class DateTimeHelper
  14. {
  15. /// <summary>
  16. /// 获取某一年有多少周
  17. /// </summary>
  18. /// <param name="now"></param>
  19. /// <returns>该年周数</returns>
  20. public static int GetWeekAmount(this in DateTime now)
  21. {
  22. var end = new DateTime(now.Year, 12, 31); //该年最后一天
  23. var gc = new GregorianCalendar();
  24. return gc.GetWeekOfYear(end, CalendarWeekRule.FirstDay, DayOfWeek.Monday); //该年星期数
  25. }
  26. /// <summary>
  27. /// 返回年度第几个星期 默认星期日是第一天
  28. /// </summary>
  29. /// <param name="date">时间</param>
  30. /// <returns>第几周</returns>
  31. public static int WeekOfYear(this in DateTime date)
  32. {
  33. var gc = new GregorianCalendar();
  34. return gc.GetWeekOfYear(date, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
  35. }
  36. /// <summary>
  37. /// 返回年度第几个星期
  38. /// </summary>
  39. /// <param name="date">时间</param>
  40. /// <param name="week">一周的开始日期</param>
  41. /// <returns>第几周</returns>
  42. public static int WeekOfYear(this in DateTime date, DayOfWeek week)
  43. {
  44. var gc = new GregorianCalendar();
  45. return gc.GetWeekOfYear(date, CalendarWeekRule.FirstDay, week);
  46. }
  47. /// <summary>
  48. /// 得到一年中的某周的起始日和截止日
  49. /// 周数 nNumWeek
  50. /// </summary>
  51. /// <param name="now"></param>
  52. /// <param name="nNumWeek">第几周</param>
  53. public static DateTimeRange GetWeekTime(this DateTime now, int nNumWeek)
  54. {
  55. var dt = new DateTime(now.Year, 1, 1);
  56. dt += new TimeSpan((nNumWeek - 1) * 7, 0, 0, 0);
  57. return GetCurrentWeek(dt);
  58. }
  59. /// <summary>
  60. /// 得到当前周的起始日和截止日
  61. /// </summary>
  62. /// <param name="dt"></param>
  63. public static DateTimeRange GetCurrentWeek(this DateTime dt)
  64. {
  65. CultureInfo culture = CultureInfo.CurrentCulture;
  66. DayOfWeek firstDayOfWeek = culture.DateTimeFormat.FirstDayOfWeek;
  67. // 计算星期的起始日期(第一天)
  68. DateTime startOfWeek = dt.Date;
  69. while (startOfWeek.DayOfWeek != firstDayOfWeek)
  70. {
  71. startOfWeek = startOfWeek.AddDays(-1);
  72. }
  73. // 计算星期的结束日期(最后一天)
  74. DateTime endOfWeek = startOfWeek.AddDays(6).AddSeconds(86399);
  75. return new DateTimeRange(startOfWeek, endOfWeek);
  76. }
  77. /// <summary>
  78. /// 得到当前月的起始日和截止日
  79. /// </summary>
  80. /// <param name="dt"></param>
  81. public static DateTimeRange GetCurrentMonth(this DateTime dt)
  82. {
  83. return new DateTimeRange(new DateTime(dt.Year, dt.Month, 1), new DateTime(dt.Year, dt.Month, GetDaysOfMonth(dt), 23, 59, 59));
  84. }
  85. /// <summary>
  86. /// 得到当前农历月的起始日和截止日
  87. /// </summary>
  88. /// <param name="dt"></param>
  89. public static DateTimeRange GetCurrentLunarMonth(this DateTime dt)
  90. {
  91. var calendar = new ChineseCalendar(dt);
  92. return new DateTimeRange(new ChineseCalendar(calendar.ChineseYear, calendar.ChineseMonth, 1).Date, new ChineseCalendar(calendar.ChineseYear, calendar.ChineseMonth, calendar.GetChineseMonthDays()).Date.AddSeconds(86399));
  93. }
  94. /// <summary>
  95. /// 得到当前年的起始日和截止日
  96. /// </summary>
  97. /// <param name="dt"></param>
  98. public static DateTimeRange GetCurrentYear(this DateTime dt)
  99. {
  100. return new DateTimeRange(new DateTime(dt.Year, 1, 1), new DateTime(dt.Year, 12, 31, 23, 59, 59));
  101. }
  102. /// <summary>
  103. /// 得到当前农历年的起始日和截止日
  104. /// </summary>
  105. /// <param name="dt"></param>
  106. public static DateTimeRange GetCurrentLunarYear(this DateTime dt)
  107. {
  108. var calendar = new ChineseCalendar(dt);
  109. return new DateTimeRange(new ChineseCalendar(calendar.ChineseYear, 1, 1).Date, new ChineseCalendar(calendar.ChineseYear, 12, calendar.GetChineseMonthDays(calendar.ChineseYear, 12)).Date.AddSeconds(86399));
  110. }
  111. /// <summary>
  112. /// 得到当前季度的起始日和截止日
  113. /// </summary>
  114. /// <param name="dt"></param>
  115. public static DateTimeRange GetCurrentQuarter(this DateTime dt)
  116. {
  117. return dt.Month switch
  118. {
  119. >= 1 and <= 3 => new DateTimeRange(new DateTime(dt.Year, 1, 1), new DateTime(dt.Year, 3, 31, 23, 59, 59)),
  120. >= 4 and <= 6 => new DateTimeRange(new DateTime(dt.Year, 4, 1), new DateTime(dt.Year, 6, 30, 23, 59, 59)),
  121. >= 7 and <= 9 => new DateTimeRange(new DateTime(dt.Year, 7, 1), new DateTime(dt.Year, 9, 30, 23, 59, 59)),
  122. >= 10 and <= 12 => new DateTimeRange(new DateTime(dt.Year, 10, 1), new DateTime(dt.Year, 12, 31, 23, 59, 59)),
  123. _ => throw new ArgumentOutOfRangeException()
  124. };
  125. }
  126. /// <summary>
  127. /// 得到当前农历季度的起始日和截止日
  128. /// </summary>
  129. /// <param name="dt"></param>
  130. public static DateTimeRange GetCurrentLunarQuarter(this DateTime dt)
  131. {
  132. var calendar = new ChineseCalendar(dt);
  133. return dt.Month switch
  134. {
  135. >= 1 and <= 3 => new DateTimeRange(new ChineseCalendar(calendar.ChineseYear, 1, 1).Date, new ChineseCalendar(calendar.ChineseYear, 3, calendar.GetChineseMonthDays(calendar.ChineseYear, 3)).Date.AddSeconds(86399)),
  136. >= 4 and <= 6 => new DateTimeRange(new ChineseCalendar(calendar.ChineseYear, 4, 1).Date, new ChineseCalendar(calendar.ChineseYear, 6, calendar.GetChineseMonthDays(calendar.ChineseYear, 6)).Date.AddSeconds(86399)),
  137. >= 7 and <= 9 => new DateTimeRange(new ChineseCalendar(calendar.ChineseYear, 7, 1).Date, new ChineseCalendar(calendar.ChineseYear, 9, calendar.GetChineseMonthDays(calendar.ChineseYear, 9)).Date.AddSeconds(86399)),
  138. >= 10 and <= 12 => new DateTimeRange(new ChineseCalendar(calendar.ChineseYear, 10, 1).Date, new ChineseCalendar(calendar.ChineseYear, 12, calendar.GetChineseMonthDays(calendar.ChineseYear, 12)).Date.AddSeconds(86399)),
  139. _ => throw new ArgumentOutOfRangeException()
  140. };
  141. }
  142. /// <summary>
  143. /// 得到当前农历季度的起始日和截止日
  144. /// </summary>
  145. /// <param name="dt"></param>
  146. public static DateTimeRange GetCurrentSolar(this DateTime dt)
  147. {
  148. var calendar = new ChineseCalendar(dt);
  149. ChineseCalendar[] quarters =
  150. [
  151. calendar.ChineseTwentyFourPrevDay.ChineseTwentyFourPrevDay.ChineseTwentyFourPrevDay,
  152. calendar.ChineseTwentyFourPrevDay.ChineseTwentyFourPrevDay,
  153. calendar.ChineseTwentyFourPrevDay,
  154. calendar,
  155. calendar.ChineseTwentyFourNextDay,
  156. calendar.ChineseTwentyFourNextDay.ChineseTwentyFourNextDay,
  157. calendar.ChineseTwentyFourNextDay.ChineseTwentyFourNextDay.ChineseTwentyFourNextDay
  158. ];
  159. var solar = quarters.LastOrDefault(c => new[] { "春分", "夏至", "秋分", "冬至" }.Contains(c.ChineseTwentyFourDay));
  160. var start = solar.ChineseTwentyFourPrevDay.ChineseTwentyFourPrevDay.ChineseTwentyFourPrevDay;
  161. var end = solar.ChineseTwentyFourNextDay.ChineseTwentyFourNextDay.ChineseTwentyFourNextDay;
  162. return new DateTimeRange(start.Date, end.Date.AddSeconds(-1));
  163. }
  164. /// <summary>
  165. /// 得到当前范围的起始日和截止日
  166. /// </summary>
  167. /// <param name="dt"></param>
  168. /// <param name="type"></param>
  169. public static DateTimeRange GetCurrentRange(this DateTime dt, DateRangeType type)
  170. {
  171. return type switch
  172. {
  173. DateRangeType.Week => GetCurrentWeek(dt),
  174. DateRangeType.Month => GetCurrentMonth(dt),
  175. DateRangeType.Quarter => GetCurrentQuarter(dt),
  176. DateRangeType.Year => GetCurrentYear(dt),
  177. DateRangeType.LunarMonth => GetCurrentLunarMonth(dt),
  178. DateRangeType.LunarQuarter => GetCurrentLunarQuarter(dt),
  179. DateRangeType.Solar => GetCurrentSolar(dt),
  180. DateRangeType.LunarYear => GetCurrentLunarYear(dt),
  181. _ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
  182. };
  183. }
  184. #region P/Invoke 设置本地时间
  185. [DllImport("kernel32.dll")]
  186. private static extern bool SetLocalTime(ref SystemTime time);
  187. [StructLayout(LayoutKind.Sequential)]
  188. private record struct SystemTime
  189. {
  190. public short year;
  191. public short month;
  192. public short dayOfWeek;
  193. public short day;
  194. public short hour;
  195. public short minute;
  196. public short second;
  197. public short milliseconds;
  198. }
  199. /// <summary>
  200. /// 设置本地计算机系统时间,仅支持Windows系统
  201. /// </summary>
  202. /// <param name="dt">DateTime对象</param>
  203. public static void SetLocalTime(this in DateTime dt)
  204. {
  205. SystemTime st;
  206. st.year = (short)dt.Year;
  207. st.month = (short)dt.Month;
  208. st.dayOfWeek = (short)dt.DayOfWeek;
  209. st.day = (short)dt.Day;
  210. st.hour = (short)dt.Hour;
  211. st.minute = (short)dt.Minute;
  212. st.second = (short)dt.Second;
  213. st.milliseconds = (short)dt.Millisecond;
  214. SetLocalTime(ref st);
  215. }
  216. #endregion P/Invoke 设置本地时间
  217. /// <summary>
  218. /// 返回相对于当前时间的相对天数
  219. /// </summary>
  220. /// <param name="dt"></param>
  221. /// <param name="relativeday">相对天数</param>
  222. public static string GetDateTime(this in DateTime dt, int relativeday)
  223. {
  224. return dt.AddDays(relativeday).ToString("yyyy-MM-dd HH:mm:ss");
  225. }
  226. /// <summary>
  227. /// 获取该时间相对于1970-01-01T00:00:00Z的秒数
  228. /// </summary>
  229. /// <param name="dt"></param>
  230. /// <returns></returns>
  231. public static long GetTotalSeconds(this in DateTime dt) => new DateTimeOffset(dt).UtcDateTime.Ticks / 10_000_000L - 62135596800L;
  232. /// <summary>
  233. /// 获取该时间相对于1970-01-01T00:00:00Z的毫秒数
  234. /// </summary>
  235. /// <param name="dt"></param>
  236. /// <returns></returns>
  237. public static long GetTotalMilliseconds(this in DateTime dt) => new DateTimeOffset(dt).UtcDateTime.Ticks / 10000L - 62135596800000L;
  238. /// <summary>
  239. /// 获取该时间相对于1970-01-01T00:00:00Z的微秒时间戳
  240. /// </summary>
  241. /// <param name="dt"></param>
  242. /// <returns></returns>
  243. public static long GetTotalMicroseconds(this in DateTime dt) => (new DateTimeOffset(dt).UtcTicks - 621355968000000000) / 10;
  244. [DllImport("Kernel32.dll")]
  245. private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
  246. /// <summary>
  247. /// 获取该时间相对于1970-01-01T00:00:00Z的纳秒时间戳
  248. /// </summary>
  249. /// <param name="dt"></param>
  250. /// <returns></returns>
  251. public static long GetTotalNanoseconds(this in DateTime dt)
  252. {
  253. var ticks = (new DateTimeOffset(dt).UtcTicks - 621355968000000000) * 100;
  254. if (Environment.OSVersion.Platform == PlatformID.Win32NT)
  255. {
  256. QueryPerformanceCounter(out var timestamp);
  257. return ticks + timestamp % 100;
  258. }
  259. return ticks + Stopwatch.GetTimestamp() % 100;
  260. }
  261. /// <summary>
  262. /// 获取该时间相对于1970-01-01T00:00:00Z的分钟数
  263. /// </summary>
  264. /// <param name="dt"></param>
  265. /// <returns></returns>
  266. public static long GetTotalMinutes(this in DateTime dt) => GetTotalSeconds(dt) / 60;
  267. /// <summary>
  268. /// 获取该时间相对于1970-01-01T00:00:00Z的小时数
  269. /// </summary>
  270. /// <param name="dt"></param>
  271. /// <returns></returns>
  272. public static long GetTotalHours(this in DateTime dt) => GetTotalSeconds(dt) / 3600;
  273. /// <summary>
  274. /// 获取该时间相对于1970-01-01T00:00:00Z的天数
  275. /// </summary>
  276. /// <param name="dt"></param>
  277. /// <returns></returns>
  278. public static long GetTotalDays(this in DateTime dt) => GetTotalSeconds(dt) / 86400;
  279. /// <summary>本年有多少天</summary>
  280. /// <param name="dt">日期</param>
  281. /// <returns>本天在当年的天数</returns>
  282. public static int GetDaysOfYear(this in DateTime dt)
  283. {
  284. //取得传入参数的年份部分,用来判断是否是闰年
  285. int n = dt.Year;
  286. return DateTime.IsLeapYear(n) ? 366 : 365;
  287. }
  288. /// <summary>本月有多少天</summary>
  289. /// <param name="now"></param>
  290. /// <returns>天数</returns>
  291. public static int GetDaysOfMonth(this DateTime now)
  292. {
  293. return now.Month switch
  294. {
  295. 1 => 31,
  296. 2 => DateTime.IsLeapYear(now.Year) ? 29 : 28,
  297. 3 => 31,
  298. 4 => 30,
  299. 5 => 31,
  300. 6 => 30,
  301. 7 => 31,
  302. 8 => 31,
  303. 9 => 30,
  304. 10 => 31,
  305. 11 => 30,
  306. 12 => 31,
  307. _ => 0
  308. };
  309. }
  310. /// <summary>返回当前日期的星期名称</summary>
  311. /// <param name="now">日期</param>
  312. /// <returns>星期名称</returns>
  313. public static string GetWeekNameOfDay(this in DateTime now)
  314. {
  315. return now.DayOfWeek switch
  316. {
  317. DayOfWeek.Monday => "星期一",
  318. DayOfWeek.Tuesday => "星期二",
  319. DayOfWeek.Wednesday => "星期三",
  320. DayOfWeek.Thursday => "星期四",
  321. DayOfWeek.Friday => "星期五",
  322. DayOfWeek.Saturday => "星期六",
  323. DayOfWeek.Sunday => "星期日",
  324. _ => ""
  325. };
  326. }
  327. /// <summary>
  328. /// 判断时间是否在区间内
  329. /// </summary>
  330. /// <param name="this"></param>
  331. /// <param name="start">开始</param>
  332. /// <param name="end">结束</param>
  333. /// <param name="mode">模式</param>
  334. /// <returns></returns>
  335. public static bool In(this in DateTime @this, DateTime? start, DateTime? end, RangeMode mode = RangeMode.Close)
  336. {
  337. start ??= DateTime.MinValue;
  338. end ??= DateTime.MaxValue;
  339. return mode switch
  340. {
  341. RangeMode.Open => start < @this && end > @this,
  342. RangeMode.Close => start <= @this && end >= @this,
  343. RangeMode.OpenClose => start < @this && end >= @this,
  344. RangeMode.CloseOpen => start <= @this && end > @this,
  345. _ => throw new ArgumentOutOfRangeException(nameof(mode), mode, null)
  346. };
  347. }
  348. /// <summary>
  349. /// 返回某年某月最后一天
  350. /// </summary>
  351. /// <param name="now"></param>
  352. /// <returns>日</returns>
  353. public static int GetMonthLastDate(this DateTime now)
  354. {
  355. DateTime lastDay = new DateTime(now.Year, now.Month, new GregorianCalendar().GetDaysInMonth(now.Year, now.Month));
  356. return lastDay.Day;
  357. }
  358. /// <summary>
  359. /// 获得一段时间内有多少小时
  360. /// </summary>
  361. /// <param name="start">起始时间</param>
  362. /// <param name="end">终止时间</param>
  363. /// <returns>小时差</returns>
  364. public static string GetTimeDelay(this in DateTime start, DateTime end)
  365. {
  366. return (end - start).ToString("c");
  367. }
  368. /// <summary>
  369. /// 返回时间差
  370. /// </summary>
  371. /// <param name="dateTime1">时间1</param>
  372. /// <param name="dateTime2">时间2</param>
  373. /// <returns>时间差</returns>
  374. public static string DateDiff(this in DateTime dateTime1, in DateTime dateTime2)
  375. {
  376. string dateDiff;
  377. var ts = dateTime2 - dateTime1;
  378. if (ts.TotalDays >= 1)
  379. {
  380. dateDiff = ts.TotalDays >= 30 ? (ts.TotalDays / 30) + "个月前" : ts.TotalDays + "天前";
  381. }
  382. else
  383. {
  384. dateDiff = ts.Hours > 1 ? ts.Hours + "小时前" : ts.Minutes + "分钟前";
  385. }
  386. return dateDiff;
  387. }
  388. /// <summary>
  389. /// 计算2个时间差
  390. /// </summary>
  391. /// <param name="beginTime">开始时间</param>
  392. /// <param name="endTime">结束时间</param>
  393. /// <returns>时间差</returns>
  394. public static string GetDiffTime(this in DateTime beginTime, in DateTime endTime)
  395. {
  396. string strResout = string.Empty;
  397. //获得2时间的时间间隔秒计算
  398. TimeSpan span = endTime.Subtract(beginTime);
  399. if (span.Days >= 365)
  400. {
  401. strResout += span.Days / 365 + "年";
  402. }
  403. if (span.Days >= 30)
  404. {
  405. strResout += span.Days % 365 / 30 + "个月";
  406. }
  407. if (span.Days >= 1)
  408. {
  409. strResout += (int)(span.TotalDays % 30.42) + "天";
  410. }
  411. if (span.Hours >= 1)
  412. {
  413. strResout += span.Hours + "小时";
  414. }
  415. if (span.Minutes >= 1)
  416. {
  417. strResout += span.Minutes + "分钟";
  418. }
  419. if (span.Seconds >= 1)
  420. {
  421. strResout += span.Seconds + "秒";
  422. }
  423. return strResout;
  424. }
  425. /// <summary>
  426. /// 根据某个时间段查找在某批时间段中的最大并集
  427. /// </summary>
  428. /// <param name="destination"></param>
  429. /// <param name="sources"></param>
  430. /// <typeparam name="T"></typeparam>
  431. /// <returns></returns>
  432. public static ICollection<T> GetUnionSet<T>(this T destination, List<T> sources) where T : ITimePeriod, new()
  433. {
  434. var result = true;
  435. ICollection<T> frames = new List<T>();
  436. var timeFrames = sources.Where(frame =>
  437. !(destination.Start > frame.End || destination.End < frame.Start)).ToList();
  438. if (timeFrames.Any())
  439. foreach (var frame in timeFrames)
  440. {
  441. frames.Add(frame);
  442. sources.Remove(frame);
  443. }
  444. if (!frames.Any()) return frames;
  445. var timePeriod = new T()
  446. {
  447. End = frames.OrderBy(frame => frame.End).Max(frame => frame.End),
  448. Start = frames.OrderBy(frame => frame.Start).Min(frame => frame.Start)
  449. };
  450. while (result)
  451. {
  452. var maxTimeFrame = GetUnionSet<T>(timePeriod, sources);
  453. if (!maxTimeFrame.Any())
  454. result = false;
  455. else
  456. foreach (var frame in maxTimeFrame)
  457. frames.Add(frame);
  458. }
  459. return frames;
  460. }
  461. /// <summary>
  462. /// 获取一批时间段内存在相互重叠的最大时间段
  463. /// </summary>
  464. /// <param name="destination">基础时间段</param>
  465. /// <param name="sources">一批时间段</param>
  466. /// <typeparam name="T"></typeparam>
  467. /// <returns></returns>
  468. /// <remarks>源数据sources 会受到影响</remarks>
  469. public static T GetMaxTimePeriod<T>(this T destination, List<T> sources) where T : ITimePeriod, new()
  470. {
  471. var list = sources.Select(period => new T()
  472. {
  473. End = period.End,
  474. Start = period.Start,
  475. }).ToList();
  476. var timePeriods = GetUnionSet(destination, list);
  477. return new T()
  478. {
  479. End = timePeriods.OrderBy(period => period.End).Max(period => period.End),
  480. Start = timePeriods.OrderBy(period => period.Start).Min(period => period.Start)
  481. };
  482. }
  483. }
  484. /// <summary>
  485. ///
  486. /// </summary>
  487. public interface ITimePeriod
  488. {
  489. /// <summary>
  490. /// 起始时间
  491. /// </summary>
  492. public DateTime? Start { get; set; }
  493. /// <summary>
  494. /// 终止时间
  495. /// </summary>
  496. public DateTime? End { get; set; }
  497. }
  498. /// <summary>
  499. /// 区间模式
  500. /// </summary>
  501. public enum RangeMode
  502. {
  503. /// <summary>
  504. /// 开区间
  505. /// </summary>
  506. Open,
  507. /// <summary>
  508. /// 闭区间
  509. /// </summary>
  510. Close,
  511. /// <summary>
  512. /// 左开右闭区间
  513. /// </summary>
  514. OpenClose,
  515. /// <summary>
  516. /// 左闭右开区间
  517. /// </summary>
  518. CloseOpen
  519. }
  520. public enum DateRangeType
  521. {
  522. Week,
  523. Month,
  524. Quarter,
  525. Year,
  526. LunarMonth,
  527. LunarQuarter,
  528. Solar,
  529. LunarYear,
  530. }
  531. }