|
1 | | -import type { TimestampFormatOption } from "@/tools/unix-timestamp/lib/constants" |
| 1 | +import type { TimestampFormatOption } from "@/tools/unix-timestamp/lib/constants"; |
2 | 2 |
|
3 | 3 | export interface TimestampResult { |
4 | | - gmt: string |
5 | | - local: string |
6 | | - isValid: boolean |
| 4 | + gmt: string; |
| 5 | + local: string; |
| 6 | + prettyDate: string; |
| 7 | + prettyTime: string; |
| 8 | + isValid: boolean; |
7 | 9 | } |
8 | 10 |
|
9 | 11 | function toDate(input: string) { |
10 | | - const trimmed = input.trim() |
11 | | - if (!trimmed) return null |
12 | | - const numeric = Number(trimmed) |
13 | | - if (!Number.isFinite(numeric)) return null |
14 | | - const isSeconds = trimmed.length <= 10 |
15 | | - const millis = isSeconds ? numeric * 1000 : numeric |
16 | | - const date = new Date(millis) |
17 | | - if (Number.isNaN(date.getTime())) return null |
18 | | - return date |
| 12 | + const trimmed = input.trim(); |
| 13 | + if (!trimmed) return null; |
| 14 | + const numeric = Number(trimmed); |
| 15 | + if (!Number.isFinite(numeric)) return null; |
| 16 | + const isSeconds = trimmed.length <= 10; |
| 17 | + const millis = isSeconds ? numeric * 1000 : numeric; |
| 18 | + const date = new Date(millis); |
| 19 | + if (Number.isNaN(date.getTime())) return null; |
| 20 | + return date; |
| 21 | +} |
| 22 | + |
| 23 | +export interface PrettyDateParts { |
| 24 | + dateLabel: string; |
| 25 | + timeLabel: string; |
| 26 | +} |
| 27 | + |
| 28 | +export function formatPrettyDateParts(date: Date): PrettyDateParts { |
| 29 | + const dateLabel = date.toLocaleDateString("en-US", { |
| 30 | + weekday: "short", |
| 31 | + month: "short", |
| 32 | + day: "2-digit", |
| 33 | + year: "numeric", |
| 34 | + }); |
| 35 | + const timeLabel = date.toLocaleTimeString("en-US", { |
| 36 | + hour: "2-digit", |
| 37 | + minute: "2-digit", |
| 38 | + }); |
| 39 | + return { dateLabel, timeLabel }; |
19 | 40 | } |
20 | 41 |
|
21 | 42 | function formatGmt(date: Date, format: TimestampFormatOption["id"]) { |
22 | | - if (format === "iso") return date.toISOString() |
| 43 | + if (format === "iso") return date.toISOString(); |
23 | 44 | if (format === "locale") { |
24 | | - return date.toLocaleString("en-US", { timeZone: "UTC" }) |
| 45 | + return date.toLocaleString("en-US", { timeZone: "UTC" }); |
25 | 46 | } |
26 | | - return date.toUTCString() |
| 47 | + return date.toUTCString(); |
27 | 48 | } |
28 | 49 |
|
29 | 50 | function formatLocal(date: Date, format: TimestampFormatOption["id"]) { |
30 | 51 | if (format === "iso") { |
31 | | - const offsetMinutes = date.getTimezoneOffset() |
32 | | - const localDate = new Date(date.getTime() - offsetMinutes * 60000) |
33 | | - const iso = localDate.toISOString().replace("Z", "") |
34 | | - const sign = offsetMinutes <= 0 ? "+" : "-" |
35 | | - const abs = Math.abs(offsetMinutes) |
36 | | - const hours = String(Math.floor(abs / 60)).padStart(2, "0") |
37 | | - const minutes = String(abs % 60).padStart(2, "0") |
38 | | - return `${iso}${sign}${hours}${minutes}` |
| 52 | + const offsetMinutes = date.getTimezoneOffset(); |
| 53 | + const localDate = new Date(date.getTime() - offsetMinutes * 60000); |
| 54 | + const iso = localDate.toISOString().replace("Z", ""); |
| 55 | + const sign = offsetMinutes <= 0 ? "+" : "-"; |
| 56 | + const abs = Math.abs(offsetMinutes); |
| 57 | + const hours = String(Math.floor(abs / 60)).padStart(2, "0"); |
| 58 | + const minutes = String(abs % 60).padStart(2, "0"); |
| 59 | + return `${iso}${sign}${hours}${minutes}`; |
39 | 60 | } |
40 | | - if (format === "locale") return date.toLocaleString() |
41 | | - return date.toString() |
| 61 | + if (format === "locale") return date.toLocaleString(); |
| 62 | + return date.toString(); |
42 | 63 | } |
43 | 64 |
|
44 | 65 | export function formatTimestamp( |
45 | 66 | input: string, |
46 | 67 | format: TimestampFormatOption["id"] |
47 | 68 | ): TimestampResult { |
48 | | - const date = toDate(input) |
| 69 | + const date = toDate(input); |
49 | 70 | if (!date) { |
50 | | - return { gmt: "", local: "", isValid: false } |
| 71 | + return { |
| 72 | + gmt: "invalid", |
| 73 | + local: "invalid", |
| 74 | + prettyDate: "invalid", |
| 75 | + prettyTime: "", |
| 76 | + isValid: false, |
| 77 | + }; |
51 | 78 | } |
| 79 | + const pretty = formatPrettyDateParts(date); |
52 | 80 |
|
53 | 81 | return { |
54 | 82 | gmt: formatGmt(date, format), |
55 | 83 | local: formatLocal(date, format), |
| 84 | + prettyDate: pretty.dateLabel, |
| 85 | + prettyTime: pretty.timeLabel, |
56 | 86 | isValid: true, |
57 | | - } |
| 87 | + }; |
58 | 88 | } |
0 commit comments