day.ts 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /**
  2. * 轻量级日期工具类
  3. * 基于 uni-app-x UTS Date API
  4. * 参考 dayjs 设计理念
  5. */
  6. export class DayUts {
  7. private _date: Date;
  8. constructor(date?: Date | string | number | null) {
  9. if (date == null || date == "") {
  10. this._date = new Date();
  11. } else if (typeof date == "string") {
  12. this._date = new Date(date);
  13. } else if (typeof date == "number") {
  14. this._date = new Date(date);
  15. } else if (date instanceof Date) {
  16. this._date = new Date(date.getTime());
  17. } else {
  18. this._date = new Date();
  19. }
  20. }
  21. /**
  22. * 格式化日期
  23. * @param template 格式模板,支持 YYYY-MM-DD HH:mm:ss 等
  24. */
  25. format(template: string): string {
  26. // 使用传入的模板
  27. let actualTemplate: string = template;
  28. const year = this._date.getFullYear();
  29. const month = this._date.getMonth() + 1;
  30. const date = this._date.getDate();
  31. const hours = this._date.getHours();
  32. const minutes = this._date.getMinutes();
  33. const seconds = this._date.getSeconds();
  34. const milliseconds = this._date.getMilliseconds();
  35. // 使用数组来依次替换,避免UTS的replace方法兼容性问题
  36. let result: string = actualTemplate;
  37. // 按照长度从长到短替换,避免冲突
  38. // 替换年份 (YYYY 必须在 YY 之前)
  39. result = result.replace("YYYY", year.toString());
  40. result = result.replace("YY", year.toString().slice(-2));
  41. // 替换月份 (MM 必须在 M 之前)
  42. result = result.replace("MM", month.toString().padStart(2, "0"));
  43. result = result.replace("M", month.toString());
  44. // 替换日期 (DD 必须在 D 之前)
  45. result = result.replace("DD", date.toString().padStart(2, "0"));
  46. result = result.replace("D", date.toString());
  47. // 替换小时 (HH 必须在 H 之前)
  48. result = result.replace("HH", hours.toString().padStart(2, "0"));
  49. result = result.replace("H", hours.toString());
  50. // 替换分钟 (mm 必须在 m 之前)
  51. result = result.replace("mm", minutes.toString().padStart(2, "0"));
  52. result = result.replace("m", minutes.toString());
  53. // 替换秒数 (ss 必须在 s 之前)
  54. result = result.replace("ss", seconds.toString().padStart(2, "0"));
  55. result = result.replace("s", seconds.toString());
  56. // 替换毫秒
  57. result = result.replace("SSS", milliseconds.toString().padStart(3, "0"));
  58. return result;
  59. }
  60. /**
  61. * 本月多少天
  62. */
  63. getDays(): number {
  64. return new Date(this._date.getFullYear(), this._date.getMonth() + 1, 0).getDate();
  65. }
  66. /**
  67. * 是否为闰年
  68. */
  69. isLeapYear(): boolean {
  70. return this._date.getFullYear() % 4 == 0 && this._date.getFullYear() % 100 != 0;
  71. }
  72. /**
  73. * 星期几
  74. */
  75. getDay(): number {
  76. return this._date.getDay();
  77. }
  78. /**
  79. * 获取某个单位的开始时间
  80. */
  81. startOf(unit: "month" | "day" | "year" | "week"): DayUts {
  82. const newDate = new Date(this._date.getTime());
  83. switch (unit) {
  84. case "year":
  85. newDate.setMonth(0);
  86. newDate.setDate(1);
  87. newDate.setHours(0);
  88. newDate.setMinutes(0);
  89. newDate.setSeconds(0);
  90. newDate.setMilliseconds(0);
  91. break;
  92. case "month":
  93. newDate.setDate(1);
  94. newDate.setHours(0);
  95. newDate.setMinutes(0);
  96. newDate.setSeconds(0);
  97. newDate.setMilliseconds(0);
  98. break;
  99. case "week":
  100. newDate.setDate(newDate.getDate() - newDate.getDay());
  101. newDate.setHours(0);
  102. newDate.setMinutes(0);
  103. newDate.setSeconds(0);
  104. newDate.setMilliseconds(0);
  105. break;
  106. case "day":
  107. newDate.setHours(0);
  108. newDate.setMinutes(0);
  109. newDate.setSeconds(0);
  110. newDate.setMilliseconds(0);
  111. break;
  112. }
  113. return new DayUts(newDate);
  114. }
  115. /**
  116. * 获取某个单位的结束时间
  117. */
  118. endOf(unit: "month" | "day" | "year" | "week"): DayUts {
  119. const newDate = new Date(this._date.getTime());
  120. switch (unit) {
  121. case "year":
  122. newDate.setMonth(11);
  123. newDate.setDate(31);
  124. newDate.setHours(23);
  125. newDate.setMinutes(59);
  126. newDate.setSeconds(59);
  127. newDate.setMilliseconds(999);
  128. break;
  129. case "month":
  130. newDate.setMonth(newDate.getMonth() + 1);
  131. newDate.setDate(0);
  132. newDate.setHours(23);
  133. newDate.setMinutes(59);
  134. newDate.setSeconds(59);
  135. newDate.setMilliseconds(999);
  136. break;
  137. case "week":
  138. const day = newDate.getDay();
  139. const diff = 6 - day;
  140. newDate.setDate(newDate.getDate() + diff);
  141. newDate.setHours(23);
  142. newDate.setMinutes(59);
  143. newDate.setSeconds(59);
  144. newDate.setMilliseconds(999);
  145. break;
  146. case "day":
  147. newDate.setHours(23);
  148. newDate.setMinutes(59);
  149. newDate.setSeconds(59);
  150. newDate.setMilliseconds(999);
  151. break;
  152. }
  153. return new DayUts(newDate);
  154. }
  155. /**
  156. * 判断是否早于另一个日期
  157. */
  158. isBefore(date: DayUts | Date | string | number): boolean {
  159. const compareDate = this._parseDate(date);
  160. return this._date.getTime() < compareDate.getTime();
  161. }
  162. /**
  163. * 判断是否晚于另一个日期
  164. */
  165. isAfter(date: DayUts | Date | string | number): boolean {
  166. const compareDate = this._parseDate(date);
  167. return this._date.getTime() > compareDate.getTime();
  168. }
  169. /**
  170. * 判断是否与另一个日期相同
  171. */
  172. isSame(date: DayUts | Date | string | number): boolean {
  173. const compareDate = this._parseDate(date);
  174. return this._date.getTime() == compareDate.getTime();
  175. }
  176. /**
  177. * 计算与另一个日期的差值(毫秒)
  178. */
  179. diff(date: DayUts | Date | string | number): number {
  180. const compareDate = this._parseDate(date);
  181. return this._date.getTime() - compareDate.getTime();
  182. }
  183. /**
  184. * 计算与另一个日期的差值(指定单位)
  185. */
  186. diffUnit(
  187. date: DayUts | Date | string | number,
  188. unit: "day" | "hour" | "minute" | "second" | "millisecond"
  189. ): number {
  190. const compareDate = this._parseDate(date);
  191. const diffMs = this._date.getTime() - compareDate.getTime();
  192. switch (unit) {
  193. case "day":
  194. return Math.floor(diffMs / (1000 * 60 * 60 * 24));
  195. case "hour":
  196. return Math.floor(diffMs / (1000 * 60 * 60));
  197. case "minute":
  198. return Math.floor(diffMs / (1000 * 60));
  199. case "second":
  200. return Math.floor(diffMs / 1000);
  201. case "millisecond":
  202. default:
  203. return diffMs;
  204. }
  205. }
  206. /**
  207. * 添加时间
  208. */
  209. add(value: number, unit: "day" | "month" | "year" | "hour" | "minute" | "second"): DayUts {
  210. const newDate = new Date(this._date.getTime());
  211. switch (unit) {
  212. case "year":
  213. newDate.setFullYear(newDate.getFullYear() + value);
  214. break;
  215. case "month":
  216. newDate.setMonth(newDate.getMonth() + value);
  217. break;
  218. case "day":
  219. newDate.setDate(newDate.getDate() + value);
  220. break;
  221. case "hour":
  222. newDate.setHours(newDate.getHours() + value);
  223. break;
  224. case "minute":
  225. newDate.setMinutes(newDate.getMinutes() + value);
  226. break;
  227. case "second":
  228. newDate.setSeconds(newDate.getSeconds() + value);
  229. break;
  230. }
  231. return new DayUts(newDate);
  232. }
  233. /**
  234. * 减少时间
  235. */
  236. subtract(value: number, unit: "day" | "month" | "year" | "hour" | "minute" | "second"): DayUts {
  237. return this.add(-value, unit);
  238. }
  239. /**
  240. * 获取时间戳
  241. */
  242. valueOf(): number {
  243. return this._date.getTime();
  244. }
  245. /**
  246. * 获取原生Date对象
  247. */
  248. toDate(): Date {
  249. return new Date(this._date.getTime());
  250. }
  251. /**
  252. * 获取日期数组
  253. */
  254. toArray(): number[] {
  255. return [
  256. this._date.getFullYear(),
  257. this._date.getMonth() + 1,
  258. this._date.getDate(),
  259. this._date.getHours(),
  260. this._date.getMinutes(),
  261. this._date.getSeconds()
  262. ];
  263. }
  264. /**
  265. * 私有方法:解析不同类型的日期参数
  266. */
  267. private _parseDate(date: DayUts | Date | string | number): Date {
  268. if (date instanceof DayUts) {
  269. return date.toDate();
  270. } else if (date instanceof Date) {
  271. return date;
  272. } else if (typeof date == "string") {
  273. return new Date(date);
  274. } else if (typeof date == "number") {
  275. return new Date(date);
  276. } else {
  277. // 如果都不匹配,返回当前时间
  278. return new Date();
  279. }
  280. }
  281. }
  282. /**
  283. * 创建 DayUts 实例
  284. */
  285. export function dayUts(date: Date | string | number | null = new Date()): DayUts {
  286. return new DayUts(date);
  287. }