coraab-time 0.0.0-stage → 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 JJetmar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,180 @@
1
- # Temporary Holding Version
1
+ # Coraab-time
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Work with time in the units of Coraab, the planet of the [Coraabia](https://coraabia.fandom.com/wiki/Coraabia_Wiki) universe.
4
+ The API is similar to [Day.js](https://day.js.org/), and the package also ships an optional Day.js plugin.
5
+
6
+ Live clock and converter: <https://jjetmar.github.io/coraab-time>
7
+
8
+ ## Coraab units
9
+
10
+ | Unit | Length | Notes |
11
+ | --- | --- | --- |
12
+ | OM | 5 Earth seconds | 60 OM = 1 UNT |
13
+ | UNT | 5 Earth minutes | 12 UNT = 1 UN |
14
+ | UN | 1 Earth hour | |
15
+ | Oonar (Light Day) | 96 UN | first day of a TOL |
16
+ | Hakkar (Haze Day) | 72 UN | second day of a TOL |
17
+ | TOL | 168 UN = 7 Earth days | 8 TOL = 1 TU (Ta'Tol … Raa'Tol) |
18
+ | TU | 56 Earth days | the Coraab "year", TU 0 starts on 1358-08-14 UTC |
19
+ | GUL | 6 TU = 336 Earth days | Ta'Tu … Ro'Tu |
20
+
21
+ TU starts at 0 and can be negative. GUL, TOL, UN, UNT and OM start at 1, so GUL 1 is TU 0–5 and GUL 714 ends when TU 4284 starts.
22
+
23
+ ## Install
24
+
25
+ ```sh
26
+ npm install coraab-time
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ ```ts
32
+ import { coraab } from 'coraab-time';
33
+
34
+ const now = coraab(); // current time
35
+ now.toString(); // "53H|2|4358 Tu 4 Unt 60 Om"
36
+ now.format('MMMM, dddd'); // "Nuu'Tol, Hakkar"
37
+ now.tu(); // 4358
38
+ now.tol(3); // new instance in TOL 3 (instances are immutable)
39
+
40
+ coraab('54L|6|4273 Tu').toDate(); // Coraab -> Earth
41
+ coraab(new Date('2026-11-01')); // Earth -> Coraab
42
+ coraab('2026-11-01T12:00:00Z'); // Earth strings work too
43
+
44
+ now.add(2, 'tol').subtract(3, 'days');
45
+ now.startOf('tu').add(1, 'tu').diff(now, 'second'); // seconds until the next TU
46
+ ```
47
+
48
+ ### Creating a date from parts
49
+
50
+ `coraab.from(parts)` creates an exact date. Only `tu` is required, and missing parts start at the beginning (Oonar, 1, 0 ms), like in Coraab strings:
51
+
52
+ ```ts
53
+ const time = coraab.from({ tu: 4360, tol: 5, un: 12, unt: 3, om: 30 });
54
+
55
+ time.toString(); // "12L|5|4360 Tu 3 Unt 30 Om"
56
+ time.format('MMMM, dddd'); // "Tha'Tol, Oonar"
57
+
58
+ coraab.from({ tu: 4360, tol: 5, day: 'hakkar', un: 10 }).toString(); // "10H|5|4360 Tu 1 Unt 1 Om"
59
+ ```
60
+
61
+ Values out of range roll over, for example `un: 97` on Oonar gives Hakkar UN 1.
62
+
63
+ ### Changing units
64
+
65
+ Setters change one unit and keep the rest. Each one returns a new instance, so they can be chained:
66
+
67
+ ```ts
68
+ time.tol(6).un(20).toString(); // "20L|6|4360 Tu 3 Unt 30 Om"
69
+ time.gul(800).toString(); // "12L|5|4798 Tu 3 Unt 30 Om" (TU 5 of GUL 800)
70
+ time.set('tol', 6).set('un', 20); // the same as the first line
71
+ ```
72
+
73
+ `un()` counts within the current day. There is no setter for the day itself, so use `coraab.from` to pick Oonar or Hakkar.
74
+
75
+ ### Input
76
+
77
+ `coraab(input?)` accepts a `Date`, a timestamp in milliseconds, a Coraab string, an Earth date string, another `CoraabTime`,
78
+ or any object with `valueOf()` (for example a Day.js instance). `null` and unparsable strings give an invalid instance, like in Day.js.
79
+
80
+ Coraab strings can be written as `4273 Tu`, `6|4273 Tu` (TOL|TU), `54L|6|4273 Tu`, `54L|6|4273 Tu 5 Unt` or `54L|6|4273 Tu 5 Unt 31 Om`.
81
+ Unit names and `Tu` are not case-sensitive.
82
+ Missing parts default to 1.
83
+ `coraab.unix(seconds)` creates an instance from Unix seconds, and `coraab.from(parts)` from Coraab parts (see above).
84
+
85
+ ### Units
86
+
87
+ - `add` / `subtract` / `diff`: `gul`, `tu`, `tol`, `un`, `unt`, `om` and Earth units `millisecond`, `second`, `minute`, `hour`, `day`, `week`.
88
+ Plurals (`tols`, `days`) and short names (`ms`, `s`, `m`, `h`, `d`, `w`) work too.
89
+ - `startOf` / `endOf` / `isSame` / `isBefore` / `isAfter`: `gul`, `tu`, `tol`, `coraabDay` (Oonar or Hakkar), `un`, `unt`, `om` (plurals work too).
90
+ - Fractional amounts are rounded to whole milliseconds. Unknown units throw an error.
91
+ - Getters and setters: `gul()`, `tu()`, `tol()`, `un()`, `unt()`, `om()`, plus `get(unit)` and `set(unit, value)`.
92
+ Values out of range roll over, for example `un(97)` in Oonar moves to Hakkar UN 1.
93
+ - Read only: `tuOfGul()`, `coraabDay()` (`'oonar'` or `'hakkar'`), `toParts()`.
94
+
95
+ ### Format tokens
96
+
97
+ | Token | Output | Example |
98
+ | --- | --- | --- |
99
+ | `Y` | TU | `4358` |
100
+ | `G` | GUL | `727` |
101
+ | `g` | TU in GUL (1–6) | `3` |
102
+ | `gggg` | TU name | `Ka'Tu` |
103
+ | `M` / `MM` | TOL (1–8) | `2` / `02` |
104
+ | `MMMM` | TOL name | `Nuu'Tol` |
105
+ | `d` | day letter | `L` (Oonar) / `H` (Hakkar) |
106
+ | `dddd` | day name | `Oonar` / `Hakkar` |
107
+ | `H` / `HH` | UN in the day | `7` / `07` |
108
+ | `m` / `mm` | UNT | `4` / `04` |
109
+ | `s` / `ss` | OM | `9` / `09` |
110
+ | `[text]` | escaped text | `[Tu]` |
111
+
112
+ `toString()` uses `Hd|M|Y [Tu] m [Unt] s [Om]`, which extends the wiki's notation (`54L|6|4273 Tu`) with UNT and OM: `54L|6|4273 Tu 5 Unt 31 Om`.
113
+ The wiki text only ever uses `L`. `H` for Hakkar comes from the news images on [coraabopedia.cz](https://coraabopedia.cz/wiki/Coraabia_News), which are named `TU_TOL_L` / `TU_TOL_H` and whose upload times match this library's Oonar/Hakkar periods.
114
+ Coraab strings are precise to one OM (5 seconds). `toJSON()` returns an ISO string so no precision is lost.
115
+
116
+ ### Conversion
117
+
118
+ `valueOf()`, `unix()`, `toDate()`, `toISOString()`, `toJSON()`, `clone()`, `isValid()`.
119
+
120
+ ## Day.js plugin
121
+
122
+ ```ts
123
+ import dayjs from 'dayjs';
124
+ import coraabPlugin from 'coraab-time/dayjs';
125
+
126
+ dayjs.extend(coraabPlugin);
127
+
128
+ dayjs().add(1, 'tol');
129
+ dayjs().startOf('tu');
130
+ dayjs().diff(other, 'tu');
131
+ dayjs().toCoraab().toString();
132
+ dayjs.fromCoraab('54L|6|4273 Tu');
133
+ ```
134
+
135
+ With CommonJS use `dayjs.extend(require('coraab-time/dayjs'))`.
136
+
137
+ With the `timezone` plugin, extend `timezone` first and this plugin after it.
138
+ In the other order `timezone` passes a shifted wall-clock time to `startOf`, so Coraab units would be off by the timezone offset.
139
+
140
+ ## Development
141
+
142
+ ```sh
143
+ npm install
144
+ npm test
145
+ npm run typecheck
146
+ npm run build # builds dist/ and the browser bundle in public/lib/
147
+ ```
148
+
149
+ To preview the page, run `npm run build` and then `npx http-server public -c-1` (`-c-1` turns off caching, so you always see the latest files).
150
+
151
+ Publishing to npm is done by hand: bump the version in `package.json`, then run `npm publish` (it runs typecheck, tests and build first).
152
+
153
+ ## Sources
154
+
155
+ [Coraabopedia](https://coraabopedia.cz) (the official Czech wiki):
156
+
157
+ - [Tu](https://coraabopedia.cz/wiki/Tu): TU, 8 TOL names, TU 0 = start of the Excavation
158
+ - [Tol](https://coraabopedia.cz/wiki/Tol): TOL names, Oonar and Hakkar, the older "small tols"
159
+ - [Gul](https://coraabopedia.cz/wiki/Gul): 6 TU names, GUL numbering ("V 4284 Tu tak bude završen 714 Gul")
160
+ - [Un](https://coraabopedia.cz/wiki/Un), [Unt](https://coraabopedia.cz/wiki/Unt), [Om](https://coraabopedia.cz/wiki/Om): lengths of the small units
161
+ - [Den Světla](https://coraabopedia.cz/wiki/Den_Sv%C4%9Btla) (Oonar) and [Den Šera](https://coraabopedia.cz/wiki/Den_%C5%A0era) (Hakkar): 96 and 72 UN
162
+ - [Časová osa](https://coraabopedia.cz/wiki/%C4%8Casov%C3%A1_osa): timeline with dates in TU
163
+ - [Coraabia News](https://coraabopedia.cz/wiki/Coraabia_News): dated news; its image names and upload times confirm the epoch and the `L` / `H` letters
164
+
165
+ [Coraabia Wiki](https://coraabia.fandom.com/wiki/Coraabia_Wiki) (English, on Fandom):
166
+
167
+ - [Tu](https://coraabia.fandom.com/wiki/Tu), [Tol](https://coraabia.fandom.com/wiki/Tol), [Gul](https://coraabia.fandom.com/wiki/Gul),
168
+ [Un](https://coraabia.fandom.com/wiki/Un), [Unt](https://coraabia.fandom.com/wiki/Unt), [Om](https://coraabia.fandom.com/wiki/Om),
169
+ [Light Day](https://coraabia.fandom.com/wiki/Light_Day), [Haze Day](https://coraabia.fandom.com/wiki/Haze_Day)
170
+ - [Gu-Rang](https://coraabia.fandom.com/wiki/Gu-Rang): examples of the date notation (`7L|6|4270 Tu`)
171
+
172
+ The epoch (TU 0 = 1358-08-14 UTC) comes from the original version of this page.
173
+
174
+ ## Credits
175
+
176
+ Background video generated with Google Gemini. Font [Anton](https://fonts.google.com/specimen/Anton) by The Anton Project Authors, self-hosted under the SIL Open Font License (see `public/fonts/Anton-OFL.txt`).
177
+
178
+ ## License
179
+
180
+ MIT
@@ -0,0 +1,102 @@
1
+ type CoraabDay = 'oonar' | 'hakkar';
2
+ interface CoraabParts {
3
+ gul: number;
4
+ tuOfGul: number;
5
+ tu: number;
6
+ tol: number;
7
+ day: CoraabDay;
8
+ un: number;
9
+ unt: number;
10
+ om: number;
11
+ millisecond: number;
12
+ }
13
+ type CoraabPartsInput = Pick<CoraabParts, 'tu'> & Partial<Pick<CoraabParts, 'tol' | 'day' | 'un' | 'unt' | 'om' | 'millisecond'>>;
14
+ type CoraabUnit = 'gul' | 'tu' | 'tol' | 'un' | 'unt' | 'om';
15
+ type EarthUnit = 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | 'week';
16
+ type DurationUnit = CoraabUnit | EarthUnit;
17
+ type StartOfUnit = CoraabUnit | 'coraabDay';
18
+ type StartOfUnitInput = StartOfUnit | 'coraabDays' | 'guls' | 'tus' | 'tols' | 'uns' | 'unts' | 'oms';
19
+ declare const UNIT_ALIASES: {
20
+ readonly gul: "gul";
21
+ readonly guls: "gul";
22
+ readonly tu: "tu";
23
+ readonly tus: "tu";
24
+ readonly tol: "tol";
25
+ readonly tols: "tol";
26
+ readonly un: "un";
27
+ readonly uns: "un";
28
+ readonly unt: "unt";
29
+ readonly unts: "unt";
30
+ readonly om: "om";
31
+ readonly oms: "om";
32
+ readonly millisecond: "millisecond";
33
+ readonly milliseconds: "millisecond";
34
+ readonly ms: "millisecond";
35
+ readonly second: "second";
36
+ readonly seconds: "second";
37
+ readonly s: "second";
38
+ readonly minute: "minute";
39
+ readonly minutes: "minute";
40
+ readonly m: "minute";
41
+ readonly hour: "hour";
42
+ readonly hours: "hour";
43
+ readonly h: "hour";
44
+ readonly day: "day";
45
+ readonly days: "day";
46
+ readonly d: "day";
47
+ readonly week: "week";
48
+ readonly weeks: "week";
49
+ readonly w: "week";
50
+ };
51
+ type DurationUnitInput = keyof typeof UNIT_ALIASES;
52
+ declare const DEFAULT_FORMAT = "Hd|M|Y [Tu] m [Unt] s [Om]";
53
+ type CoraabInput = CoraabTime | Date | number | string | null | {
54
+ valueOf(): number;
55
+ };
56
+ type SettableUnit = CoraabUnit;
57
+ declare class CoraabTime {
58
+ #private;
59
+ constructor(input?: CoraabInput);
60
+ isValid(): boolean;
61
+ toParts(): CoraabParts;
62
+ get(unit: SettableUnit): number;
63
+ set(unit: SettableUnit, value: number): CoraabTime;
64
+ gul(): number;
65
+ gul(value: number): CoraabTime;
66
+ tu(): number;
67
+ tu(value: number): CoraabTime;
68
+ tol(): number;
69
+ tol(value: number): CoraabTime;
70
+ un(): number;
71
+ un(value: number): CoraabTime;
72
+ unt(): number;
73
+ unt(value: number): CoraabTime;
74
+ om(): number;
75
+ om(value: number): CoraabTime;
76
+ tuOfGul(): number;
77
+ coraabDay(): CoraabDay;
78
+ add(value: number, unit?: DurationUnitInput): CoraabTime;
79
+ subtract(value: number, unit?: DurationUnitInput): CoraabTime;
80
+ startOf(unit: StartOfUnitInput): CoraabTime;
81
+ endOf(unit: StartOfUnitInput): CoraabTime;
82
+ diff(other: CoraabInput, unit?: DurationUnitInput, float?: boolean): number;
83
+ isBefore(other: CoraabInput, unit?: StartOfUnitInput): boolean;
84
+ isAfter(other: CoraabInput, unit?: StartOfUnitInput): boolean;
85
+ isSame(other: CoraabInput, unit?: StartOfUnitInput): boolean;
86
+ format(template?: string): string;
87
+ clone(): CoraabTime;
88
+ valueOf(): number;
89
+ unix(): number;
90
+ toDate(): Date;
91
+ toISOString(): string;
92
+ toJSON(): string | null;
93
+ toString(): string;
94
+ }
95
+ declare function coraab(input?: CoraabInput): CoraabTime;
96
+ declare namespace coraab {
97
+ var unix: (seconds: number) => CoraabTime;
98
+ var from: (parts: CoraabPartsInput) => CoraabTime;
99
+ var isCoraab: (value: unknown) => value is CoraabTime;
100
+ }
101
+
102
+ export { CoraabTime as C, DEFAULT_FORMAT as D, type EarthUnit as E, type StartOfUnitInput as S, type CoraabInput as a, type CoraabDay as b, type CoraabParts as c, type CoraabPartsInput as d, type CoraabUnit as e, type DurationUnit as f, type DurationUnitInput as g, type StartOfUnit as h, coraab as i };
@@ -0,0 +1,102 @@
1
+ type CoraabDay = 'oonar' | 'hakkar';
2
+ interface CoraabParts {
3
+ gul: number;
4
+ tuOfGul: number;
5
+ tu: number;
6
+ tol: number;
7
+ day: CoraabDay;
8
+ un: number;
9
+ unt: number;
10
+ om: number;
11
+ millisecond: number;
12
+ }
13
+ type CoraabPartsInput = Pick<CoraabParts, 'tu'> & Partial<Pick<CoraabParts, 'tol' | 'day' | 'un' | 'unt' | 'om' | 'millisecond'>>;
14
+ type CoraabUnit = 'gul' | 'tu' | 'tol' | 'un' | 'unt' | 'om';
15
+ type EarthUnit = 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | 'week';
16
+ type DurationUnit = CoraabUnit | EarthUnit;
17
+ type StartOfUnit = CoraabUnit | 'coraabDay';
18
+ type StartOfUnitInput = StartOfUnit | 'coraabDays' | 'guls' | 'tus' | 'tols' | 'uns' | 'unts' | 'oms';
19
+ declare const UNIT_ALIASES: {
20
+ readonly gul: "gul";
21
+ readonly guls: "gul";
22
+ readonly tu: "tu";
23
+ readonly tus: "tu";
24
+ readonly tol: "tol";
25
+ readonly tols: "tol";
26
+ readonly un: "un";
27
+ readonly uns: "un";
28
+ readonly unt: "unt";
29
+ readonly unts: "unt";
30
+ readonly om: "om";
31
+ readonly oms: "om";
32
+ readonly millisecond: "millisecond";
33
+ readonly milliseconds: "millisecond";
34
+ readonly ms: "millisecond";
35
+ readonly second: "second";
36
+ readonly seconds: "second";
37
+ readonly s: "second";
38
+ readonly minute: "minute";
39
+ readonly minutes: "minute";
40
+ readonly m: "minute";
41
+ readonly hour: "hour";
42
+ readonly hours: "hour";
43
+ readonly h: "hour";
44
+ readonly day: "day";
45
+ readonly days: "day";
46
+ readonly d: "day";
47
+ readonly week: "week";
48
+ readonly weeks: "week";
49
+ readonly w: "week";
50
+ };
51
+ type DurationUnitInput = keyof typeof UNIT_ALIASES;
52
+ declare const DEFAULT_FORMAT = "Hd|M|Y [Tu] m [Unt] s [Om]";
53
+ type CoraabInput = CoraabTime | Date | number | string | null | {
54
+ valueOf(): number;
55
+ };
56
+ type SettableUnit = CoraabUnit;
57
+ declare class CoraabTime {
58
+ #private;
59
+ constructor(input?: CoraabInput);
60
+ isValid(): boolean;
61
+ toParts(): CoraabParts;
62
+ get(unit: SettableUnit): number;
63
+ set(unit: SettableUnit, value: number): CoraabTime;
64
+ gul(): number;
65
+ gul(value: number): CoraabTime;
66
+ tu(): number;
67
+ tu(value: number): CoraabTime;
68
+ tol(): number;
69
+ tol(value: number): CoraabTime;
70
+ un(): number;
71
+ un(value: number): CoraabTime;
72
+ unt(): number;
73
+ unt(value: number): CoraabTime;
74
+ om(): number;
75
+ om(value: number): CoraabTime;
76
+ tuOfGul(): number;
77
+ coraabDay(): CoraabDay;
78
+ add(value: number, unit?: DurationUnitInput): CoraabTime;
79
+ subtract(value: number, unit?: DurationUnitInput): CoraabTime;
80
+ startOf(unit: StartOfUnitInput): CoraabTime;
81
+ endOf(unit: StartOfUnitInput): CoraabTime;
82
+ diff(other: CoraabInput, unit?: DurationUnitInput, float?: boolean): number;
83
+ isBefore(other: CoraabInput, unit?: StartOfUnitInput): boolean;
84
+ isAfter(other: CoraabInput, unit?: StartOfUnitInput): boolean;
85
+ isSame(other: CoraabInput, unit?: StartOfUnitInput): boolean;
86
+ format(template?: string): string;
87
+ clone(): CoraabTime;
88
+ valueOf(): number;
89
+ unix(): number;
90
+ toDate(): Date;
91
+ toISOString(): string;
92
+ toJSON(): string | null;
93
+ toString(): string;
94
+ }
95
+ declare function coraab(input?: CoraabInput): CoraabTime;
96
+ declare namespace coraab {
97
+ var unix: (seconds: number) => CoraabTime;
98
+ var from: (parts: CoraabPartsInput) => CoraabTime;
99
+ var isCoraab: (value: unknown) => value is CoraabTime;
100
+ }
101
+
102
+ export { CoraabTime as C, DEFAULT_FORMAT as D, type EarthUnit as E, type StartOfUnitInput as S, type CoraabInput as a, type CoraabDay as b, type CoraabParts as c, type CoraabPartsInput as d, type CoraabUnit as e, type DurationUnit as f, type DurationUnitInput as g, type StartOfUnit as h, coraab as i };