@gobrand/tiempo 2.3.2 → 2.3.4

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/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![CI](https://github.com/go-brand/tiempo/actions/workflows/ci.yml/badge.svg)](https://github.com/go-brand/tiempo/actions/workflows/ci.yml)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
6
 
7
- Comprehensive datetime utilities for the [Temporal API](https://tc39.es/proposal-temporal/docs/). Full timezone support, nanosecond precision, and 54+ utility functions with a familiar API.
7
+ Comprehensive datetime utilities for the [Temporal API](https://tc39.es/proposal-temporal/docs/). Full timezone support, nanosecond precision, and a familiar API.
8
8
 
9
9
  ## Installation
10
10
 
@@ -18,7 +18,7 @@ yarn add @gobrand/tiempo
18
18
 
19
19
  ## Why tiempo?
20
20
 
21
- The Temporal API is powerful but requires understanding its various methods and objects. **tiempo** (`@gobrand/tiempo`) provides 54+ intuitive utilities for every datetime task:
21
+ The Temporal API is powerful but requires understanding its various methods and objects. **tiempo** (`@gobrand/tiempo`) provides intuitive utilities for every datetime task:
22
22
 
23
23
  - **🌍 Timezone conversions** - Convert between UTC and any timezone effortlessly
24
24
  - **➕ Complete arithmetic** - Add/subtract any time unit from nanoseconds to years
@@ -314,6 +314,95 @@ format(instant, "yyyy-MM-dd HH:mm", { timeZone: "America/New_York" }); // "2025-
314
314
  format(instant, "yyyy-MM-dd HH:mm", { timeZone: "Asia/Tokyo" }); // "2025-01-21 05:30"
315
315
  ```
316
316
 
317
+ #### `formatPlainDate(date, formatStr, options?)`
318
+
319
+ Format a Temporal.PlainDate using date-fns-like format tokens. Only supports date-related tokens (no time or timezone tokens).
320
+
321
+ **Parameters:**
322
+ - `date` (Temporal.PlainDate): A Temporal.PlainDate to format
323
+ - `formatStr` (string): Format string using date-fns tokens (e.g., "yyyy-MM-dd")
324
+ - `options` (FormatPlainDateOptions, optional): Configuration for locale
325
+ - `locale` (string): BCP 47 language tag (default: "en-US")
326
+
327
+ **Returns:** `string` - Formatted date string
328
+
329
+ **Supported tokens:**
330
+ - **Year**: `yyyy` (2025), `yy` (25), `y` (2025)
331
+ - **Month**: `MMMM` (January), `MMM` (Jan), `MM` (01), `M` (1), `Mo` (1st)
332
+ - **Day**: `dd` (20), `d` (20), `do` (20th)
333
+ - **Weekday**: `EEEE` (Monday), `EEE` (Mon), `EEEEE` (M)
334
+ - **Quarter**: `Q` (1), `QQQ` (Q1), `QQQQ` (1st quarter)
335
+ - **Era**: `G` (AD), `GGGG` (Anno Domini)
336
+ - **Escape text**: Use single quotes `'...'`, double single quotes `''` for literal quote
337
+
338
+ **Example:**
339
+ ```typescript
340
+ import { formatPlainDate, today } from '@gobrand/tiempo';
341
+
342
+ const date = Temporal.PlainDate.from("2025-01-20");
343
+
344
+ formatPlainDate(date, "yyyy-MM-dd"); // "2025-01-20"
345
+ formatPlainDate(date, "MMMM d, yyyy"); // "January 20, 2025"
346
+ formatPlainDate(date, "EEEE, MMMM do, yyyy"); // "Monday, January 20th, 2025"
347
+ formatPlainDate(date, "MM/dd/yyyy"); // "01/20/2025"
348
+
349
+ // With locale
350
+ formatPlainDate(date, "MMMM d, yyyy", { locale: "es-ES" }); // "enero 20, 2025"
351
+ formatPlainDate(date, "EEEE", { locale: "de-DE" }); // "Montag"
352
+
353
+ // Use with today()
354
+ const todayFormatted = formatPlainDate(today(), "EEEE, MMMM do");
355
+ // "Thursday, January 23rd"
356
+ ```
357
+
358
+ #### `simpleFormat(input, options?)`
359
+
360
+ Format a Temporal date in a human-friendly way: "Dec 23" or "Dec 23, 2020". By default, shows the year only if the date is not in the current year. Optionally includes time in 12-hour or 24-hour format.
361
+
362
+ **Parameters:**
363
+ - `input` (Temporal.PlainDate | Temporal.ZonedDateTime | Temporal.Instant): The date to format
364
+ - `options` (object, optional): Formatting options
365
+ - `locale` (string): BCP 47 language tag (default: "en-US")
366
+ - `year` ('auto' | 'always' | 'never'): Control year display (default: 'auto')
367
+ - `time` ('12h' | '24h'): Include time in output (not available for PlainDate)
368
+ - `timeZone` (string): IANA timezone identifier (required for Instant, optional for ZonedDateTime)
369
+
370
+ **Returns:** `string` - Human-friendly formatted date string
371
+
372
+ **Example:**
373
+ ```typescript
374
+ import { simpleFormat, today, now } from '@gobrand/tiempo';
375
+
376
+ // Assuming current year is 2026
377
+ const date2026 = Temporal.ZonedDateTime.from("2026-12-23T15:30:00[America/New_York]");
378
+ const date2020 = Temporal.ZonedDateTime.from("2020-12-23T15:30:00[America/New_York]");
379
+
380
+ // Basic usage - year shown only for past years
381
+ simpleFormat(date2026); // "Dec 23"
382
+ simpleFormat(date2020); // "Dec 23, 2020"
383
+
384
+ // With time
385
+ simpleFormat(date2026, { time: '12h' }); // "Dec 23, 3:30 PM"
386
+ simpleFormat(date2026, { time: '24h' }); // "Dec 23, 15:30"
387
+
388
+ // Control year display
389
+ simpleFormat(date2026, { year: 'always' }); // "Dec 23, 2026"
390
+ simpleFormat(date2020, { year: 'never' }); // "Dec 23"
391
+
392
+ // With Instant (timeZone required)
393
+ const instant = Temporal.Instant.from("2026-12-23T20:30:00Z");
394
+ simpleFormat(instant, { timeZone: 'America/New_York' }); // "Dec 23"
395
+ simpleFormat(instant, { timeZone: 'America/New_York', time: '12h' }); // "Dec 23, 3:30 PM"
396
+
397
+ // With PlainDate (no time option available)
398
+ const plain = Temporal.PlainDate.from("2020-12-23");
399
+ simpleFormat(plain); // "Dec 23, 2020"
400
+
401
+ // Different locales
402
+ simpleFormat(date2020, { locale: 'es-ES' }); // "23 dic 2020"
403
+ simpleFormat(date2020, { locale: 'de-DE' }); // "23. Dez. 2020"
404
+ ```
405
+
317
406
  ### Start/End Utilities
318
407
 
319
408
  #### `today(timezone?)`
@@ -0,0 +1,186 @@
1
+ // src/formatPlainDate.ts
2
+ import "@js-temporal/polyfill";
3
+ function formatPlainDate(date, formatStr, options = {}) {
4
+ const { locale = "en-US" } = options;
5
+ let result = "";
6
+ let i = 0;
7
+ const len = formatStr.length;
8
+ while (i < len) {
9
+ const char = formatStr[i];
10
+ if (!char) break;
11
+ if (char === "'") {
12
+ if (i + 1 < len && formatStr[i + 1] === "'") {
13
+ result += "'";
14
+ i += 2;
15
+ continue;
16
+ }
17
+ i++;
18
+ while (i < len) {
19
+ if (formatStr[i] === "'") {
20
+ if (i + 1 < len && formatStr[i + 1] === "'") {
21
+ result += "'";
22
+ i += 2;
23
+ } else {
24
+ i++;
25
+ break;
26
+ }
27
+ } else {
28
+ result += formatStr[i];
29
+ i++;
30
+ }
31
+ }
32
+ continue;
33
+ }
34
+ const token = consumeToken(formatStr, i, char);
35
+ if (token !== null) {
36
+ result += formatToken(token, date, locale);
37
+ i += token.length;
38
+ } else {
39
+ result += char;
40
+ i++;
41
+ }
42
+ }
43
+ return result;
44
+ }
45
+ function consumeToken(formatStr, start, char) {
46
+ if (char === "M" && start + 1 < formatStr.length && formatStr[start + 1] === "o") {
47
+ return "Mo";
48
+ }
49
+ if (char === "d" && start + 1 < formatStr.length && formatStr[start + 1] === "o") {
50
+ return "do";
51
+ }
52
+ let end = start;
53
+ while (end < formatStr.length && formatStr[end] === char) {
54
+ end++;
55
+ }
56
+ const count = end - start;
57
+ const validTokens = [
58
+ // Era
59
+ "GGGGG",
60
+ "GGGG",
61
+ "GGG",
62
+ "GG",
63
+ "G",
64
+ // Year
65
+ "yyyy",
66
+ "yyy",
67
+ "yy",
68
+ "y",
69
+ // Quarter
70
+ "QQQQQ",
71
+ "QQQQ",
72
+ "QQQ",
73
+ "QQ",
74
+ "Q",
75
+ // Month
76
+ "MMMMM",
77
+ "MMMM",
78
+ "MMM",
79
+ "MM",
80
+ "M",
81
+ // Day
82
+ "dd",
83
+ "d",
84
+ // Weekday
85
+ "EEEEEE",
86
+ "EEEEE",
87
+ "EEEE",
88
+ "EEE",
89
+ "EE",
90
+ "E"
91
+ ];
92
+ for (let len = Math.min(count, 6); len > 0; len--) {
93
+ const candidate = char.repeat(len);
94
+ if (validTokens.includes(candidate)) {
95
+ return candidate;
96
+ }
97
+ }
98
+ return null;
99
+ }
100
+ function formatToken(token, date, locale) {
101
+ switch (token) {
102
+ // Era
103
+ case "GGGGG":
104
+ return formatPart(date, "era", "narrow", locale);
105
+ case "GGGG":
106
+ return formatPart(date, "era", "long", locale);
107
+ case "GGG":
108
+ case "GG":
109
+ case "G":
110
+ return formatPart(date, "era", "short", locale);
111
+ // Year
112
+ case "yyyy":
113
+ return date.year.toString().padStart(4, "0");
114
+ case "yyy":
115
+ return date.year.toString().padStart(3, "0");
116
+ case "yy":
117
+ return (date.year % 100).toString().padStart(2, "0");
118
+ case "y":
119
+ return date.year.toString();
120
+ // Quarter
121
+ case "QQQQQ":
122
+ return Math.ceil(date.month / 3).toString();
123
+ case "QQQQ": {
124
+ const quarter = Math.ceil(date.month / 3);
125
+ return `${quarter}${getOrdinalSuffix(quarter)} quarter`;
126
+ }
127
+ case "QQQ":
128
+ return `Q${Math.ceil(date.month / 3)}`;
129
+ case "QQ":
130
+ return Math.ceil(date.month / 3).toString().padStart(2, "0");
131
+ case "Q":
132
+ return Math.ceil(date.month / 3).toString();
133
+ // Month
134
+ case "MMMMM":
135
+ return formatPart(date, "month", "narrow", locale);
136
+ case "MMMM":
137
+ return formatPart(date, "month", "long", locale);
138
+ case "MMM":
139
+ return formatPart(date, "month", "short", locale);
140
+ case "MM":
141
+ return date.month.toString().padStart(2, "0");
142
+ case "Mo":
143
+ return `${date.month}${getOrdinalSuffix(date.month)}`;
144
+ case "M":
145
+ return date.month.toString();
146
+ // Day of month
147
+ case "do":
148
+ return `${date.day}${getOrdinalSuffix(date.day)}`;
149
+ case "dd":
150
+ return date.day.toString().padStart(2, "0");
151
+ case "d":
152
+ return date.day.toString();
153
+ // Day of week
154
+ case "EEEEEE":
155
+ return formatPart(date, "weekday", "short", locale).slice(0, 2);
156
+ case "EEEEE":
157
+ return formatPart(date, "weekday", "narrow", locale);
158
+ case "EEEE":
159
+ return formatPart(date, "weekday", "long", locale);
160
+ case "EEE":
161
+ case "EE":
162
+ case "E":
163
+ return formatPart(date, "weekday", "short", locale);
164
+ default:
165
+ return token;
166
+ }
167
+ }
168
+ function formatPart(date, part, style, locale) {
169
+ const options = {
170
+ [part]: style
171
+ };
172
+ return date.toLocaleString(locale, options);
173
+ }
174
+ function getOrdinalSuffix(num) {
175
+ const j = num % 10;
176
+ const k = num % 100;
177
+ if (j === 1 && k !== 11) return "st";
178
+ if (j === 2 && k !== 12) return "nd";
179
+ if (j === 3 && k !== 13) return "rd";
180
+ return "th";
181
+ }
182
+
183
+ export {
184
+ formatPlainDate
185
+ };
186
+ //# sourceMappingURL=chunk-3A6X6WV5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/formatPlainDate.ts"],"sourcesContent":["import { Temporal } from '@js-temporal/polyfill';\n\nexport interface FormatPlainDateOptions {\n locale?: string;\n}\n\n/**\n * Format a Temporal.PlainDate using date-fns-like format tokens.\n * Uses Intl.DateTimeFormat under the hood for locale support.\n *\n * Only supports date-related tokens (no time or timezone tokens).\n *\n * @param date - A Temporal.PlainDate to format\n * @param formatStr - Format string using date-fns tokens (e.g., \"yyyy-MM-dd\")\n * @param options - Optional configuration for locale\n * @returns Formatted date string\n *\n * @example\n * ```typescript\n * const date = Temporal.PlainDate.from(\"2025-01-20\");\n *\n * formatPlainDate(date, \"yyyy-MM-dd\"); // \"2025-01-20\"\n * formatPlainDate(date, \"MMMM d, yyyy\"); // \"January 20, 2025\"\n * formatPlainDate(date, \"EEEE, MMMM do, yyyy\"); // \"Monday, January 20th, 2025\"\n *\n * // With locale\n * formatPlainDate(date, \"MMMM d, yyyy\", { locale: \"es-ES\" }); // \"enero 20, 2025\"\n * ```\n */\nexport function formatPlainDate(\n date: Temporal.PlainDate,\n formatStr: string,\n options: FormatPlainDateOptions = {}\n): string {\n const { locale = 'en-US' } = options;\n\n let result = '';\n let i = 0;\n const len = formatStr.length;\n\n while (i < len) {\n const char = formatStr[i];\n if (!char) break;\n\n // Handle escaped text\n if (char === \"'\") {\n // Check for double single quote (not inside a string, just '')\n if (i + 1 < len && formatStr[i + 1] === \"'\") {\n result += \"'\";\n i += 2;\n continue;\n }\n // Find closing quote, handling '' inside the string\n i++;\n while (i < len) {\n if (formatStr[i] === \"'\") {\n // Check if it's a doubled quote ''\n if (i + 1 < len && formatStr[i + 1] === \"'\") {\n result += \"'\";\n i += 2;\n } else {\n // End of quoted string\n i++;\n break;\n }\n } else {\n result += formatStr[i];\n i++;\n }\n }\n continue;\n }\n\n // Check for tokens by looking ahead\n const token = consumeToken(formatStr, i, char);\n if (token !== null) {\n result += formatToken(token, date, locale);\n i += token.length;\n } else {\n result += char;\n i++;\n }\n }\n\n return result;\n}\n\nfunction consumeToken(formatStr: string, start: number, char: string): string | null {\n // Special case for 'Mo' and 'do' - these end with 'o'\n if (char === 'M' && start + 1 < formatStr.length && formatStr[start + 1] === 'o') {\n return 'Mo';\n }\n if (char === 'd' && start + 1 < formatStr.length && formatStr[start + 1] === 'o') {\n return 'do';\n }\n\n // Count how many consecutive identical characters\n let end = start;\n while (end < formatStr.length && formatStr[end] === char) {\n end++;\n }\n const count = end - start;\n\n // Valid tokens for PlainDate (date-only, no time/timezone)\n const validTokens = [\n // Era\n 'GGGGG',\n 'GGGG',\n 'GGG',\n 'GG',\n 'G',\n // Year\n 'yyyy',\n 'yyy',\n 'yy',\n 'y',\n // Quarter\n 'QQQQQ',\n 'QQQQ',\n 'QQQ',\n 'QQ',\n 'Q',\n // Month\n 'MMMMM',\n 'MMMM',\n 'MMM',\n 'MM',\n 'M',\n // Day\n 'dd',\n 'd',\n // Weekday\n 'EEEEEE',\n 'EEEEE',\n 'EEEE',\n 'EEE',\n 'EE',\n 'E',\n ];\n\n // Try to match from longest to shortest\n for (let len = Math.min(count, 6); len > 0; len--) {\n const candidate = char.repeat(len);\n if (validTokens.includes(candidate)) {\n return candidate;\n }\n }\n\n return null;\n}\n\nfunction formatToken(token: string, date: Temporal.PlainDate, locale: string): string {\n switch (token) {\n // Era\n case 'GGGGG':\n return formatPart(date, 'era', 'narrow', locale);\n case 'GGGG':\n return formatPart(date, 'era', 'long', locale);\n case 'GGG':\n case 'GG':\n case 'G':\n return formatPart(date, 'era', 'short', locale);\n\n // Year\n case 'yyyy':\n return date.year.toString().padStart(4, '0');\n case 'yyy':\n return date.year.toString().padStart(3, '0');\n case 'yy':\n return (date.year % 100).toString().padStart(2, '0');\n case 'y':\n return date.year.toString();\n\n // Quarter\n case 'QQQQQ':\n return Math.ceil(date.month / 3).toString();\n case 'QQQQ': {\n const quarter = Math.ceil(date.month / 3);\n return `${quarter}${getOrdinalSuffix(quarter)} quarter`;\n }\n case 'QQQ':\n return `Q${Math.ceil(date.month / 3)}`;\n case 'QQ':\n return Math.ceil(date.month / 3)\n .toString()\n .padStart(2, '0');\n case 'Q':\n return Math.ceil(date.month / 3).toString();\n\n // Month\n case 'MMMMM':\n return formatPart(date, 'month', 'narrow', locale);\n case 'MMMM':\n return formatPart(date, 'month', 'long', locale);\n case 'MMM':\n return formatPart(date, 'month', 'short', locale);\n case 'MM':\n return date.month.toString().padStart(2, '0');\n case 'Mo':\n return `${date.month}${getOrdinalSuffix(date.month)}`;\n case 'M':\n return date.month.toString();\n\n // Day of month\n case 'do':\n return `${date.day}${getOrdinalSuffix(date.day)}`;\n case 'dd':\n return date.day.toString().padStart(2, '0');\n case 'd':\n return date.day.toString();\n\n // Day of week\n case 'EEEEEE':\n return formatPart(date, 'weekday', 'short', locale).slice(0, 2);\n case 'EEEEE':\n return formatPart(date, 'weekday', 'narrow', locale);\n case 'EEEE':\n return formatPart(date, 'weekday', 'long', locale);\n case 'EEE':\n case 'EE':\n case 'E':\n return formatPart(date, 'weekday', 'short', locale);\n\n default:\n return token;\n }\n}\n\nfunction formatPart(\n date: Temporal.PlainDate,\n part: 'era' | 'year' | 'month' | 'weekday' | 'day',\n style: 'narrow' | 'short' | 'long' | 'numeric' | '2-digit',\n locale: string\n): string {\n const options: Intl.DateTimeFormatOptions = {\n [part]: style,\n };\n\n return date.toLocaleString(locale, options);\n}\n\nfunction getOrdinalSuffix(num: number): string {\n const j = num % 10;\n const k = num % 100;\n if (j === 1 && k !== 11) return 'st';\n if (j === 2 && k !== 12) return 'nd';\n if (j === 3 && k !== 13) return 'rd';\n return 'th';\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,46 @@
1
+ // src/simpleFormat.ts
2
+ import { Temporal } from "@js-temporal/polyfill";
3
+ function simpleFormat(input, options = {}) {
4
+ const locale = options.locale ?? "en-US";
5
+ const time = "time" in options ? options.time : void 0;
6
+ const timeZone = "timeZone" in options ? options.timeZone : void 0;
7
+ const yearOption = "year" in options ? options.year : void 0;
8
+ let year;
9
+ let dateTimeForFormat;
10
+ if (input instanceof Temporal.Instant) {
11
+ const tz = timeZone ?? "UTC";
12
+ const zoned = input.toZonedDateTimeISO(tz);
13
+ year = zoned.year;
14
+ dateTimeForFormat = zoned;
15
+ } else if (input instanceof Temporal.ZonedDateTime) {
16
+ if (timeZone) {
17
+ const zoned = input.toInstant().toZonedDateTimeISO(timeZone);
18
+ year = zoned.year;
19
+ dateTimeForFormat = zoned;
20
+ } else {
21
+ year = input.year;
22
+ dateTimeForFormat = input;
23
+ }
24
+ } else {
25
+ year = input.year;
26
+ dateTimeForFormat = input;
27
+ }
28
+ const currentYear = Temporal.Now.plainDateISO().year;
29
+ const showYear = yearOption === "always" ? true : yearOption === "never" ? false : year !== currentYear;
30
+ const dateOptions = {
31
+ day: "numeric",
32
+ month: "short",
33
+ year: showYear ? "numeric" : void 0
34
+ };
35
+ if (time && !(input instanceof Temporal.PlainDate)) {
36
+ dateOptions.hour = "numeric";
37
+ dateOptions.minute = "2-digit";
38
+ dateOptions.hour12 = time === "12h";
39
+ }
40
+ return dateTimeForFormat.toLocaleString(locale, dateOptions);
41
+ }
42
+
43
+ export {
44
+ simpleFormat
45
+ };
46
+ //# sourceMappingURL=chunk-GQBO2UXH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/simpleFormat.ts"],"sourcesContent":["import { Temporal } from '@js-temporal/polyfill';\n\n// simpleFormat options - discriminated by input type\ninterface PlainDateOptions {\n locale?: string;\n year?: 'auto' | 'always' | 'never';\n}\n\ninterface ZonedDateTimeOptions {\n locale?: string;\n time?: '12h' | '24h';\n timeZone?: string;\n year?: 'auto' | 'always' | 'never';\n}\n\ninterface InstantOptions {\n locale?: string;\n time?: '12h' | '24h';\n timeZone: string; // required for Instant\n year?: 'auto' | 'always' | 'never';\n}\n\n/**\n * Format a Temporal date in a human-friendly way: \"Dec 23\" or \"Dec 23, 2020\"\n *\n * By default (year: 'auto'), shows the year only if the date is not in the current year.\n * Use year: 'always' to always show the year, or year: 'never' to always hide it.\n * Optionally includes time in 12-hour or 24-hour format.\n *\n * @example\n * ```typescript\n * // Assuming current year is 2026\n * const date2026 = Temporal.ZonedDateTime.from(\"2026-12-23T15:30:00[America/New_York]\");\n * const date2020 = Temporal.ZonedDateTime.from(\"2020-12-23T15:30:00[America/New_York]\");\n *\n * simpleFormat(date2026); // \"Dec 23\"\n * simpleFormat(date2020); // \"Dec 23, 2020\"\n * simpleFormat(date2026, { time: '12h' }); // \"Dec 23, 3:30 PM\"\n * simpleFormat(date2026, { time: '24h' }); // \"Dec 23, 15:30\"\n *\n * // Control year display\n * simpleFormat(date2026, { year: 'always' }); // \"Dec 23, 2026\"\n * simpleFormat(date2020, { year: 'never' }); // \"Dec 23\"\n * simpleFormat(date2020, { year: 'auto' }); // \"Dec 23, 2020\" (default behavior)\n *\n * // With Instant (timeZone required)\n * const instant = Temporal.Instant.from(\"2026-12-23T20:30:00Z\");\n * simpleFormat(instant, { timeZone: 'America/New_York' }); // \"Dec 23\"\n * simpleFormat(instant, { timeZone: 'America/New_York', time: '12h' }); // \"Dec 23, 3:30 PM\"\n *\n * // With PlainDate (no time option)\n * const plain = Temporal.PlainDate.from(\"2020-12-23\");\n * simpleFormat(plain); // \"Dec 23, 2020\"\n * ```\n */\nexport function simpleFormat(input: Temporal.PlainDate, options?: PlainDateOptions): string;\nexport function simpleFormat(input: Temporal.ZonedDateTime, options?: ZonedDateTimeOptions): string;\nexport function simpleFormat(input: Temporal.Instant, options: InstantOptions): string;\nexport function simpleFormat(\n input: Temporal.PlainDate | Temporal.ZonedDateTime | Temporal.Instant,\n options: PlainDateOptions | ZonedDateTimeOptions | InstantOptions = {}\n): string {\n const locale = options.locale ?? 'en-US';\n const time = 'time' in options ? options.time : undefined;\n const timeZone = 'timeZone' in options ? options.timeZone : undefined;\n const yearOption = 'year' in options ? options.year : undefined;\n\n // Get year from the input (converting Instant to ZonedDateTime if needed)\n let year: number;\n let dateTimeForFormat: Temporal.PlainDate | Temporal.ZonedDateTime;\n\n if (input instanceof Temporal.Instant) {\n const tz = timeZone ?? 'UTC';\n const zoned = input.toZonedDateTimeISO(tz);\n year = zoned.year;\n dateTimeForFormat = zoned;\n } else if (input instanceof Temporal.ZonedDateTime) {\n if (timeZone) {\n const zoned = input.toInstant().toZonedDateTimeISO(timeZone);\n year = zoned.year;\n dateTimeForFormat = zoned;\n } else {\n year = input.year;\n dateTimeForFormat = input;\n }\n } else {\n year = input.year;\n dateTimeForFormat = input;\n }\n\n // Determine if year should be shown\n const currentYear = Temporal.Now.plainDateISO().year;\n const showYear =\n yearOption === 'always' ? true : yearOption === 'never' ? false : year !== currentYear;\n\n const dateOptions: Intl.DateTimeFormatOptions = {\n day: 'numeric',\n month: 'short',\n year: showYear ? 'numeric' : undefined,\n };\n\n // Add time options if requested and input supports it\n if (time && !(input instanceof Temporal.PlainDate)) {\n dateOptions.hour = 'numeric';\n dateOptions.minute = '2-digit';\n dateOptions.hour12 = time === '12h';\n }\n\n return dateTimeForFormat.toLocaleString(locale, dateOptions);\n}\n"],"mappings":";AAAA,SAAS,gBAAgB;AA0DlB,SAAS,aACd,OACA,UAAoE,CAAC,GAC7D;AACR,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,OAAO,UAAU,UAAU,QAAQ,OAAO;AAChD,QAAM,WAAW,cAAc,UAAU,QAAQ,WAAW;AAC5D,QAAM,aAAa,UAAU,UAAU,QAAQ,OAAO;AAGtD,MAAI;AACJ,MAAI;AAEJ,MAAI,iBAAiB,SAAS,SAAS;AACrC,UAAM,KAAK,YAAY;AACvB,UAAM,QAAQ,MAAM,mBAAmB,EAAE;AACzC,WAAO,MAAM;AACb,wBAAoB;AAAA,EACtB,WAAW,iBAAiB,SAAS,eAAe;AAClD,QAAI,UAAU;AACZ,YAAM,QAAQ,MAAM,UAAU,EAAE,mBAAmB,QAAQ;AAC3D,aAAO,MAAM;AACb,0BAAoB;AAAA,IACtB,OAAO;AACL,aAAO,MAAM;AACb,0BAAoB;AAAA,IACtB;AAAA,EACF,OAAO;AACL,WAAO,MAAM;AACb,wBAAoB;AAAA,EACtB;AAGA,QAAM,cAAc,SAAS,IAAI,aAAa,EAAE;AAChD,QAAM,WACJ,eAAe,WAAW,OAAO,eAAe,UAAU,QAAQ,SAAS;AAE7E,QAAM,cAA0C;AAAA,IAC9C,KAAK;AAAA,IACL,OAAO;AAAA,IACP,MAAM,WAAW,YAAY;AAAA,EAC/B;AAGA,MAAI,QAAQ,EAAE,iBAAiB,SAAS,YAAY;AAClD,gBAAY,OAAO;AACnB,gBAAY,SAAS;AACrB,gBAAY,SAAS,SAAS;AAAA,EAChC;AAEA,SAAO,kBAAkB,eAAe,QAAQ,WAAW;AAC7D;","names":[]}
@@ -0,0 +1,29 @@
1
+ import { Temporal } from '@js-temporal/polyfill';
2
+ export interface FormatPlainDateOptions {
3
+ locale?: string;
4
+ }
5
+ /**
6
+ * Format a Temporal.PlainDate using date-fns-like format tokens.
7
+ * Uses Intl.DateTimeFormat under the hood for locale support.
8
+ *
9
+ * Only supports date-related tokens (no time or timezone tokens).
10
+ *
11
+ * @param date - A Temporal.PlainDate to format
12
+ * @param formatStr - Format string using date-fns tokens (e.g., "yyyy-MM-dd")
13
+ * @param options - Optional configuration for locale
14
+ * @returns Formatted date string
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const date = Temporal.PlainDate.from("2025-01-20");
19
+ *
20
+ * formatPlainDate(date, "yyyy-MM-dd"); // "2025-01-20"
21
+ * formatPlainDate(date, "MMMM d, yyyy"); // "January 20, 2025"
22
+ * formatPlainDate(date, "EEEE, MMMM do, yyyy"); // "Monday, January 20th, 2025"
23
+ *
24
+ * // With locale
25
+ * formatPlainDate(date, "MMMM d, yyyy", { locale: "es-ES" }); // "enero 20, 2025"
26
+ * ```
27
+ */
28
+ export declare function formatPlainDate(date: Temporal.PlainDate, formatStr: string, options?: FormatPlainDateOptions): string;
29
+ //# sourceMappingURL=formatPlainDate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatPlainDate.d.ts","sourceRoot":"","sources":["../src/formatPlainDate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,CAAC,SAAS,EACxB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,sBAA2B,GACnC,MAAM,CAoDR"}
@@ -0,0 +1,7 @@
1
+ import {
2
+ formatPlainDate
3
+ } from "./chunk-3A6X6WV5.js";
4
+ export {
5
+ formatPlainDate
6
+ };
7
+ //# sourceMappingURL=formatPlainDate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=formatPlainDate.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatPlainDate.test.d.ts","sourceRoot":"","sources":["../src/formatPlainDate.test.ts"],"names":[],"mappings":""}
package/dist/index.d.ts CHANGED
@@ -3,6 +3,8 @@ export { toUtc } from './toUtc';
3
3
  export { toUtcString } from './toUtcString';
4
4
  export { toDate } from './toDate';
5
5
  export { format, type FormatOptions } from './format';
6
+ export { formatPlainDate, type FormatPlainDateOptions } from './formatPlainDate';
7
+ export { simpleFormat } from './simpleFormat';
6
8
  export { today } from './today';
7
9
  export { now } from './now';
8
10
  export { startOfDay } from './startOfDay';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,6 +1,18 @@
1
+ import {
2
+ toUtcString
3
+ } from "./chunk-DMKGJY4N.js";
4
+ import {
5
+ toZonedTime
6
+ } from "./chunk-2MP3ESL7.js";
1
7
  import {
2
8
  today
3
9
  } from "./chunk-67QHALIG.js";
10
+ import {
11
+ subMonths
12
+ } from "./chunk-52NEOY34.js";
13
+ import {
14
+ subNanoseconds
15
+ } from "./chunk-WVHAYLBW.js";
4
16
  import {
5
17
  subSeconds
6
18
  } from "./chunk-BH2YB4MV.js";
@@ -17,11 +29,11 @@ import {
17
29
  toUtc
18
30
  } from "./chunk-BW5SFCKS.js";
19
31
  import {
20
- toUtcString
21
- } from "./chunk-DMKGJY4N.js";
32
+ startOfMonth
33
+ } from "./chunk-TU2UNOOW.js";
22
34
  import {
23
- toZonedTime
24
- } from "./chunk-2MP3ESL7.js";
35
+ startOfWeek
36
+ } from "./chunk-2WMXB7QL.js";
25
37
  import {
26
38
  startOfYear
27
39
  } from "./chunk-YR2UCUIT.js";
@@ -41,11 +53,8 @@ import {
41
53
  subMinutes
42
54
  } from "./chunk-J6G2I2TU.js";
43
55
  import {
44
- subMonths
45
- } from "./chunk-52NEOY34.js";
46
- import {
47
- subNanoseconds
48
- } from "./chunk-WVHAYLBW.js";
56
+ isSameMonth
57
+ } from "./chunk-ADQTZVMH.js";
49
58
  import {
50
59
  isSameNanosecond
51
60
  } from "./chunk-S63QUP4W.js";
@@ -61,15 +70,15 @@ import {
61
70
  import {
62
71
  now
63
72
  } from "./chunk-3YGPHHB6.js";
73
+ import {
74
+ simpleFormat
75
+ } from "./chunk-GQBO2UXH.js";
64
76
  import {
65
77
  startOfDay
66
78
  } from "./chunk-TW5EV3DH.js";
67
79
  import {
68
- startOfMonth
69
- } from "./chunk-TU2UNOOW.js";
70
- import {
71
- startOfWeek
72
- } from "./chunk-2WMXB7QL.js";
80
+ isPlainDateAfter
81
+ } from "./chunk-BPZ7BRJW.js";
73
82
  import {
74
83
  isPlainDateBefore
75
84
  } from "./chunk-4E7OGJ3F.js";
@@ -91,12 +100,12 @@ import {
91
100
  import {
92
101
  isSameMinute
93
102
  } from "./chunk-LDO6PRNJ.js";
94
- import {
95
- isSameMonth
96
- } from "./chunk-ADQTZVMH.js";
97
103
  import {
98
104
  format
99
105
  } from "./chunk-2G5RJGPR.js";
106
+ import {
107
+ formatPlainDate
108
+ } from "./chunk-3A6X6WV5.js";
100
109
  import {
101
110
  intlFormatDistance
102
111
  } from "./chunk-XEDXPI5G.js";
@@ -112,9 +121,6 @@ import {
112
121
  import {
113
122
  isPast
114
123
  } from "./chunk-2H4KLXGL.js";
115
- import {
116
- isPlainDateAfter
117
- } from "./chunk-BPZ7BRJW.js";
118
124
  import {
119
125
  differenceInNanoseconds
120
126
  } from "./chunk-OABS374T.js";
@@ -215,6 +221,7 @@ export {
215
221
  endOfWeek,
216
222
  endOfYear,
217
223
  format,
224
+ formatPlainDate,
218
225
  intlFormatDistance,
219
226
  isAfter,
220
227
  isBefore,
@@ -234,6 +241,7 @@ export {
234
241
  isSameWeek,
235
242
  isSameYear,
236
243
  now,
244
+ simpleFormat,
237
245
  startOfDay,
238
246
  startOfMonth,
239
247
  startOfWeek,
@@ -0,0 +1,55 @@
1
+ import { Temporal } from '@js-temporal/polyfill';
2
+ interface PlainDateOptions {
3
+ locale?: string;
4
+ year?: 'auto' | 'always' | 'never';
5
+ }
6
+ interface ZonedDateTimeOptions {
7
+ locale?: string;
8
+ time?: '12h' | '24h';
9
+ timeZone?: string;
10
+ year?: 'auto' | 'always' | 'never';
11
+ }
12
+ interface InstantOptions {
13
+ locale?: string;
14
+ time?: '12h' | '24h';
15
+ timeZone: string;
16
+ year?: 'auto' | 'always' | 'never';
17
+ }
18
+ /**
19
+ * Format a Temporal date in a human-friendly way: "Dec 23" or "Dec 23, 2020"
20
+ *
21
+ * By default (year: 'auto'), shows the year only if the date is not in the current year.
22
+ * Use year: 'always' to always show the year, or year: 'never' to always hide it.
23
+ * Optionally includes time in 12-hour or 24-hour format.
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * // Assuming current year is 2026
28
+ * const date2026 = Temporal.ZonedDateTime.from("2026-12-23T15:30:00[America/New_York]");
29
+ * const date2020 = Temporal.ZonedDateTime.from("2020-12-23T15:30:00[America/New_York]");
30
+ *
31
+ * simpleFormat(date2026); // "Dec 23"
32
+ * simpleFormat(date2020); // "Dec 23, 2020"
33
+ * simpleFormat(date2026, { time: '12h' }); // "Dec 23, 3:30 PM"
34
+ * simpleFormat(date2026, { time: '24h' }); // "Dec 23, 15:30"
35
+ *
36
+ * // Control year display
37
+ * simpleFormat(date2026, { year: 'always' }); // "Dec 23, 2026"
38
+ * simpleFormat(date2020, { year: 'never' }); // "Dec 23"
39
+ * simpleFormat(date2020, { year: 'auto' }); // "Dec 23, 2020" (default behavior)
40
+ *
41
+ * // With Instant (timeZone required)
42
+ * const instant = Temporal.Instant.from("2026-12-23T20:30:00Z");
43
+ * simpleFormat(instant, { timeZone: 'America/New_York' }); // "Dec 23"
44
+ * simpleFormat(instant, { timeZone: 'America/New_York', time: '12h' }); // "Dec 23, 3:30 PM"
45
+ *
46
+ * // With PlainDate (no time option)
47
+ * const plain = Temporal.PlainDate.from("2020-12-23");
48
+ * simpleFormat(plain); // "Dec 23, 2020"
49
+ * ```
50
+ */
51
+ export declare function simpleFormat(input: Temporal.PlainDate, options?: PlainDateOptions): string;
52
+ export declare function simpleFormat(input: Temporal.ZonedDateTime, options?: ZonedDateTimeOptions): string;
53
+ export declare function simpleFormat(input: Temporal.Instant, options: InstantOptions): string;
54
+ export {};
55
+ //# sourceMappingURL=simpleFormat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simpleFormat.d.ts","sourceRoot":"","sources":["../src/simpleFormat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGjD,UAAU,gBAAgB;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;CACpC;AAED,UAAU,oBAAoB;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;CACpC;AAED,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;AAC5F,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,MAAM,CAAC;AACpG,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAAC"}
@@ -0,0 +1,7 @@
1
+ import {
2
+ simpleFormat
3
+ } from "./chunk-GQBO2UXH.js";
4
+ export {
5
+ simpleFormat
6
+ };
7
+ //# sourceMappingURL=simpleFormat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=simpleFormat.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simpleFormat.test.d.ts","sourceRoot":"","sources":["../src/simpleFormat.test.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobrand/tiempo",
3
- "version": "2.3.2",
3
+ "version": "2.3.4",
4
4
  "description": "Lightweight utility functions for converting between UTC and timezone-aware datetimes using the Temporal API",
5
5
  "private": false,
6
6
  "publishConfig": {