-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdateToString.ts
96 lines (90 loc) · 3.04 KB
/
dateToString.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import localeInfo from "../objects/localeInfo";
export function zeroBefore(v: number, length: number): string {
const s = `${v}`;
const rc = length - s.length;
if (rc > 0) {
return "0".repeat(rc) + s;
}
return s;
}
function cutEndString(s: string, length: number): string {
return s.substring(s.length - length);
}
/** Returns a string representation of a date-time according to pointed format
* @param format 'yyyy-MM-dd hh:mm:ss.fff AZ'
* @example
* "yyyy-MM-dd hh:mm:ss.fff Z" => "2022-04-23 16:09:12.234" // point 'Z' at the end for UTCdate
* "yyyy-MM-dd hh:mm:ss a" => "2022-04-23 04:09:12 pm" // point 'a' or 'A' at the end for 12hour format
* "yyyy-MM-dd hh:mm:ss.fff aZ" => "2022-04-23 04:09:12 pm" // point 'Z' at the end for UTCdate
* "yyyy-MM-dd hh:mm:ss" => "2022-04-23 16:09:12"
* "yy-M-d h:m:s" => "22-4-23 13:9:12"
* "dd/MM/yyyy" => "23/04/2022"
* "MMM d, hh:mm A" => "Apr 23, 04:09 PM" (depends on localeInfo.namesMonthShort)
* @tutorial Troubleshooting
* * AM PM in the middle isn't supported (only at the end): use 'hh:mm, d/m/yyyy A' instead 'hh:mm A, d/m/yyyy'
*/
export default function dateToString(v: Date, format: string): string {
if (Number.isNaN(v.valueOf())) {
return "NaN";
}
const isUTC = format.endsWith("Z") || format.endsWith("z");
format = isUTC ? format.substring(0, format.length - 1) : format;
const ukey = isUTC ? "UTC" : "";
let h12 = format.endsWith("a") || format.endsWith("A") ? format[format.length - 1] : "";
format = h12 ? format.substring(0, format.length - 1) : format;
let char = format[0];
let cnt = 1;
let s = "";
for (let i = 1; i <= format.length; ++i) {
const ch = format[i];
if (char !== ch) {
switch (char) {
case "y":
case "Y":
s += cutEndString(zeroBefore(v[`get${ukey}FullYear`].call(v), cnt), cnt);
break;
case "M":
if (cnt === 3) {
s += localeInfo.namesMonthShort[v[`get${ukey}Month`].call(v)].substring(0, 3);
} else {
s += zeroBefore(v[`get${ukey}Month`].call(v) + 1, cnt);
}
break;
case "d":
case "D":
s += zeroBefore(v[`get${ukey}Date`].call(v), cnt);
break;
case "h":
case "H":
{
const hh = v[`get${ukey}Hours`].call(v);
s += zeroBefore(h12 ? hh % 12 || 12 : hh, cnt);
if (h12) {
// eslint-disable-next-line no-nested-ternary
h12 = hh < 12 ? (h12 === "A" ? "AM" : "am") : h12 === "A" ? "PM" : "pm";
}
}
break;
case "m":
s += zeroBefore(v[`get${ukey}Minutes`].call(v), cnt);
break;
case "s":
case "S":
s += zeroBefore(v[`get${ukey}Seconds`].call(v), cnt);
break;
case "f":
case "F":
s += zeroBefore(v[`get${ukey}Milliseconds`].call(v), cnt);
break;
default: {
s += char.repeat(cnt);
}
}
char = ch;
cnt = 1;
} else {
++cnt;
}
}
return s + h12;
}