chronal 0.0.9 → 0.0.12
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 +22 -0
- package/esm/core/rtf.d.ts +2 -0
- package/esm/core/rtf.d.ts.map +1 -0
- package/esm/core/rtf.js +10 -0
- package/esm/lib/from-now.d.ts.map +1 -1
- package/esm/lib/from-now.js +9 -3
- package/esm/lib/parse-date.d.ts.map +1 -1
- package/esm/lib/parse-date.js +4 -2
- package/esm/lib/to-now.d.ts.map +1 -1
- package/esm/lib/to-now.js +9 -3
- package/package.json +1 -1
- package/script/core/rtf.d.ts +2 -0
- package/script/core/rtf.d.ts.map +1 -0
- package/script/core/rtf.js +13 -0
- package/script/lib/from-now.d.ts.map +1 -1
- package/script/lib/from-now.js +9 -3
- package/script/lib/parse-date.d.ts.map +1 -1
- package/script/lib/parse-date.js +4 -2
- package/script/lib/to-now.d.ts.map +1 -1
- package/script/lib/to-now.js +9 -3
package/README.md
CHANGED
|
@@ -324,9 +324,28 @@ Parses a date string into a Date object using an optional format pattern.
|
|
|
324
324
|
- `dateString` (string) - The date string to parse
|
|
325
325
|
- `format` (string, optional) - Format pattern (e.g., "YYYY-MM-DD",
|
|
326
326
|
"DD/MM/YYYY")
|
|
327
|
+
- `options` (object, optional) - Parsing options
|
|
328
|
+
- `tz` (string) - IANA timezone (e.g., 'America/Sao_Paulo')
|
|
327
329
|
|
|
328
330
|
**Returns:** Date object
|
|
329
331
|
|
|
332
|
+
**Timezone Behavior:**
|
|
333
|
+
|
|
334
|
+
When parsing date strings, `parseDate` follows these rules:
|
|
335
|
+
|
|
336
|
+
1. **Explicit timezone** (e.g., `Z` or `+03:00`) - Always respected, ignores `config.timezone`
|
|
337
|
+
2. **No timezone** - Uses `config.timezone` or the `tz` option to interpret the string as local time in that timezone
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
// With explicit UTC marker (Z) - always UTC
|
|
341
|
+
parseDate("2026-01-12T02:59:59.999Z"); // UTC time, ignores config
|
|
342
|
+
|
|
343
|
+
// Without timezone - uses config.timezone
|
|
344
|
+
setChronalConfig({ timezone: "America/Sao_Paulo" });
|
|
345
|
+
parseDate("2026-01-12T02:59:59.999"); // Interpreted as São Paulo time
|
|
346
|
+
parseDate("2026-01-12"); // Midnight in São Paulo
|
|
347
|
+
```
|
|
348
|
+
|
|
330
349
|
**Supported Tokens:**
|
|
331
350
|
|
|
332
351
|
- `YYYY` - 4-digit year
|
|
@@ -346,6 +365,9 @@ parseDate("2024-06-15"); // Date object
|
|
|
346
365
|
parseDate("15/06/2024", "DD/MM/YYYY");
|
|
347
366
|
parseDate("2024-06-15 14:30:00", "YYYY-MM-DD HH:mm:ss");
|
|
348
367
|
parseDate("06/15/2024", "MM/DD/YYYY");
|
|
368
|
+
|
|
369
|
+
// With timezone
|
|
370
|
+
parseDate("2024-06-15", { tz: "America/Sao_Paulo" }); // Parse as São Paulo time
|
|
349
371
|
```
|
|
350
372
|
|
|
351
373
|
### Manipulation
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rtf.d.ts","sourceRoot":"","sources":["../../src/core/rtf.ts"],"names":[],"mappings":"AAEA,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ,2BAQhE"}
|
package/esm/core/rtf.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const rtfCache = new Map();
|
|
2
|
+
export function getRTF(locale, numeric) {
|
|
3
|
+
const key = `${locale}|${numeric}`;
|
|
4
|
+
let rtf = rtfCache.get(key);
|
|
5
|
+
if (!rtf) {
|
|
6
|
+
rtf = new Intl.RelativeTimeFormat(locale, { numeric });
|
|
7
|
+
rtfCache.set(key, rtf);
|
|
8
|
+
}
|
|
9
|
+
return rtf;
|
|
10
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"from-now.d.ts","sourceRoot":"","sources":["../../src/lib/from-now.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"from-now.d.ts","sourceRoot":"","sources":["../../src/lib/from-now.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,GAAE,MAAsB,GAAG,MAAM,CAyC1E"}
|
package/esm/lib/from-now.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getRTF } from "../core/rtf.js";
|
|
1
2
|
import { config } from "./config.js";
|
|
2
3
|
/**
|
|
3
4
|
* Returns a string representing how long ago the date was from now.
|
|
@@ -25,21 +26,26 @@ export function fromNow(date, locale = config.locale) {
|
|
|
25
26
|
const minutes = Math.floor(seconds / 60);
|
|
26
27
|
const hours = Math.floor(minutes / 60);
|
|
27
28
|
const days = Math.floor(hours / 24);
|
|
29
|
+
const weeks = Math.floor(days / 7);
|
|
28
30
|
const months = Math.floor(days / 30);
|
|
29
31
|
const years = Math.floor(days / 365);
|
|
30
|
-
|
|
32
|
+
// Use auto for "now", always for everything else
|
|
31
33
|
if (seconds < 60) {
|
|
32
|
-
return
|
|
34
|
+
return getRTF(locale, "auto").format(0, "second");
|
|
33
35
|
}
|
|
36
|
+
const rtf = getRTF(locale, "always");
|
|
34
37
|
if (minutes < 60) {
|
|
35
38
|
return rtf.format(diff < 0 ? minutes : -minutes, "minute");
|
|
36
39
|
}
|
|
37
40
|
if (hours < 24) {
|
|
38
41
|
return rtf.format(diff < 0 ? hours : -hours, "hour");
|
|
39
42
|
}
|
|
40
|
-
if (days <
|
|
43
|
+
if (days < 7) {
|
|
41
44
|
return rtf.format(diff < 0 ? days : -days, "day");
|
|
42
45
|
}
|
|
46
|
+
if (days < 30) {
|
|
47
|
+
return rtf.format(diff < 0 ? weeks : -weeks, "week");
|
|
48
|
+
}
|
|
43
49
|
if (months < 12) {
|
|
44
50
|
return rtf.format(diff < 0 ? months : -months, "month");
|
|
45
51
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-date.d.ts","sourceRoot":"","sources":["../../src/lib/parse-date.ts"],"names":[],"mappings":"AAGA,KAAK,gBAAgB,GAAG;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CACvB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GAAG,gBAAgB,GAClC,IAAI,
|
|
1
|
+
{"version":3,"file":"parse-date.d.ts","sourceRoot":"","sources":["../../src/lib/parse-date.ts"],"names":[],"mappings":"AAGA,KAAK,gBAAgB,GAAG;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CACvB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GAAG,gBAAgB,GAClC,IAAI,CA6FN"}
|
package/esm/lib/parse-date.js
CHANGED
|
@@ -27,8 +27,10 @@ export function parseDate(dateString, options) {
|
|
|
27
27
|
if (isNaN(date.getTime())) {
|
|
28
28
|
throw new Error("Invalid date");
|
|
29
29
|
}
|
|
30
|
-
// If
|
|
31
|
-
|
|
30
|
+
// If the string has explicit timezone (Z or offset like +03:00), respect it
|
|
31
|
+
// Only apply config.timezone for date strings without timezone info
|
|
32
|
+
const hasExplicitTimezone = /Z|[+-]\d{2}:\d{2}$/.test(dateString);
|
|
33
|
+
if (!hasExplicitTimezone && timezone !== "UTC") {
|
|
32
34
|
return parseDateInTimezone(date, timezone);
|
|
33
35
|
}
|
|
34
36
|
return date;
|
package/esm/lib/to-now.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"to-now.d.ts","sourceRoot":"","sources":["../../src/lib/to-now.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"to-now.d.ts","sourceRoot":"","sources":["../../src/lib/to-now.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,GAAE,MAAsB,GAAG,MAAM,CAyCxE"}
|
package/esm/lib/to-now.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getRTF } from "../core/rtf.js";
|
|
1
2
|
import { config } from "./config.js";
|
|
2
3
|
/**
|
|
3
4
|
* Returns a string representing the time from now to the date.
|
|
@@ -26,21 +27,26 @@ export function toNow(date, locale = config.locale) {
|
|
|
26
27
|
const minutes = Math.floor(seconds / 60);
|
|
27
28
|
const hours = Math.floor(minutes / 60);
|
|
28
29
|
const days = Math.floor(hours / 24);
|
|
30
|
+
const weeks = Math.floor(days / 7);
|
|
29
31
|
const months = Math.floor(days / 30);
|
|
30
32
|
const years = Math.floor(days / 365);
|
|
31
|
-
|
|
33
|
+
// Use auto for "now", always for everything else
|
|
32
34
|
if (seconds < 60) {
|
|
33
|
-
return
|
|
35
|
+
return getRTF(locale, "auto").format(0, "second");
|
|
34
36
|
}
|
|
37
|
+
const rtf = getRTF(locale, "always");
|
|
35
38
|
if (minutes < 60) {
|
|
36
39
|
return rtf.format(diff > 0 ? minutes : -minutes, "minute");
|
|
37
40
|
}
|
|
38
41
|
if (hours < 24) {
|
|
39
42
|
return rtf.format(diff > 0 ? hours : -hours, "hour");
|
|
40
43
|
}
|
|
41
|
-
if (days <
|
|
44
|
+
if (days < 7) {
|
|
42
45
|
return rtf.format(diff > 0 ? days : -days, "day");
|
|
43
46
|
}
|
|
47
|
+
if (days < 30) {
|
|
48
|
+
return rtf.format(diff > 0 ? weeks : -weeks, "week");
|
|
49
|
+
}
|
|
44
50
|
if (months < 12) {
|
|
45
51
|
return rtf.format(diff > 0 ? months : -months, "month");
|
|
46
52
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rtf.d.ts","sourceRoot":"","sources":["../../src/core/rtf.ts"],"names":[],"mappings":"AAEA,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ,2BAQhE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getRTF = getRTF;
|
|
4
|
+
const rtfCache = new Map();
|
|
5
|
+
function getRTF(locale, numeric) {
|
|
6
|
+
const key = `${locale}|${numeric}`;
|
|
7
|
+
let rtf = rtfCache.get(key);
|
|
8
|
+
if (!rtf) {
|
|
9
|
+
rtf = new Intl.RelativeTimeFormat(locale, { numeric });
|
|
10
|
+
rtfCache.set(key, rtf);
|
|
11
|
+
}
|
|
12
|
+
return rtf;
|
|
13
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"from-now.d.ts","sourceRoot":"","sources":["../../src/lib/from-now.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"from-now.d.ts","sourceRoot":"","sources":["../../src/lib/from-now.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,GAAE,MAAsB,GAAG,MAAM,CAyC1E"}
|
package/script/lib/from-now.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.fromNow = fromNow;
|
|
4
|
+
const rtf_js_1 = require("../core/rtf.js");
|
|
4
5
|
const config_js_1 = require("./config.js");
|
|
5
6
|
/**
|
|
6
7
|
* Returns a string representing how long ago the date was from now.
|
|
@@ -28,21 +29,26 @@ function fromNow(date, locale = config_js_1.config.locale) {
|
|
|
28
29
|
const minutes = Math.floor(seconds / 60);
|
|
29
30
|
const hours = Math.floor(minutes / 60);
|
|
30
31
|
const days = Math.floor(hours / 24);
|
|
32
|
+
const weeks = Math.floor(days / 7);
|
|
31
33
|
const months = Math.floor(days / 30);
|
|
32
34
|
const years = Math.floor(days / 365);
|
|
33
|
-
|
|
35
|
+
// Use auto for "now", always for everything else
|
|
34
36
|
if (seconds < 60) {
|
|
35
|
-
return
|
|
37
|
+
return (0, rtf_js_1.getRTF)(locale, "auto").format(0, "second");
|
|
36
38
|
}
|
|
39
|
+
const rtf = (0, rtf_js_1.getRTF)(locale, "always");
|
|
37
40
|
if (minutes < 60) {
|
|
38
41
|
return rtf.format(diff < 0 ? minutes : -minutes, "minute");
|
|
39
42
|
}
|
|
40
43
|
if (hours < 24) {
|
|
41
44
|
return rtf.format(diff < 0 ? hours : -hours, "hour");
|
|
42
45
|
}
|
|
43
|
-
if (days <
|
|
46
|
+
if (days < 7) {
|
|
44
47
|
return rtf.format(diff < 0 ? days : -days, "day");
|
|
45
48
|
}
|
|
49
|
+
if (days < 30) {
|
|
50
|
+
return rtf.format(diff < 0 ? weeks : -weeks, "week");
|
|
51
|
+
}
|
|
46
52
|
if (months < 12) {
|
|
47
53
|
return rtf.format(diff < 0 ? months : -months, "month");
|
|
48
54
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-date.d.ts","sourceRoot":"","sources":["../../src/lib/parse-date.ts"],"names":[],"mappings":"AAGA,KAAK,gBAAgB,GAAG;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CACvB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GAAG,gBAAgB,GAClC,IAAI,
|
|
1
|
+
{"version":3,"file":"parse-date.d.ts","sourceRoot":"","sources":["../../src/lib/parse-date.ts"],"names":[],"mappings":"AAGA,KAAK,gBAAgB,GAAG;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CACvB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GAAG,gBAAgB,GAClC,IAAI,CA6FN"}
|
package/script/lib/parse-date.js
CHANGED
|
@@ -30,8 +30,10 @@ function parseDate(dateString, options) {
|
|
|
30
30
|
if (isNaN(date.getTime())) {
|
|
31
31
|
throw new Error("Invalid date");
|
|
32
32
|
}
|
|
33
|
-
// If
|
|
34
|
-
|
|
33
|
+
// If the string has explicit timezone (Z or offset like +03:00), respect it
|
|
34
|
+
// Only apply config.timezone for date strings without timezone info
|
|
35
|
+
const hasExplicitTimezone = /Z|[+-]\d{2}:\d{2}$/.test(dateString);
|
|
36
|
+
if (!hasExplicitTimezone && timezone !== "UTC") {
|
|
35
37
|
return parseDateInTimezone(date, timezone);
|
|
36
38
|
}
|
|
37
39
|
return date;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"to-now.d.ts","sourceRoot":"","sources":["../../src/lib/to-now.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"to-now.d.ts","sourceRoot":"","sources":["../../src/lib/to-now.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,GAAE,MAAsB,GAAG,MAAM,CAyCxE"}
|
package/script/lib/to-now.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.toNow = toNow;
|
|
4
|
+
const rtf_js_1 = require("../core/rtf.js");
|
|
4
5
|
const config_js_1 = require("./config.js");
|
|
5
6
|
/**
|
|
6
7
|
* Returns a string representing the time from now to the date.
|
|
@@ -29,21 +30,26 @@ function toNow(date, locale = config_js_1.config.locale) {
|
|
|
29
30
|
const minutes = Math.floor(seconds / 60);
|
|
30
31
|
const hours = Math.floor(minutes / 60);
|
|
31
32
|
const days = Math.floor(hours / 24);
|
|
33
|
+
const weeks = Math.floor(days / 7);
|
|
32
34
|
const months = Math.floor(days / 30);
|
|
33
35
|
const years = Math.floor(days / 365);
|
|
34
|
-
|
|
36
|
+
// Use auto for "now", always for everything else
|
|
35
37
|
if (seconds < 60) {
|
|
36
|
-
return
|
|
38
|
+
return (0, rtf_js_1.getRTF)(locale, "auto").format(0, "second");
|
|
37
39
|
}
|
|
40
|
+
const rtf = (0, rtf_js_1.getRTF)(locale, "always");
|
|
38
41
|
if (minutes < 60) {
|
|
39
42
|
return rtf.format(diff > 0 ? minutes : -minutes, "minute");
|
|
40
43
|
}
|
|
41
44
|
if (hours < 24) {
|
|
42
45
|
return rtf.format(diff > 0 ? hours : -hours, "hour");
|
|
43
46
|
}
|
|
44
|
-
if (days <
|
|
47
|
+
if (days < 7) {
|
|
45
48
|
return rtf.format(diff > 0 ? days : -days, "day");
|
|
46
49
|
}
|
|
50
|
+
if (days < 30) {
|
|
51
|
+
return rtf.format(diff > 0 ? weeks : -weeks, "week");
|
|
52
|
+
}
|
|
47
53
|
if (months < 12) {
|
|
48
54
|
return rtf.format(diff > 0 ? months : -months, "month");
|
|
49
55
|
}
|