gitea源码

time.ts 2.5KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import dayjs from 'dayjs';
  2. import utc from 'dayjs/plugin/utc.js';
  3. import {getCurrentLocale} from '../utils.ts';
  4. import type {ConfigType} from 'dayjs';
  5. dayjs.extend(utc);
  6. /**
  7. * Returns an array of millisecond-timestamps of start-of-week days (Sundays)
  8. *
  9. * @param startDate The start date. Can take any type that dayjs accepts.
  10. * @param endDate The end date. Can take any type that dayjs accepts.
  11. */
  12. export function startDaysBetween(startDate: ConfigType, endDate: ConfigType): number[] {
  13. const start = dayjs.utc(startDate);
  14. const end = dayjs.utc(endDate);
  15. let current = start;
  16. // Ensure the start date is a Sunday
  17. while (current.day() !== 0) {
  18. current = current.add(1, 'day');
  19. }
  20. const startDays: number[] = [];
  21. while (current.isBefore(end)) {
  22. startDays.push(current.valueOf());
  23. current = current.add(1, 'week');
  24. }
  25. return startDays;
  26. }
  27. export function firstStartDateAfterDate(inputDate: Date): number {
  28. if (!(inputDate instanceof Date)) {
  29. throw new Error('Invalid date');
  30. }
  31. const dayOfWeek = inputDate.getUTCDay();
  32. const daysUntilSunday = 7 - dayOfWeek;
  33. const resultDate = new Date(inputDate.getTime());
  34. resultDate.setUTCDate(resultDate.getUTCDate() + daysUntilSunday);
  35. return resultDate.valueOf();
  36. }
  37. export type DayData = {
  38. week: number,
  39. additions: number,
  40. deletions: number,
  41. commits: number,
  42. };
  43. export type DayDataObject = {
  44. [timestamp: string]: DayData,
  45. };
  46. export function fillEmptyStartDaysWithZeroes(startDays: number[], data: DayDataObject): DayData[] {
  47. const result: Record<string, any> = {};
  48. for (const startDay of startDays) {
  49. result[startDay] = data[startDay] || {'week': startDay, 'additions': 0, 'deletions': 0, 'commits': 0};
  50. }
  51. return Object.values(result);
  52. }
  53. let dateFormat: Intl.DateTimeFormat;
  54. /** Format a Date object to document's locale, but with 24h format from user's current locale because this
  55. * option is a personal preference of the user, not something that the document's locale should dictate. */
  56. export function formatDatetime(date: Date | number): string {
  57. if (!dateFormat) {
  58. // TODO: replace `hour12` with `Intl.Locale.prototype.getHourCycles` once there is broad browser support
  59. dateFormat = new Intl.DateTimeFormat(getCurrentLocale(), {
  60. day: 'numeric',
  61. month: 'short',
  62. year: 'numeric',
  63. hour: 'numeric',
  64. hour12: !Number.isInteger(Number(new Intl.DateTimeFormat([], {hour: 'numeric'}).format())),
  65. minute: '2-digit',
  66. timeZoneName: 'short',
  67. });
  68. }
  69. return dateFormat.format(date);
  70. }