@prairielearn/formatter 1.3.12 → 1.3.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/date.d.ts +7 -0
- package/dist/date.js +15 -0
- package/dist/date.js.map +1 -1
- package/dist/date.test.js +1 -1
- package/dist/date.test.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interval.test.js +1 -1
- package/dist/interval.test.js.map +1 -1
- package/package.json +6 -18
- package/src/date.test.ts +1 -1
- package/src/date.ts +16 -0
- package/src/index.ts +1 -1
- package/src/interval.test.ts +1 -1
- package/tsconfig.json +1 -1
- package/vitest.config.ts +11 -0
- package/.mocharc.cjs +0 -3
package/CHANGELOG.md
CHANGED
package/dist/date.d.ts
CHANGED
|
@@ -28,3 +28,10 @@ export declare function formatDateYMD(date: Date, timeZone: string): string;
|
|
|
28
28
|
* @returns Human-readable string representing the date.
|
|
29
29
|
*/
|
|
30
30
|
export declare function formatDateYMDHM(date: Date, timeZone: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* Format a time zone to a human-readable string like 'CDT'.
|
|
33
|
+
*
|
|
34
|
+
* @param timeZone The time zone to format.
|
|
35
|
+
* @returns Human-readable string representing the time zone.
|
|
36
|
+
*/
|
|
37
|
+
export declare function formatTz(timeZone: string): string;
|
package/dist/date.js
CHANGED
|
@@ -69,4 +69,19 @@ export function formatDateYMDHM(date, timeZone) {
|
|
|
69
69
|
const parts = keyBy(new Intl.DateTimeFormat('en-US', options).formatToParts(date), (x) => x.type);
|
|
70
70
|
return `${parts.year.value}-${parts.month.value}-${parts.day.value} ${parts.hour.value}:${parts.minute.value}`;
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Format a time zone to a human-readable string like 'CDT'.
|
|
74
|
+
*
|
|
75
|
+
* @param timeZone The time zone to format.
|
|
76
|
+
* @returns Human-readable string representing the time zone.
|
|
77
|
+
*/
|
|
78
|
+
export function formatTz(timeZone) {
|
|
79
|
+
const date = new Date();
|
|
80
|
+
const parts = new Intl.DateTimeFormat('en-US', {
|
|
81
|
+
timeZone,
|
|
82
|
+
timeZoneName: 'short',
|
|
83
|
+
}).formatToParts(date);
|
|
84
|
+
const tz = parts.find((p) => p.type === 'timeZoneName');
|
|
85
|
+
return tz ? tz.value : timeZone;
|
|
86
|
+
}
|
|
72
87
|
//# sourceMappingURL=date.js.map
|
package/dist/date.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date.js","sourceRoot":"","sources":["../src/date.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,iBAAiB,CAAC;AAEpC;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CACxB,IAAU,EACV,QAAgB,EAChB,EACE,SAAS,GAAG,IAAI,EAChB,MAAM,GAAG,KAAK,EACd,SAAS,GAAG,KAAK,MACiD,EAAE;IAEtE,MAAM,OAAO,GAA+B;QAC1C,QAAQ;QACR,SAAS,EAAE,KAAK;QAChB,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;QAChB,GAAG,EAAE,SAAS;QACd,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,SAAS;QACjB,sBAAsB,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;QACjD,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;KACxC,CAAC;IACF,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAClG,IAAI,aAAa,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAClJ,IAAI,SAAS,EAAE,CAAC;QACd,aAAa,GAAG,GAAG,aAAa,IAAI,KAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;IACrE,CAAC;IACD,IAAI,SAAS,EAAE,CAAC;QACd,aAAa,GAAG,GAAG,aAAa,KAAK,KAAK,CAAC,YAAY,CAAC,KAAK,GAAG,CAAC;IACnE,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,IAAU,EAAE,QAAgB;IACxD,MAAM,OAAO,GAA+B;QAC1C,QAAQ;QACR,SAAS,EAAE,KAAK;QAChB,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;QAChB,GAAG,EAAE,SAAS;KACf,CAAC;IACF,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAClG,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;AACvE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAU,EAAE,QAAgB;IAC1D,MAAM,OAAO,GAA+B;QAC1C,QAAQ;QACR,SAAS,EAAE,KAAK;QAChB,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;QAChB,GAAG,EAAE,SAAS;QACd,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,SAAS;KAClB,CAAC;IACF,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAClG,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;AACjH,CAAC","sourcesContent":["import keyBy from 'lodash/keyBy.js';\n\n/**\n * Format a date to a human-readable string like '2020-03-27T12:34:56 (CDT)'.\n *\n * @param date The date to format.\n * @param timeZone The time zone to use for formatting.\n * @param param2.includeTz Whether to include the time zone in the output (default true).\n * @param param2.longTz Whether to use the long time zone name (default false).\n * @returns Human-readable string representing the date.\n */\nexport function formatDate(\n date: Date,\n timeZone: string,\n {\n includeTz = true,\n longTz = false,\n includeMs = false,\n }: { includeTz?: boolean; longTz?: boolean; includeMs?: boolean } = {},\n): string {\n const options: Intl.DateTimeFormatOptions = {\n timeZone,\n hourCycle: 'h23',\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n fractionalSecondDigits: includeMs ? 3 : undefined,\n timeZoneName: longTz ? 'long' : 'short',\n };\n const parts = keyBy(new Intl.DateTimeFormat('en-US', options).formatToParts(date), (x) => x.type);\n let dateFormatted = `${parts.year.value}-${parts.month.value}-${parts.day.value} ${parts.hour.value}:${parts.minute.value}:${parts.second.value}`;\n if (includeMs) {\n dateFormatted = `${dateFormatted}.${parts.fractionalSecond.value}`;\n }\n if (includeTz) {\n dateFormatted = `${dateFormatted} (${parts.timeZoneName.value})`;\n }\n return dateFormatted;\n}\n\n/**\n * Format a date to a human-readable string like '2020-03-27'.\n *\n * @param date The date to format.\n * @param timeZone The time zone to use for formatting.\n * @returns Human-readable string representing the date.\n */\nexport function formatDateYMD(date: Date, timeZone: string): string {\n const options: Intl.DateTimeFormatOptions = {\n timeZone,\n hourCycle: 'h23',\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n };\n const parts = keyBy(new Intl.DateTimeFormat('en-US', options).formatToParts(date), (x) => x.type);\n return `${parts.year.value}-${parts.month.value}-${parts.day.value}`;\n}\n\n/**\n * Format a date to a human-readable string like '2020-03-27 14:27'.\n *\n * @param date The date to format.\n * @param timeZone The time zone to use for formatting.\n * @returns Human-readable string representing the date.\n */\nexport function formatDateYMDHM(date: Date, timeZone: string): string {\n const options: Intl.DateTimeFormatOptions = {\n timeZone,\n hourCycle: 'h23',\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n };\n const parts = keyBy(new Intl.DateTimeFormat('en-US', options).formatToParts(date), (x) => x.type);\n return `${parts.year.value}-${parts.month.value}-${parts.day.value} ${parts.hour.value}:${parts.minute.value}`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"date.js","sourceRoot":"","sources":["../src/date.ts"],"names":[],"mappings":"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","sourcesContent":["import keyBy from 'lodash/keyBy.js';\n\n/**\n * Format a date to a human-readable string like '2020-03-27T12:34:56 (CDT)'.\n *\n * @param date The date to format.\n * @param timeZone The time zone to use for formatting.\n * @param param2.includeTz Whether to include the time zone in the output (default true).\n * @param param2.longTz Whether to use the long time zone name (default false).\n * @returns Human-readable string representing the date.\n */\nexport function formatDate(\n date: Date,\n timeZone: string,\n {\n includeTz = true,\n longTz = false,\n includeMs = false,\n }: { includeTz?: boolean; longTz?: boolean; includeMs?: boolean } = {},\n): string {\n const options: Intl.DateTimeFormatOptions = {\n timeZone,\n hourCycle: 'h23',\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n fractionalSecondDigits: includeMs ? 3 : undefined,\n timeZoneName: longTz ? 'long' : 'short',\n };\n const parts = keyBy(new Intl.DateTimeFormat('en-US', options).formatToParts(date), (x) => x.type);\n let dateFormatted = `${parts.year.value}-${parts.month.value}-${parts.day.value} ${parts.hour.value}:${parts.minute.value}:${parts.second.value}`;\n if (includeMs) {\n dateFormatted = `${dateFormatted}.${parts.fractionalSecond.value}`;\n }\n if (includeTz) {\n dateFormatted = `${dateFormatted} (${parts.timeZoneName.value})`;\n }\n return dateFormatted;\n}\n\n/**\n * Format a date to a human-readable string like '2020-03-27'.\n *\n * @param date The date to format.\n * @param timeZone The time zone to use for formatting.\n * @returns Human-readable string representing the date.\n */\nexport function formatDateYMD(date: Date, timeZone: string): string {\n const options: Intl.DateTimeFormatOptions = {\n timeZone,\n hourCycle: 'h23',\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n };\n const parts = keyBy(new Intl.DateTimeFormat('en-US', options).formatToParts(date), (x) => x.type);\n return `${parts.year.value}-${parts.month.value}-${parts.day.value}`;\n}\n\n/**\n * Format a date to a human-readable string like '2020-03-27 14:27'.\n *\n * @param date The date to format.\n * @param timeZone The time zone to use for formatting.\n * @returns Human-readable string representing the date.\n */\nexport function formatDateYMDHM(date: Date, timeZone: string): string {\n const options: Intl.DateTimeFormatOptions = {\n timeZone,\n hourCycle: 'h23',\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n };\n const parts = keyBy(new Intl.DateTimeFormat('en-US', options).formatToParts(date), (x) => x.type);\n return `${parts.year.value}-${parts.month.value}-${parts.day.value} ${parts.hour.value}:${parts.minute.value}`;\n}\n\n/**\n * Format a time zone to a human-readable string like 'CDT'.\n *\n * @param timeZone The time zone to format.\n * @returns Human-readable string representing the time zone.\n */\nexport function formatTz(timeZone: string): string {\n const date = new Date();\n const parts = new Intl.DateTimeFormat('en-US', {\n timeZone,\n timeZoneName: 'short',\n }).formatToParts(date);\n const tz = parts.find((p) => p.type === 'timeZoneName');\n return tz ? tz.value : timeZone;\n}\n"]}
|
package/dist/date.test.js
CHANGED
package/dist/date.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date.test.js","sourceRoot":"","sources":["../src/date.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"date.test.js","sourceRoot":"","sources":["../src/date.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEvE,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;YAC5B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,2BAA2B,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;YAC5B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,2BAA2B,CAAC,CAAC;QACjF,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;YAC5B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,2BAA2B,CAAC,CAAC;QACjF,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;YACvC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,2BAA2B,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YACzD,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,+BAA+B,CAAC,CAAC;QAC9F,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,qBAAqB,CAAC,CAAC;QACrF,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM,CAAC,KAAK,CACV,UAAU,CAAC,IAAI,EAAE,iBAAiB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EACrD,6CAA6C,CAC9C,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;YAClC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,YAAY,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;YAClC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,YAAY,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;YAClC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,YAAY,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,YAAY,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;YAClC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;YACvD,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,kBAAkB,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;YAClC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;YACvD,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,kBAAkB,CAAC,CAAC;QAC7E,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;YAClC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YACvD,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,kBAAkB,CAAC,CAAC;QAC7E,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,kBAAkB,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { assert, describe, it } from 'vitest';\n\nimport { formatDate, formatDateYMD, formatDateYMDHM } from './date.js';\n\ndescribe('date formatting', () => {\n describe('formatDate', () => {\n it('formats a UTC date', () => {\n const date = new Date(Date.UTC(2018, 0, 1, 12, 0, 0));\n assert.equal(formatDate(date, 'UTC'), '2018-01-01 12:00:00 (UTC)');\n });\n it('formats a CST date', () => {\n const date = new Date(Date.UTC(2018, 0, 1, 12, 0, 0));\n assert.equal(formatDate(date, 'America/Chicago'), '2018-01-01 06:00:00 (CST)');\n });\n it('formats a CDT date', () => {\n const date = new Date(Date.UTC(2018, 6, 1, 12, 0, 0));\n assert.equal(formatDate(date, 'America/Chicago'), '2018-07-01 07:00:00 (CDT)');\n });\n it('formats dates with zero hours', () => {\n const date = new Date(Date.UTC(2018, 0, 1, 0, 1, 0));\n assert.equal(formatDate(date, 'UTC'), '2018-01-01 00:01:00 (UTC)');\n });\n it('formats dates with milliseconds', () => {\n const date = new Date(Date.UTC(2018, 0, 1, 4, 1, 3, 12));\n assert.equal(formatDate(date, 'UTC', { includeMs: true }), '2018-01-01 04:01:03.012 (UTC)');\n });\n it('formats dates without the timezone', () => {\n const date = new Date(Date.UTC(2018, 0, 1, 12, 0, 0));\n assert.equal(formatDate(date, 'UTC', { includeTz: false }), '2018-01-01 12:00:00');\n });\n it('formats dates with the long timezone name', () => {\n const date = new Date(Date.UTC(2018, 0, 1, 12, 0, 0));\n assert.equal(\n formatDate(date, 'America/Chicago', { longTz: true }),\n '2018-01-01 06:00:00 (Central Standard Time)',\n );\n });\n });\n\n describe('formatDateYMD()', () => {\n it('should handle a UTC date', () => {\n const date = new Date(Date.UTC(2018, 0, 1, 12, 0, 0));\n assert.equal(formatDateYMD(date, 'UTC'), '2018-01-01');\n });\n it('should handle a CST date', () => {\n const date = new Date(Date.UTC(2018, 0, 3, 5, 0, 0));\n assert.equal(formatDateYMD(date, 'America/Chicago'), '2018-01-02');\n });\n it('should handle a CDT date', () => {\n const date = new Date(Date.UTC(2018, 6, 1, 12, 0, 0));\n assert.equal(formatDateYMD(date, 'America/Chicago'), '2018-07-01');\n });\n it('should correctly format dates with zero hours', () => {\n const date = new Date(Date.UTC(2018, 0, 1, 0, 1, 0));\n assert.equal(formatDateYMD(date, 'UTC'), '2018-01-01');\n });\n });\n\n describe('formatDateYMDHM()', () => {\n it('should handle a UTC date', () => {\n const date = new Date(Date.UTC(2018, 0, 1, 12, 34, 7));\n assert.equal(formatDateYMDHM(date, 'UTC'), '2018-01-01 12:34');\n });\n it('should handle a CST date', () => {\n const date = new Date(Date.UTC(2018, 0, 3, 5, 10, 50));\n assert.equal(formatDateYMDHM(date, 'America/Chicago'), '2018-01-02 23:10');\n });\n it('should handle a CDT date', () => {\n const date = new Date(Date.UTC(2018, 6, 1, 19, 8, 19));\n assert.equal(formatDateYMDHM(date, 'America/Chicago'), '2018-07-01 14:08');\n });\n it('should correctly format dates with zero hours', () => {\n const date = new Date(Date.UTC(2018, 0, 1, 0, 1, 0));\n assert.equal(formatDateYMDHM(date, 'UTC'), '2018-01-01 00:01');\n });\n });\n});\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { formatDate, formatDateYMD, formatDateYMDHM } from './date.js';
|
|
1
|
+
export { formatDate, formatDateYMD, formatDateYMDHM, formatTz } from './date.js';
|
|
2
2
|
export { formatInterval } from './interval.js';
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC","sourcesContent":["export { formatDate, formatDateYMD, formatDateYMDHM, formatTz } from './date.js';\nexport { formatInterval } from './interval.js';\n"]}
|
package/dist/interval.test.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interval.test.js","sourceRoot":"","sources":["../src/interval.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"interval.test.js","sourceRoot":"","sources":["../src/interval.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;YAC/B,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;YAC/B,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;YAC7B,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;YAC7B,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,mBAAmB,CAAC,CAAC;QAC/F,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;YAC5B,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,CAAC,KAAK,CACV,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAC1D,uBAAuB,CACxB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { assert, describe, it } from 'vitest';\n\nimport { formatInterval } from './interval.js';\n\ndescribe('interval formatting', () => {\n describe('formatInterval()', () => {\n it('should handle seconds', () => {\n assert.equal(formatInterval(7000), '7 s');\n });\n it('should handle fractional seconds', () => {\n assert.equal(formatInterval(7321), '7 s');\n });\n it('should handle minutes', () => {\n assert.equal(formatInterval(2 * 60 * 1000), '2 min');\n });\n it('should handle hours', () => {\n assert.equal(formatInterval(3 * 60 * 60 * 1000), '3 h');\n });\n it('should handle hours', () => {\n assert.equal(formatInterval(4 * 24 * 60 * 60 * 1000), '4 d');\n });\n it('should handle complex intervals', () => {\n assert.equal(formatInterval((((4 * 24 + 3) * 60 + 2) * 60 + 7) * 1000), '4 d 3 h 2 min 7 s');\n });\n it('should handle zero', () => {\n assert.equal(formatInterval(0), '0 s');\n });\n it('should handle negative intervals', () => {\n assert.equal(\n formatInterval(-(((4 * 24 + 3) * 60 + 2) * 60 + 7) * 1000),\n '-4 d -3 h -2 min -7 s',\n );\n });\n });\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prairielearn/formatter",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -11,29 +11,17 @@
|
|
|
11
11
|
"scripts": {
|
|
12
12
|
"build": "tsc",
|
|
13
13
|
"dev": "tsc --watch --preserveWatchOutput",
|
|
14
|
-
"test": "
|
|
14
|
+
"test": "vitest run --coverage"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"lodash": "^4.17.21"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@prairielearn/tsconfig": "^0.0.0",
|
|
21
|
-
"@types/node": "^
|
|
22
|
-
"
|
|
23
|
-
"chai": "^5.2.0",
|
|
24
|
-
"mocha": "^11.1.0",
|
|
21
|
+
"@types/node": "^22.15.29",
|
|
22
|
+
"@vitest/coverage-v8": "^3.2.2",
|
|
25
23
|
"tsx": "^4.19.4",
|
|
26
|
-
"typescript": "^5.8.3"
|
|
27
|
-
|
|
28
|
-
"c8": {
|
|
29
|
-
"reporter": [
|
|
30
|
-
"html",
|
|
31
|
-
"text-summary",
|
|
32
|
-
"cobertura"
|
|
33
|
-
],
|
|
34
|
-
"all": true,
|
|
35
|
-
"include": [
|
|
36
|
-
"src/**"
|
|
37
|
-
]
|
|
24
|
+
"typescript": "^5.8.3",
|
|
25
|
+
"vitest": "^3.2.2"
|
|
38
26
|
}
|
|
39
27
|
}
|
package/src/date.test.ts
CHANGED
package/src/date.ts
CHANGED
|
@@ -80,3 +80,19 @@ export function formatDateYMDHM(date: Date, timeZone: string): string {
|
|
|
80
80
|
const parts = keyBy(new Intl.DateTimeFormat('en-US', options).formatToParts(date), (x) => x.type);
|
|
81
81
|
return `${parts.year.value}-${parts.month.value}-${parts.day.value} ${parts.hour.value}:${parts.minute.value}`;
|
|
82
82
|
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Format a time zone to a human-readable string like 'CDT'.
|
|
86
|
+
*
|
|
87
|
+
* @param timeZone The time zone to format.
|
|
88
|
+
* @returns Human-readable string representing the time zone.
|
|
89
|
+
*/
|
|
90
|
+
export function formatTz(timeZone: string): string {
|
|
91
|
+
const date = new Date();
|
|
92
|
+
const parts = new Intl.DateTimeFormat('en-US', {
|
|
93
|
+
timeZone,
|
|
94
|
+
timeZoneName: 'short',
|
|
95
|
+
}).formatToParts(date);
|
|
96
|
+
const tz = parts.find((p) => p.type === 'timeZoneName');
|
|
97
|
+
return tz ? tz.value : timeZone;
|
|
98
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { formatDate, formatDateYMD, formatDateYMDHM } from './date.js';
|
|
1
|
+
export { formatDate, formatDateYMD, formatDateYMDHM, formatTz } from './date.js';
|
|
2
2
|
export { formatInterval } from './interval.js';
|
package/src/interval.test.ts
CHANGED
package/tsconfig.json
CHANGED
package/vitest.config.ts
ADDED
package/.mocharc.cjs
DELETED