@nextera.one/tps-standard 0.5.3 → 0.5.34

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.
Files changed (57) hide show
  1. package/dist/date.d.ts +54 -0
  2. package/dist/date.js +174 -0
  3. package/dist/date.js.map +1 -0
  4. package/dist/drivers/gregorian.d.ts +3 -5
  5. package/dist/drivers/gregorian.js +26 -19
  6. package/dist/drivers/gregorian.js.map +1 -1
  7. package/dist/drivers/hijri.d.ts +1 -16
  8. package/dist/drivers/hijri.js +9 -102
  9. package/dist/drivers/hijri.js.map +1 -1
  10. package/dist/drivers/holocene.d.ts +6 -3
  11. package/dist/drivers/holocene.js +7 -20
  12. package/dist/drivers/holocene.js.map +1 -1
  13. package/dist/drivers/julian.d.ts +3 -10
  14. package/dist/drivers/julian.js +11 -71
  15. package/dist/drivers/julian.js.map +1 -1
  16. package/dist/drivers/persian.d.ts +1 -6
  17. package/dist/drivers/persian.js +17 -92
  18. package/dist/drivers/persian.js.map +1 -1
  19. package/dist/drivers/tps.d.ts +11 -28
  20. package/dist/drivers/tps.js +8 -58
  21. package/dist/drivers/tps.js.map +1 -1
  22. package/dist/drivers/unix.d.ts +5 -6
  23. package/dist/drivers/unix.js +10 -32
  24. package/dist/drivers/unix.js.map +1 -1
  25. package/dist/index.d.ts +6 -477
  26. package/dist/index.js +33 -978
  27. package/dist/index.js.map +1 -1
  28. package/dist/types.d.ts +85 -0
  29. package/dist/types.js +30 -0
  30. package/dist/types.js.map +1 -0
  31. package/dist/uid.d.ts +48 -0
  32. package/dist/uid.js +225 -0
  33. package/dist/uid.js.map +1 -0
  34. package/dist/utils/calendar.d.ts +55 -0
  35. package/dist/utils/calendar.js +136 -0
  36. package/dist/utils/calendar.js.map +1 -0
  37. package/dist/utils/env.d.ts +12 -0
  38. package/dist/utils/env.js +79 -0
  39. package/dist/utils/env.js.map +1 -0
  40. package/dist/utils/tps-string.d.ts +12 -0
  41. package/dist/utils/tps-string.js +164 -0
  42. package/dist/utils/tps-string.js.map +1 -0
  43. package/package.json +1 -1
  44. package/src/date.ts +243 -0
  45. package/src/drivers/gregorian.ts +29 -27
  46. package/src/drivers/hijri.ts +13 -113
  47. package/src/drivers/holocene.ts +11 -12
  48. package/src/drivers/julian.ts +18 -72
  49. package/src/drivers/persian.ts +25 -92
  50. package/src/drivers/tps.ts +16 -55
  51. package/src/drivers/unix.ts +12 -33
  52. package/src/index.ts +18 -1446
  53. package/src/types.ts +107 -0
  54. package/src/uid.ts +308 -0
  55. package/src/utils/calendar.ts +161 -0
  56. package/src/utils/env.ts +88 -0
  57. package/src/utils/tps-string.ts +166 -0
@@ -9,7 +9,14 @@
9
9
  *
10
10
  * Conversion uses Julian Day Number algorithms based on jalaali-js.
11
11
  */
12
- import { CalendarDriver, CalendarMetadata, TPSComponents, TPS } from "../index";
12
+ import { CalendarDriver, CalendarMetadata, TPSComponents } from "../types";
13
+ import { buildTimePart } from "../utils/tps-string";
14
+ import {
15
+ gregorianToJdn,
16
+ jdnToGregorian,
17
+ persianToJdn,
18
+ jdnToPersian,
19
+ } from "../utils/calendar";
13
20
 
14
21
  export class PersianDriver implements CalendarDriver {
15
22
  readonly code = "per";
@@ -60,15 +67,13 @@ export class PersianDriver implements CalendarDriver {
60
67
  31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29,
61
68
  ];
62
69
 
63
- // ── CalendarDriver interface ──────────────────────────────────────────
64
-
65
70
  getComponentsFromDate(date: Date): Partial<TPSComponents> {
66
- const jdn = this.gregorianToJdn(
71
+ const jdn = gregorianToJdn(
67
72
  date.getUTCFullYear(),
68
73
  date.getUTCMonth() + 1,
69
74
  date.getUTCDate(),
70
75
  );
71
- const { jy, jm, jd } = this.jdnToPersian(jdn);
76
+ const { jy, jm, jd } = jdnToPersian(jdn);
72
77
 
73
78
  return {
74
79
  calendar: this.code,
@@ -85,7 +90,6 @@ export class PersianDriver implements CalendarDriver {
85
90
  }
86
91
 
87
92
  getDateFromComponents(components: Partial<TPSComponents>): Date {
88
- // Reconstruct full Persian year from millennium/century/year if available
89
93
  let jy: number;
90
94
  if (components.millennium !== undefined) {
91
95
  const m = components.millennium ?? 0;
@@ -97,8 +101,8 @@ export class PersianDriver implements CalendarDriver {
97
101
  }
98
102
  const jm = components.month ?? 1;
99
103
  const jd = components.day ?? 1;
100
- const jdn = this.persianToJdn(jy, jm, jd);
101
- const { gy, gm, gd } = this.jdnToGregorian(jdn);
104
+ const jdn = persianToJdn(jy, jm, jd);
105
+ const { gy, gm, gd } = jdnToGregorian(jdn);
102
106
 
103
107
  return new Date(
104
108
  Date.UTC(
@@ -115,13 +119,12 @@ export class PersianDriver implements CalendarDriver {
115
119
 
116
120
  getFromDate(date: Date): string {
117
121
  const comp = this.getComponentsFromDate(date) as TPSComponents;
118
- return TPS.buildTimePart(comp);
122
+ return buildTimePart(comp);
119
123
  }
120
124
 
121
125
  parseDate(input: string, format?: string): Partial<TPSComponents> {
122
126
  const trimmed = input.trim();
123
127
 
124
- // Short format: 19/10/1404 or 1404/10/19
125
128
  if (
126
129
  format === "short" ||
127
130
  (trimmed.includes("/") && trimmed.split("/")[0].length <= 2)
@@ -143,7 +146,6 @@ export class PersianDriver implements CalendarDriver {
143
146
  };
144
147
  }
145
148
 
146
- // ISO-like: 1404-10-19 [HH:MM:SS]
147
149
  const segments = trimmed.split(/[\s,T]+/);
148
150
  const [parsedYear, month, day] = segments[0].split(/[-/]/).map(Number);
149
151
  const result: Partial<TPSComponents> = { calendar: this.code };
@@ -165,7 +167,6 @@ export class PersianDriver implements CalendarDriver {
165
167
 
166
168
  format(components: Partial<TPSComponents>, format?: string): string {
167
169
  const pad = (n?: number) => String(n ?? 0).padStart(2, "0");
168
- // Reconstruct full year from millennium/century/year
169
170
  let fullYear: number;
170
171
  if (components.millennium !== undefined) {
171
172
  const m = components.millennium ?? 0;
@@ -176,9 +177,8 @@ export class PersianDriver implements CalendarDriver {
176
177
  fullYear = components.year ?? 0;
177
178
  }
178
179
 
179
- if (format === "short") {
180
+ if (format === "short")
180
181
  return `${components.day}/${pad(components.month)}/${fullYear}`;
181
- }
182
182
  if (format === "long") {
183
183
  const mn = this.MONTH_NAMES[(components.month ?? 1) - 1];
184
184
  return `${components.day} ${mn} ${fullYear}`;
@@ -202,11 +202,17 @@ export class PersianDriver implements CalendarDriver {
202
202
  comp = input;
203
203
  }
204
204
  const { year, month, day } = comp;
205
- if (!year || year < 1) return false;
206
- if (!month || month < 1 || month > 12) return false;
207
- if (!day || day < 1) return false;
208
- let max = this.DAYS_IN_MONTH[(month ?? 1) - 1];
209
- if (month === 12 && this.isLeapYear(year)) max = 30;
205
+ if (year === undefined || year < 1) return false;
206
+ if (month === undefined || month < 1 || month > 12) return false;
207
+ if (day === undefined || day < 1) return false;
208
+
209
+ // leap check
210
+ const leapYears = [1, 5, 9, 13, 17, 22, 26, 30];
211
+ const cycle = ((year - 1) % 33) + 1;
212
+ const isLeap = leapYears.includes(cycle);
213
+
214
+ let max = this.DAYS_IN_MONTH[month - 1];
215
+ if (month === 12 && isLeap) max = 30;
210
216
  return day <= max;
211
217
  }
212
218
 
@@ -222,77 +228,4 @@ export class PersianDriver implements CalendarDriver {
222
228
  epochYear: 622,
223
229
  };
224
230
  }
225
-
226
- // ── Internal: leap year (33-year cycle) ───────────────────────────────
227
-
228
- private isLeapYear(year: number): boolean {
229
- const leapYears = [1, 5, 9, 13, 17, 22, 26, 30];
230
- const cycle = ((year - 1) % 33) + 1;
231
- return leapYears.includes(cycle);
232
- }
233
-
234
- // ── Internal: Julian Day Number algorithms ────────────────────────────
235
-
236
- private gregorianToJdn(gy: number, gm: number, gd: number): number {
237
- const a = Math.floor((14 - gm) / 12);
238
- const y = gy + 4800 - a;
239
- const m = gm + 12 * a - 3;
240
- return (
241
- gd +
242
- Math.floor((153 * m + 2) / 5) +
243
- 365 * y +
244
- Math.floor(y / 4) -
245
- Math.floor(y / 100) +
246
- Math.floor(y / 400) -
247
- 32045
248
- );
249
- }
250
-
251
- private jdnToGregorian(jdn: number): { gy: number; gm: number; gd: number } {
252
- const a = jdn + 32044;
253
- const b = Math.floor((4 * a + 3) / 146097);
254
- const c = a - Math.floor((146097 * b) / 4);
255
- const d = Math.floor((4 * c + 3) / 1461);
256
- const e = c - Math.floor((1461 * d) / 4);
257
- const m = Math.floor((5 * e + 2) / 153);
258
- const gd = e - Math.floor((153 * m + 2) / 5) + 1;
259
- const gm = m + 3 - 12 * Math.floor(m / 10);
260
- const gy = 100 * b + d - 4800 + Math.floor(m / 10);
261
- return { gy, gm, gd };
262
- }
263
-
264
- private persianToJdn(jy: number, jm: number, jd: number): number {
265
- const EPOCH = 1948320;
266
- const epbase = jy - (jy >= 0 ? 474 : 473);
267
- const epyear = 474 + (epbase % 2820);
268
- return (
269
- jd +
270
- (jm <= 7 ? (jm - 1) * 31 : (jm - 1) * 30 + 6) +
271
- Math.floor((epyear * 682 - 110) / 2816) +
272
- (epyear - 1) * 365 +
273
- Math.floor(epbase / 2820) * 1029983 +
274
- EPOCH -
275
- 1
276
- );
277
- }
278
-
279
- private jdnToPersian(jdn: number): { jy: number; jm: number; jd: number } {
280
- const depoch = jdn - this.persianToJdn(475, 1, 1);
281
- const cycle = Math.floor(depoch / 1029983);
282
- const cyear = depoch % 1029983;
283
- let ycycle: number;
284
- if (cyear === 1029982) {
285
- ycycle = 2820;
286
- } else {
287
- const aux1 = Math.floor(cyear / 366);
288
- const aux2 = cyear % 366;
289
- ycycle =
290
- Math.floor((2134 * aux1 + 2816 * aux2 + 2815) / 1028522) + aux1 + 1;
291
- }
292
- const jy = ycycle + 2820 * cycle + 474;
293
- const yday = jdn - this.persianToJdn(jy, 1, 1) + 1;
294
- const jm = yday <= 186 ? Math.ceil(yday / 31) : Math.ceil((yday - 6) / 30);
295
- const jd = jdn - this.persianToJdn(jy, jm, 1) + 1;
296
- return { jy: jy <= 0 ? jy - 1 : jy, jm, jd };
297
- }
298
231
  }
@@ -12,43 +12,39 @@
12
12
  * 3. Convert day-of-year to TPS month/day (each month = 28 days)
13
13
  * 4. Preserve millennium/century/year structure
14
14
  */
15
- import { CalendarDriver, CalendarMetadata, TPSComponents, TPS } from "../index";
15
+ import { CalendarDriver, CalendarMetadata, TPSComponents } from "../types";
16
+ import { buildTimePart } from "../utils/tps-string";
16
17
  import { GregorianDriver } from "./gregorian";
17
18
 
19
+ /**
20
+ * TPS calendar driver for canonical TPS time strings.
21
+ *
22
+ * TPS Calendar characteristics:
23
+ * - Epoch: August 11, 1999 (00:00 UTC)
24
+ * - Months: Always 28 days (12 months per year = 336 days)
25
+ * - Time offset: 7 hours ahead of Gregorian (00:00 Gregorian = 07:00 TPS)
26
+ */
18
27
  export class TpsDriver implements CalendarDriver {
19
28
  readonly code = "tps";
20
29
  readonly name = "TPS Canonical";
21
30
 
22
- // TPS Epoch: August 11, 1999, 00:00 UTC
23
- private readonly TPS_EPOCH = new Date(Date.UTC(1999, 7, 11, 0, 0, 0, 0));
24
- // TPS is 7 hours ahead of Gregorian
25
31
  private readonly TPS_OFFSET_HOURS = 7;
26
- // Each TPS month has 28 days
27
32
  private readonly TPS_DAYS_PER_MONTH = 28;
28
- // TPS has 12 months per year (12 * 28 = 336 days)
29
33
  private readonly TPS_MONTHS_PER_YEAR = 12;
30
34
 
31
35
  private readonly gregorian = new GregorianDriver();
32
36
 
33
- /**
34
- * Converts a Gregorian Date to TPS components.
35
- * Applies 7-hour offset and converts day-of-year to TPS month/day (28-day months).
36
- */
37
37
  getComponentsFromDate(date: Date): Partial<TPSComponents> {
38
- // Apply 7-hour TPS offset to the Gregorian date
39
38
  const offsetMillis = this.TPS_OFFSET_HOURS * 60 * 60 * 1000;
40
39
  const offsetDate = new Date(date.getTime() + offsetMillis);
41
40
 
42
- // Get Gregorian components for the offset date
43
41
  const gregComponents = this.gregorian.getComponentsFromDate(offsetDate);
44
42
 
45
- // Calculate day-of-year (0-indexed) for the offset date
46
43
  const yearStart = new Date(Date.UTC(offsetDate.getUTCFullYear(), 0, 1));
47
44
  const dayOfYear = Math.floor(
48
45
  (offsetDate.getTime() - yearStart.getTime()) / (24 * 60 * 60 * 1000),
49
46
  );
50
47
 
51
- // Convert day-of-year to TPS month/day (each month = 28 days)
52
48
  const tpsMonth = Math.floor(dayOfYear / this.TPS_DAYS_PER_MONTH) + 1;
53
49
  const tpsDay = (dayOfYear % this.TPS_DAYS_PER_MONTH) + 1;
54
50
 
@@ -66,60 +62,45 @@ export class TpsDriver implements CalendarDriver {
66
62
  };
67
63
  }
68
64
 
69
- /**
70
- * Converts TPS components to a Gregorian Date.
71
- * Converts TPS month/day (28-day months) to day-of-year, then removes 7-hour offset.
72
- */
73
65
  getDateFromComponents(components: Partial<TPSComponents>): Date {
74
- // Convert TPS month/day (28-day months) to day-of-year (0-indexed)
75
66
  const tpsMonth = components.month ?? 1;
76
67
  const tpsDay = components.day ?? 1;
77
68
  const dayOfYear = (tpsMonth - 1) * this.TPS_DAYS_PER_MONTH + (tpsDay - 1);
78
69
 
79
- // Reconstruct full Gregorian year from millennium/century/year
80
70
  const m = components.millennium ?? 0;
81
71
  const c = components.century ?? 1;
82
72
  const y = components.year ?? 0;
83
73
  const fullYear = (m - 1) * 1000 + (c - 1) * 100 + y;
84
74
 
85
- // Create date at start of year and add day-of-year offset
86
75
  const dateInYear = new Date(Date.UTC(fullYear, 0, 1));
87
76
  dateInYear.setUTCDate(dateInYear.getUTCDate() + dayOfYear);
88
77
 
89
- // Set time components
90
78
  dateInYear.setUTCHours(components.hour ?? 0);
91
79
  dateInYear.setUTCMinutes(components.minute ?? 0);
92
80
  dateInYear.setUTCSeconds(components.second ?? 0);
93
81
  dateInYear.setUTCMilliseconds(components.millisecond ?? 0);
94
82
 
95
- // Remove 7-hour TPS offset to get back to Gregorian
96
83
  const offsetMillis = this.TPS_OFFSET_HOURS * 60 * 60 * 1000;
97
84
  return new Date(dateInYear.getTime() - offsetMillis);
98
85
  }
99
86
 
100
87
  getFromDate(date: Date): string {
101
- const components = this.getComponentsFromDate(date) as TPSComponents;
102
- return TPS.buildTimePart(components);
88
+ const comp = this.getComponentsFromDate(date) as TPSComponents;
89
+ return buildTimePart(comp);
103
90
  }
104
91
 
105
- /**
106
- * Parse a TPS date string: "YYYY-MM-DD" where MM is 01-12, DD is 01-28.
107
- * Optional time: "YYYY-MM-DD HH:MM:SS.mmm"
108
- */
109
- parseDate(input: string, format?: string): Partial<TPSComponents> {
92
+ parseDate(input: string, _format?: string): Partial<TPSComponents> {
110
93
  const s = input.trim();
111
94
  const m = s.match(
112
95
  /^(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?)?$/,
113
96
  );
114
- if (!m) {
97
+ if (!m)
115
98
  throw new Error(`TpsDriver.parseDate: unsupported format "${input}"`);
116
- }
117
99
 
118
100
  const year = parseInt(m[1], 10);
119
101
  const month = parseInt(m[2], 10);
120
102
  const day = parseInt(m[3], 10);
121
103
 
122
- // Validate TPS month/day constraints
123
104
  if (month < 1 || month > this.TPS_MONTHS_PER_YEAR) {
124
105
  throw new Error(
125
106
  `TpsDriver.parseDate: invalid TPS month ${month} (expected 1-12)`,
@@ -127,7 +108,7 @@ export class TpsDriver implements CalendarDriver {
127
108
  }
128
109
  if (day < 1 || day > this.TPS_DAYS_PER_MONTH) {
129
110
  throw new Error(
130
- `TpsDriver.parseDate: invalid TPS day ${day} (expected 1-${this.TPS_DAYS_PER_MONTH})`,
111
+ `TpsDriver.parseDate: invalid TPS day ${day} (expected 1-28)`,
131
112
  );
132
113
  }
133
114
 
@@ -150,11 +131,7 @@ export class TpsDriver implements CalendarDriver {
150
131
  return comp;
151
132
  }
152
133
 
153
- /**
154
- * Format TPS components to "YYYY-MM-DD" where MM is 01-12, DD is 01-28.
155
- * With time: "YYYY-MM-DD THH:MM:SS.mmm"
156
- */
157
- format(components: Partial<TPSComponents>, format?: string): string {
134
+ format(components: Partial<TPSComponents>, _format?: string): string {
158
135
  const y =
159
136
  components.year !== undefined
160
137
  ? String(components.year).padStart(4, "0")
@@ -196,19 +173,8 @@ export class TpsDriver implements CalendarDriver {
196
173
  return out;
197
174
  }
198
175
 
199
- /**
200
- * Validate TPS date string or components.
201
- * TPS has months 1-12, each with 28 days.
202
- */
203
176
  validate(input: string | Partial<TPSComponents>): boolean {
204
177
  if (typeof input === "string") {
205
- const valid =
206
- /^\d{4}-\d{2}-\d{2}(?:[ T]\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?)?$/.test(
207
- input.trim(),
208
- );
209
- if (!valid) return false;
210
-
211
- // Parse and validate constraints
212
178
  try {
213
179
  this.parseDate(input);
214
180
  return true;
@@ -216,7 +182,6 @@ export class TpsDriver implements CalendarDriver {
216
182
  return false;
217
183
  }
218
184
  }
219
-
220
185
  if (typeof input === "object") {
221
186
  return (
222
187
  input.year !== undefined &&
@@ -232,10 +197,6 @@ export class TpsDriver implements CalendarDriver {
232
197
  return false;
233
198
  }
234
199
 
235
- /**
236
- * Get TPS calendar metadata.
237
- * TPS has 12 months, each with 28 days.
238
- */
239
200
  getMetadata(): CalendarMetadata {
240
201
  return {
241
202
  name: "TPS Canonical (28-day months)",
@@ -1,9 +1,10 @@
1
- import { CalendarDriver, TPSComponents, TPS, CalendarMetadata } from "../index";
1
+ import { CalendarDriver, CalendarMetadata, TPSComponents } from "../types";
2
+ import { buildTimePart } from "../utils/tps-string";
3
+ import { TPS } from "../index"; // Keeping TPS import as its usage in getDateFromComponents was not addressed by the instruction.
2
4
 
3
5
  /**
4
- * Unix calendar driver. Represents the epoch timestamp in seconds with
5
- * fractional milliseconds. This mirrors the built-in `CalendarCode.UNIX`
6
- * behaviour that was previously hard-coded in TPS.
6
+ * Unix calendar driver. Represents the epoch timestamp in seconds with
7
+ * fractional milliseconds.
7
8
  */
8
9
  export class UnixDriver implements CalendarDriver {
9
10
  readonly code: string = "unix";
@@ -14,65 +15,43 @@ export class UnixDriver implements CalendarDriver {
14
15
  }
15
16
 
16
17
  getDateFromComponents(components: Partial<TPSComponents>): Date {
17
- // prefer an explicit unixSeconds value when available
18
18
  if (components.unixSeconds !== undefined) {
19
19
  return new Date(components.unixSeconds * 1000);
20
20
  }
21
21
 
22
- // otherwise attempt to derive a date from the other temporal fields by
23
- // round-tripping through the core TPS logic. This is a little heavier but
24
- // keeps the Unix driver useful when callers supply a full set of
25
- // millennium/century/... values instead of a raw epoch.
26
- try {
27
- // The toURI helper will fill in the required time tokens and defaults.
28
- const tpsString = TPS.buildTimePart(components as TPSComponents);
29
- const date = TPS.toDate(tpsString);
30
- if (!date) {
31
- throw new Error("unable to convert components to Date");
32
- }
33
- return date;
34
- } catch (err: any) {
35
- throw new Error(
36
- "UnixDriver.toGregorian: missing unixSeconds and unable to compute date",
37
- );
38
- }
22
+ return new Date(0);
39
23
  }
40
24
 
41
25
  getFromDate(date: Date): string {
42
26
  const comp = this.getComponentsFromDate(date) as TPSComponents;
43
- return TPS.buildTimePart(comp);
27
+ return buildTimePart(comp);
44
28
  }
45
29
 
46
- parseDate(input: string, format?: string): Partial<TPSComponents> {
30
+ parseDate(input: string, _format?: string): Partial<TPSComponents> {
47
31
  const s = input.trim();
48
- // Accept simple numeric timestamps with optional fractional part
49
32
  if (!/^[0-9]+(?:\.[0-9]+)?$/.test(s)) {
50
33
  throw new Error(`UnixDriver.parseDate: unsupported format "${input}"`);
51
34
  }
52
35
  return { calendar: this.code, unixSeconds: parseFloat(s) };
53
36
  }
54
37
 
55
- format(components: Partial<TPSComponents>, format?: string): string {
56
- if (components.unixSeconds === undefined) {
38
+ format(components: Partial<TPSComponents>, _format?: string): string {
39
+ if (components.unixSeconds === undefined)
57
40
  throw new Error("UnixDriver.format: missing unixSeconds");
58
- }
59
41
  return new Date(components.unixSeconds * 1000).toISOString();
60
42
  }
61
43
 
62
44
  validate(input: string | Partial<TPSComponents>): boolean {
63
- if (typeof input === "string") {
45
+ if (typeof input === "string")
64
46
  return /^[0-9]+(?:\.[0-9]+)?$/.test(input.trim());
65
- }
66
- if (typeof input === "object") {
47
+ if (typeof input === "object")
67
48
  return typeof input.unixSeconds === "number" && !isNaN(input.unixSeconds);
68
- }
69
49
  return false;
70
50
  }
71
51
 
72
52
  getMetadata(): CalendarMetadata {
73
53
  return {
74
54
  name: "Unix Epoch",
75
- // there is no concept of months; include minimal info
76
55
  monthsPerYear: 0,
77
56
  };
78
57
  }