@thyrith/momentkh 3.0.0 โ†’ 3.0.2

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
@@ -2,7 +2,9 @@
2
2
 
3
3
  **MomentKH** is a lightweight, zero-dependency JavaScript/TypeScript library for accurate Khmer (Cambodian) Lunar Calendar conversions. It provides a modern, standalone implementation with full TypeScript support.
4
4
 
5
- [![Version](https://img.shields.io/badge/version-3.0.0-blue.svg)](https://github.com/ThyrithSor/momentkh)
5
+ [๐ŸŽฎ **Live Demo Playground**](https://thyrithsor.github.io/momentkh/)
6
+
7
+ [![Version](https://img.shields.io/badge/version-3.0.2-blue.svg)](https://github.com/ThyrithSor/momentkh)
6
8
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
7
9
  [![No Dependencies](https://img.shields.io/badge/dependencies-none-success.svg)](https://github.com/ThyrithSor/momentkh)
8
10
 
@@ -17,11 +19,11 @@ const momentkh = require("@thyrith/momentkh");
17
19
  // Convert date to Khmer format (default)
18
20
  const khmer = momentkh.fromDate(new Date());
19
21
  console.log(momentkh.format(khmer));
20
- // Output: แžแŸ’แž„แŸƒแž…แž“แŸ’แž‘ แŸกแŸฆแžšแŸ„แž… แžแŸ‚แž˜แžทแž‚แžŸแžทแžš แž†แŸ’แž“แžถแŸ†แžšแŸ„แž„ แž†แžŸแŸแž€ แž–แžปแž‘แŸ’แž’แžŸแž€แžšแžถแž‡ แŸขแŸฅแŸฆแŸจ
22
+ // Output: แžแŸ’แž„แŸƒแž–แžปแž’ แŸกแŸขแžšแŸ„แž… แžแŸ‚แž˜แžทแž‚แžŸแžทแžš แž†แŸ’แž“แžถแŸ†แž˜แŸ’แžŸแžถแž‰แŸ‹ แžŸแž”แŸ’แžแžŸแŸแž€ แž–แžปแž‘แŸ’แž’แžŸแž€แžšแžถแž‡ แŸขแŸฅแŸฆแŸฉ
21
23
 
22
24
  // Convert date to Khmer format (custom)
23
25
  console.log(momentkh.format(khmer, "dN แžแŸ‚m แž†แŸ’แž“แžถแŸ†a"));
24
- // Output: แŸกแŸฆแžšแŸ„แž… แžแŸ‚แž˜แžทแž‚แžŸแžทแžš แž†แŸ’แž“แžถแŸ†แžšแŸ„แž„
26
+ // Output: แŸกแŸขแžšแŸ„แž… แžแŸ‚แž˜แžทแž‚แžŸแžทแžš แž†แŸ’แž“แžถแŸ†แž˜แŸ’แžŸแžถแž‰แŸ‹
25
27
 
26
28
  // Convert Khmer date to Gregorian
27
29
  const gregorian = momentkh.fromKhmer(15, 0, 5, 2568); // 15แž€แžพแž แžแŸ‚แž–แžทแžŸแžถแž แž–.แžŸ.แŸขแŸฅแŸฆแŸจ
@@ -31,7 +33,7 @@ console.log(gregorian);
31
33
  // Get Khmer New Year
32
34
  const newYear = momentkh.getNewYear(2025);
33
35
  console.log(newYear);
34
- // Output: { year: 2025, month: 4, day: 13, hour: 20, minute: 9 }
36
+ // Output: { year: 2025, month: 4, day: 14, hour: 4, minute: 48 }
35
37
  ```
36
38
 
37
39
  ---
@@ -52,7 +54,7 @@ console.log(newYear);
52
54
  - [Understanding Khmer Calendar](#-understanding-khmer-calendar)
53
55
  - [Buddhist Era (BE) Year](#buddhist-era-be-year)
54
56
  - [Animal Year](#animal-year)
55
- - [Era Year (Sak)](#era-year-sak)
57
+ - [Sak](#sak-year-sak)
56
58
  - [When Each Year Type Increases](#when-each-year-type-increases)
57
59
  - [Format Codes](#-format-codes)
58
60
  - [Constants](#-constants)
@@ -66,7 +68,7 @@ console.log(newYear);
66
68
 
67
69
  - โœ… **Zero Dependencies** - Pure JavaScript, no external libraries required
68
70
  - โœ… **TypeScript Support** - Full type definitions included for excellent IDE experience
69
- - โœ… **Type-Safe Enums** - NEW in v3.0! Use enums for moonPhase, monthIndex, animalYear, eraYear, and dayOfWeek
71
+ - โœ… **Type-Safe Enums** - NEW in v3.0! Use enums for moonPhase, monthIndex, animalYear, sak, and dayOfWeek
70
72
  - โœ… **Bidirectional Conversion** - Convert between Gregorian โ†” Khmer Lunar dates
71
73
  - โœ… **Accurate Calculations** - Based on traditional Khmer astronomical algorithms
72
74
  - โœ… **Khmer New Year** - Precise calculation of Moha Songkran timing
@@ -85,14 +87,6 @@ console.log(newYear);
85
87
  npm install @thyrith/momentkh
86
88
  ```
87
89
 
88
- ### Direct Download
89
-
90
- Download `momentkh.js` from the repository and include it in your project.
91
-
92
- ```bash
93
- cp momentkh.js /path/to/your/project/
94
- ```
95
-
96
90
  ### TypeScript
97
91
 
98
92
  Type definitions are included automatically when you install via NPM. For direct downloads, you can also use `momentkh.ts` or the compiled `.d.ts` files from the `dist/` folder.
@@ -104,19 +98,23 @@ Type definitions are included automatically when you install via NPM. For direct
104
98
  ### Browser (HTML)
105
99
 
106
100
  ```html
107
- <script src="momentkh.js"></script>
101
+ <!-- Include the browser-compatible UMD bundle -->
102
+ <script src="https://cdn.jsdelivr.net/gh/ThyrithSor/momentkh@3.0.2/momentkh.js"></script>
108
103
  <script>
109
104
  // Convert today to Khmer
110
105
  const today = new Date();
111
106
  const khmer = momentkh.fromDate(today);
112
107
  console.log(momentkh.format(khmer));
113
- // Output: แžแŸ’แž„แŸƒแž…แž“แŸ’แž‘ แŸกแŸ แž€แžพแž แžแŸ‚แž…แŸแžแŸ’แžš แž†แŸ’แž“แžถแŸ†แžšแŸ„แž„ แž†แžŸแŸแž€ แž–แžปแž‘แŸ’แž’แžŸแž€แžšแžถแž‡ แŸขแŸฅแŸฆแŸง
108
+ // Output: แžแŸ’แž„แŸƒแž–แžปแž’ แŸกแŸขแžšแŸ„แž… แžแŸ‚แž˜แžทแž‚แžŸแžทแžš แž†แŸ’แž“แžถแŸ†แž˜แŸ’แžŸแžถแž‰แŸ‹ แžŸแž”แŸ’แžแžŸแŸแž€ แž–แžปแž‘แŸ’แž’แžŸแž€แžšแžถแž‡ แŸขแŸฅแŸฆแŸฉ
114
109
  </script>
115
110
  ```
116
111
 
112
+ > **Note:** Use `momentkh.js` (UMD bundle) for browsers. The `dist/momentkh.js` is CommonJS format for Node.js.
113
+
117
114
  ### Node.js (CommonJS)
118
115
 
119
116
  ```javascript
117
+ // Use the CommonJS module from dist/
120
118
  const momentkh = require("@thyrith/momentkh");
121
119
 
122
120
  // Convert specific date
@@ -125,7 +123,7 @@ console.log(momentkh.format(khmer));
125
123
 
126
124
  // Get Khmer New Year
127
125
  const newYear = momentkh.getNewYear(2024);
128
- console.log(newYear); // { year: 2024, month: 4, day: 13, hour: 22, minute: 24 }
126
+ console.log(newYear); // { year: 2024, month: 4, day: 13, hour: 22, minute: 17 }
129
127
  ```
130
128
 
131
129
  ### ES Modules
@@ -149,7 +147,7 @@ import momentkh, {
149
147
  MoonPhase,
150
148
  MonthIndex,
151
149
  AnimalYear,
152
- EraYear,
150
+ Sak,
153
151
  DayOfWeek,
154
152
  } from "@thyrith/momentkh";
155
153
 
@@ -165,14 +163,14 @@ console.log(momentkh.format(khmer));
165
163
 
166
164
  // Access enum values (NEW in v3.0!)
167
165
  console.log(khmer.khmer.moonPhase === MoonPhase.Waxing); // Type-safe comparison
168
- console.log(khmer.khmer.monthIndex === MonthIndex.Chetr); // Enum comparison
166
+ console.log(khmer.khmer.monthIndex === MonthIndex.Cheit); // Enum comparison
169
167
  console.log(khmer.khmer.dayOfWeek === DayOfWeek.Sunday); // Autocomplete support!
170
168
 
171
169
  // Reverse conversion with enums (type-safe!)
172
170
  const gregorianDate: GregorianDate = momentkh.fromKhmer(
173
171
  15,
174
172
  MoonPhase.Waxing, // Use enum instead of 0
175
- MonthIndex.Visakh, // Use enum instead of 5
173
+ MonthIndex.Pisakh, // Use enum instead of 5
176
174
  2568
177
175
  );
178
176
  console.log(
@@ -205,7 +203,7 @@ const monthName = momentkh.constants.LunarMonthNames[4]; // "แž…แŸแžแŸ’แžš"
205
203
  - ๐ŸŒ™ `MoonPhase` - Waxing (แž€แžพแž) and Waning (แžšแŸ„แž…)
206
204
  - ๐Ÿ“… `MonthIndex` - All 14 Khmer lunar months
207
205
  - ๐Ÿ‰ `AnimalYear` - All 12 animal years
208
- - โญ `EraYear` - All 10 era years
206
+ - โญ `Sak` - All 10 Saks
209
207
  - ๐Ÿ“† `DayOfWeek` - Sunday through Saturday
210
208
 
211
209
  ---
@@ -249,8 +247,8 @@ Converts a Gregorian (Western) date to a Khmer Lunar date.
249
247
  jsYear: 1386, // Number: Jolak Sakaraj (Chula Sakaraj) year
250
248
  animalYear: 4, // AnimalYear enum: 0-11 (NEW in v3.0)
251
249
  animalYearName: 'แžšแŸ„แž„', // String: Animal year name
252
- eraYear: 6, // EraYear enum: 0-9 (NEW in v3.0)
253
- eraYearName: 'แž†แžŸแŸแž€', // String: Era/Sak name
250
+ sak: 6, // Sak enum: 0-9 (NEW in v3.0)
251
+ sakName: 'แž†แžŸแŸแž€', // String: Sak name
254
252
  dayOfWeek: 0, // DayOfWeek enum: 0=Sunday, 6=Saturday (NEW in v3.0)
255
253
  dayOfWeekName: 'แžขแžถแž‘แžทแžแŸ’แž™' // String: Khmer weekday name
256
254
  },
@@ -267,9 +265,9 @@ Converts a Gregorian (Western) date to a Khmer Lunar date.
267
265
 
268
266
  ```javascript
269
267
  const result = momentkh.fromGregorian(2024, 4, 14);
270
- console.log(result.khmer.beYear); // 2568
268
+ console.log(result.khmer.beYear); // 2567
271
269
  console.log(result.khmer.monthName); // 'แž…แŸแžแŸ’แžš'
272
- console.log(result.khmer.animalYear); // 'แžšแŸ„แž„'
270
+ console.log(result.khmer.animalYear); // 4 (แžšแŸ„แž„)
273
271
  ```
274
272
 
275
273
  ---
@@ -319,14 +317,14 @@ Converts a Khmer Lunar date to a Gregorian date.
319
317
  ```javascript
320
318
  // Using numbers (backward compatible)
321
319
  const gregorian1 = momentkh.fromKhmer(6, 0, 4, 2568);
322
- console.log(gregorian1); // { year: 2024, month: 4, day: 14 }
320
+ console.log(gregorian1); // { year: 2025, month: 4, day: 3 }
323
321
 
324
322
  // Using enums (NEW in v3.0 - type-safe!)
325
323
  const { MoonPhase, MonthIndex } = momentkh;
326
324
  const gregorian2 = momentkh.fromKhmer(
327
325
  6,
328
326
  MoonPhase.Waxing,
329
- MonthIndex.Chetr,
327
+ MonthIndex.Cheit,
330
328
  2568
331
329
  );
332
330
  console.log(gregorian2); // { year: 2024, month: 4, day: 14 }
@@ -415,7 +413,7 @@ console.log(
415
413
  ny2024.hour
416
414
  }:${String(ny2024.minute).padStart(2, "0")}`
417
415
  );
418
- // Output: Khmer New Year 2024: 13/4/2024 at 22:24
416
+ // Output: Khmer New Year 2024: 13/4/2024 at 22:17
419
417
 
420
418
  // Loop through multiple years
421
419
  for (let year = 2020; year <= 2025; year++) {
@@ -444,9 +442,14 @@ Formats a Khmer date object into a string with optional custom formatting.
444
442
  **Default Format:**
445
443
 
446
444
  ```
447
- แžแŸ’แž„แŸƒ{weekday} {day}{moonPhase} แžแŸ‚{month} แž†แŸ’แž“แžถแŸ†{animalYear} {eraYear} แž–แžปแž‘แŸ’แž’แžŸแž€แžšแžถแž‡ {beYear}
445
+ แžแŸ’แž„แŸƒ{weekday} {day}{moonPhase} แžแŸ‚{month} แž†แŸ’แž“แžถแŸ†{animalYear} {sak} แž–แžปแž‘แŸ’แž’แžŸแž€แžšแžถแž‡ {beYear}
448
446
  ```
449
447
 
448
+ **Escaping Characters:**
449
+ To escape characters in the format string (so they are not interpreted as format codes), wrap them in square brackets `[]`.
450
+
451
+ Example: `[Week] w` -> "Week แžขแžถ"
452
+
450
453
  **Returns:** String (formatted Khmer date)
451
454
 
452
455
  **Example:**
@@ -467,6 +470,10 @@ console.log(momentkh.format(khmer, "c/M/D"));
467
470
 
468
471
  console.log(momentkh.format(khmer, "แžแŸ’แž„แŸƒw dN m แž†แŸ’แž“แžถแŸ†a e แž–.แžŸ.b"));
469
472
  // แžแŸ’แž„แŸƒแžขแžถ แŸฆแž€แžพแž แž…แŸแžแŸ’แžš แž†แŸ’แž“แžถแŸ†แžšแŸ„แž„ แž†แžŸแŸแž€ แž–.แžŸ.แŸขแŸฅแŸฆแŸจ
473
+
474
+ // Escaping characters (use brackets [])
475
+ console.log(momentkh.format(khmer, "[Day:] d [Month:] m"));
476
+ // Day: แŸฆ Month: แž…แŸแžแŸ’แžš
470
477
  ```
471
478
 
472
479
  ---
@@ -495,20 +502,20 @@ All 14 Khmer lunar months (including leap months).
495
502
  ```javascript
496
503
  const { MonthIndex } = momentkh;
497
504
 
498
- MonthIndex.Mikasar; // 0 - แž˜แžทแž‚แžŸแžทแžš
505
+ MonthIndex.Migasir; // 0 - แž˜แžทแž‚แžŸแžทแžš
499
506
  MonthIndex.Bos; // 1 - แž”แžปแžŸแŸ’แžŸ
500
507
  MonthIndex.Meak; // 2 - แž˜แžถแžƒ
501
- MonthIndex.Phalgun; // 3 - แž•แž›แŸ’แž‚แžปแž“
502
- MonthIndex.Chetr; // 4 - แž…แŸแžแŸ’แžš
503
- MonthIndex.Visakh; // 5 - แž–แžทแžŸแžถแž
508
+ MonthIndex.Phalkun; // 3 - แž•แž›แŸ’แž‚แžปแž“
509
+ MonthIndex.Cheit; // 4 - แž…แŸแžแŸ’แžš
510
+ MonthIndex.Pisakh; // 5 - แž–แžทแžŸแžถแž
504
511
  MonthIndex.Jesth; // 6 - แž‡แŸแžŸแŸ’แž‹
505
- MonthIndex.Asath; // 7 - แžขแžถแžŸแžถแž
512
+ MonthIndex.Asadh; // 7 - แžขแžถแžŸแžถแž
506
513
  MonthIndex.Srap; // 8 - แžŸแŸ’แžšแžถแž–แžŽแŸ
507
- MonthIndex.Photrobot; // 9 - แž—แž‘แŸ’แžšแž”แž‘
514
+ MonthIndex.Phatrabot; // 9 - แž—แž‘แŸ’แžšแž”แž‘
508
515
  MonthIndex.Assoch; // 10 - แžขแžŸแŸ’แžŸแžปแž‡
509
- MonthIndex.Kadek; // 11 - แž€แžแŸ’แžŠแžทแž€
510
- MonthIndex.BothmakAsath; // 12 - แž”แž‹แž˜แžถแžŸแžถแž (leap month only)
511
- MonthIndex.TutiyakAsath; // 13 - แž‘แžปแžแžทแž™แžถแžŸแžถแž (leap month only)
516
+ MonthIndex.Kadeuk; // 11 - แž€แžแŸ’แžŠแžทแž€
517
+ MonthIndex.Pathamasadh; // 12 - แž”แž‹แž˜แžถแžŸแžถแž (leap month only)
518
+ MonthIndex.Tutiyasadh; // 13 - แž‘แžปแžแžทแž™แžถแžŸแžถแž (leap month only)
512
519
  ```
513
520
 
514
521
  #### ๐Ÿ‰ AnimalYear
@@ -532,23 +539,23 @@ AnimalYear.Cho; // 10 - ๐Ÿ• แž… (Dog)
532
539
  AnimalYear.Kor; // 11 - ๐Ÿ– แž€แžปแžš (Pig)
533
540
  ```
534
541
 
535
- #### โญ EraYear
542
+ #### โญ Sak
536
543
 
537
- The 10 era years (แžŸแŸแž€) cycle.
544
+ The 10 Saks (แžŸแŸแž€) cycle.
538
545
 
539
546
  ```javascript
540
- const { EraYear } = momentkh;
541
-
542
- EraYear.Samridhisak; // 0 - ๐Ÿ”Ÿ แžŸแŸ†แžšแžนแž‘แŸ’แž’แžทแžŸแŸแž€
543
- EraYear.Ekasak; // 1 - 1๏ธโƒฃ แžฏแž€แžŸแŸแž€
544
- EraYear.Tosak; // 2 - 2๏ธโƒฃ แž‘แŸ„แžŸแŸแž€
545
- EraYear.Tresak; // 3 - 3๏ธโƒฃ แžแŸ’แžšแžธแžŸแŸแž€
546
- EraYear.Chatvasak; // 4 - 4๏ธโƒฃ แž…แžแŸ’แžœแžถแžŸแŸแž€
547
- EraYear.Panchasak; // 5 - 5๏ธโƒฃ แž”แž‰แŸ’แž…แžŸแŸแž€
548
- EraYear.Chhasak; // 6 - 6๏ธโƒฃ แž†แžŸแŸแž€
549
- EraYear.Saptasak; // 7 - 7๏ธโƒฃ แžŸแž”แŸ’แžแžŸแŸแž€
550
- EraYear.Atthasak; // 8 - 8๏ธโƒฃ แžขแžŠแŸ’แž‹แžŸแŸแž€
551
- EraYear.Novvasak; // 9 - 9๏ธโƒฃ แž“แž–แŸ’แžœแžŸแŸแž€
547
+ const { Sak } = momentkh;
548
+
549
+ Sak.SamridhiSak; // 0 - ๐Ÿ”Ÿ แžŸแŸ†แžšแžนแž‘แŸ’แž’แžทแžŸแŸแž€
550
+ Sak.AekSak; // 1 - 1๏ธโƒฃ แžฏแž€แžŸแŸแž€
551
+ Sak.ToSak; // 2 - 2๏ธโƒฃ แž‘แŸ„แžŸแŸแž€
552
+ Sak.TreiSak; // 3 - 3๏ธโƒฃ แžแŸ’แžšแžธแžŸแŸแž€
553
+ Sak.ChattvaSak; // 4 - 4๏ธโƒฃ แž…แžแŸ’แžœแžถแžŸแŸแž€
554
+ Sak.PanchaSak; // 5 - 5๏ธโƒฃ แž”แž‰แŸ’แž…แžŸแŸแž€
555
+ Sak.ChhaSak; // 6 - 6๏ธโƒฃ แž†แžŸแŸแž€
556
+ Sak.SappaSak; // 7 - 7๏ธโƒฃ แžŸแž”แŸ’แžแžŸแŸแž€
557
+ Sak.AtthaSak; // 8 - 8๏ธโƒฃ แžขแžŠแŸ’แž‹แžŸแŸแž€
558
+ Sak.NappaSak; // 9 - 9๏ธโƒฃ แž“แž–แŸ’แžœแžŸแŸแž€
552
559
  ```
553
560
 
554
561
  #### ๐Ÿ“† DayOfWeek
@@ -583,8 +590,8 @@ if (khmer.khmer.moonPhase === MoonPhase.Waxing) {
583
590
  }
584
591
 
585
592
  // Check specific month
586
- if (khmer.khmer.monthIndex === MonthIndex.Mikasar) {
587
- console.log("It is Mikasar month!");
593
+ if (khmer.khmer.monthIndex === MonthIndex.Migasir) {
594
+ console.log("It is Migasir month!");
588
595
  }
589
596
 
590
597
  // Check day of week
@@ -602,7 +609,7 @@ const { MoonPhase, MonthIndex } = momentkh;
602
609
  const date1 = momentkh.fromKhmer(
603
610
  15, // day
604
611
  MoonPhase.Waxing, // instead of 0
605
- MonthIndex.Visakh, // instead of 5
612
+ MonthIndex.Pisakh, // instead of 5
606
613
  2568
607
614
  );
608
615
 
@@ -622,14 +629,14 @@ const khmer = momentkh.fromGregorian(2024, 12, 16);
622
629
 
623
630
  // Switch on month
624
631
  switch (khmer.khmer.monthIndex) {
625
- case MonthIndex.Mikasar:
632
+ case MonthIndex.Migasir:
626
633
  case MonthIndex.Bos:
627
634
  case MonthIndex.Meak:
628
635
  console.log("Winter months");
629
636
  break;
630
- case MonthIndex.Phalgun:
631
- case MonthIndex.Chetr:
632
- case MonthIndex.Visakh:
637
+ case MonthIndex.Phalkun:
638
+ case MonthIndex.Cheit:
639
+ case MonthIndex.Pisakh:
633
640
  console.log("Spring months");
634
641
  break;
635
642
  // ... more cases
@@ -666,14 +673,14 @@ const month: MonthIndex = result.khmer.monthIndex;
666
673
  const date = momentkh.fromKhmer(
667
674
  15,
668
675
  MoonPhase. // โ† IDE shows: Waxing, Waning
669
- MonthIndex. // โ† IDE shows: Mikasar, Bos, Meak, etc.
676
+ MonthIndex. // โ† IDE shows: Migasir, Bos, Meak, etc.
670
677
  2568
671
678
  );
672
679
  ```
673
680
 
674
681
  ### Benefits of Using Enums
675
682
 
676
- 1. ๐Ÿ“– **Readability**: `MonthIndex.Visakh` is clearer than `5`
683
+ 1. ๐Ÿ“– **Readability**: `MonthIndex.Pisakh` is clearer than `5`
677
684
  2. ๐Ÿ›ก๏ธ **Type Safety**: TypeScript catches invalid values at compile time
678
685
  3. โšก **Autocomplete**: IDEs show all available options
679
686
  4. ๐Ÿ”ง **Maintainability**: Easier to understand code months later
@@ -686,8 +693,8 @@ const date = momentkh.fromKhmer(
686
693
 
687
694
  ```javascript
688
695
  // All of these work:
689
- momentkh.fromKhmer(15, MoonPhase.Waxing, MonthIndex.Visakh, 2568); // โœจ New enum way
690
- momentkh.fromKhmer(15, 0, MonthIndex.Visakh, 2568); // ๐Ÿ”€ Mixed
696
+ momentkh.fromKhmer(15, MoonPhase.Waxing, MonthIndex.Pisakh, 2568); // โœจ New enum way
697
+ momentkh.fromKhmer(15, 0, MonthIndex.Pisakh, 2568); // ๐Ÿ”€ Mixed
691
698
  momentkh.fromKhmer(15, MoonPhase.Waxing, 5, 2568); // ๐Ÿ”€ Mixed
692
699
  momentkh.fromKhmer(15, 0, 5, 2568); // ๐Ÿ‘ Old way still works!
693
700
  ```
@@ -704,15 +711,15 @@ The Khmer calendar is a **lunisolar calendar** that tracks both the moon phases
704
711
 
705
712
  **Full Name:** แž–แžปแž‘แŸ’แž’แžŸแž€แžšแžถแž‡ (Putthsak, Buddhist Era)
706
713
  **Offset from Gregorian:** +543 or +544
707
- **When it increases:** At midnight (00:00) on the **15th waxing day of Pisakh month** (แŸกแŸฅแž€แžพแž แžแŸ‚แž–แžทแžŸแžถแž)
714
+ **When it increases:** At midnight (00:00) on the **1st waning day of Pisakh month** (แŸกแžšแŸ„แž… แžแŸ‚แž–แžทแžŸแžถแž)
708
715
 
709
716
  **Example Timeline:**
710
717
 
711
718
  ```
712
- 2024-05-22 23:59 โ†’ 14แž€แžพแž Pisakh, BE 2567
713
- 2024-05-23 00:00 โ†’ 15แž€แžพแž Pisakh, BE 2568 (NEW year starts!)
714
- 2024-05-23 23:59 โ†’ 15แž€แžพแž Pisakh, BE 2568
715
- 2024-05-24 00:00 โ†’ 1แžšแŸ„แž… Pisakh, BE 2568
719
+ 2024-05-22 23:59 โ†’ 15แž€แžพแž Pisakh, BE 2567
720
+ 2024-05-23 00:00 โ†’ 1แžšแŸ„แž… Pisakh, BE 2568 (NEW year starts!)
721
+ 2024-05-23 23:59 โ†’ 1แžšแŸ„แž… Pisakh, BE 2568
722
+ 2024-05-24 00:00 โ†’ 2แžšแŸ„แž… Pisakh, BE 2568
716
723
  ```
717
724
 
718
725
  **Important:**
@@ -781,13 +788,13 @@ console.log(at.khmer.animalYear); // 'แžšแž€แžถ' (Rooster) - Changed!
781
788
 
782
789
  ---
783
790
 
784
- ### Era Year (Sak)
791
+ ### Sak
785
792
 
786
793
  **Full Name:** แžŸแŸแž€ (Sak, Era)
787
794
  **Cycle:** 10 years
788
795
  **When it increases:** At **midnight (00:00) of the last day** of Khmer New Year celebration (Lerng Sak - แžแŸ’แž„แŸƒแžกแžพแž„แžŸแŸแž€)
789
796
 
790
- **The 10 Eras (in order):**
797
+ **The 10 Saks (in order):**
791
798
  | Index | Khmer | Romanization |
792
799
  |-------|-------|--------------|
793
800
  | 0 | แžŸแŸ†แžšแžนแž‘แŸ’แž’แžทแžŸแŸแž€ | Samridhi Sak |
@@ -805,19 +812,19 @@ console.log(at.khmer.animalYear); // 'แžšแž€แžถ' (Rooster) - Changed!
805
812
 
806
813
  - ๐ŸŽ‰ **Day 1:** Moha Songkran (แž˜แž แžถแžŸแž„แŸ’แžšแŸ’แž€แžถแž“แŸ’แž) - New Year's Day
807
814
  - ๐ŸŽŠ **Day 2:** Virak Wanabat (แžœแžธแžšแŸˆแžœแŸแž“แž”แž) - Second day
808
- - โญ **Day 3 or 4:** Lerng Sak (แžแŸ’แž„แŸƒแžกแžพแž„แžŸแŸแž€) - Last day & Era change day
815
+ - โญ **Day 3 or 4:** Lerng Sak (แžแŸ’แž„แŸƒแžกแžพแž„แžŸแŸแž€) - Last day & Sak change day
809
816
 
810
817
  **Example:**
811
818
 
812
819
  ```javascript
813
820
  // 2024 New Year is on April 13, 22:24
814
- // Lerng Sak (Era change) is typically 3-4 days later at midnight
821
+ // Lerng Sak (Sak change) is typically 3-4 days later at midnight
815
822
 
816
823
  const newYearDay = momentkh.fromGregorian(2024, 4, 13, 23, 0);
817
- console.log(newYearDay.khmer.eraYear); // 'แž†แžŸแŸแž€' (still old era)
824
+ console.log(newYearDay.khmer.sak); // 'แž†แžŸแŸแž€' (still old sak)
818
825
 
819
826
  const lerngSakDay = momentkh.fromGregorian(2024, 4, 17, 0, 0); // Midnight of Lerng Sak
820
- console.log(lerngSakDay.khmer.eraYear); // 'แžŸแž”แŸ’แžแžŸแŸแž€' (new era!)
827
+ console.log(lerngSakDay.khmer.sak); // 'แžŸแž”แŸ’แžแžŸแŸแž€' (new sak!)
821
828
  ```
822
829
 
823
830
  ---
@@ -826,20 +833,20 @@ console.log(lerngSakDay.khmer.eraYear); // 'แžŸแž”แŸ’แžแžŸแŸแž€' (new era!)
826
833
 
827
834
  **Summary Table:**
828
835
 
829
- | Year Type | Changes At | Example Date/Time |
830
- | --------------- | ---------------------- | -------------------- |
831
- | **BE Year** | 00:00 on แŸกแŸฅแž€แžพแž แžแŸ‚แž–แžทแžŸแžถแž | May 23, 2024 00:00 |
832
- | **Animal Year** | แž˜แŸ‰แŸ„แž„ แž“แžทแž„ แž“แžถแž‘แžธแž‘แŸแžœแžแžถแž…แžปแŸ‡ | April 13, 2024 22:17 |
833
- | **Era Year** | 00:00 แž“แŸ…แžแŸ’แž„แŸƒแžกแžพแž„แžŸแŸแž€ | April 16, 2024 00:00 |
836
+ | Year Type | Changes At | Example Date/Time |
837
+ | --------------- | ------------------------ | -------------------- |
838
+ | **BE Year** | 00:00 แž“แŸ…แžแŸ’แž„แŸƒแŸกแžšแŸ„แž… แžแŸ‚แž–แžทแžŸแžถแž | May 23, 2024 00:00 |
839
+ | **Animal Year** | แž˜แŸ‰แŸ„แž„ แž“แžทแž„ แž“แžถแž‘แžธแž‘แŸแžœแžแžถแž…แžปแŸ‡ | April 13, 2024 22:17 |
840
+ | **Sak** | 00:00 แž“แŸ…แžแŸ’แž„แŸƒแžกแžพแž„แžŸแŸแž€ | April 16, 2024 00:00 |
834
841
 
835
842
  **Visual Timeline for 2024:**
836
843
 
837
844
  ```
838
- April 13, 22:23 โ†’ BE 2567, Monkey (แžœแž€), Old Era (แž†แžŸแŸแž€)
839
- April 13, 22:24 โ†’ BE 2567, Rooster (แžšแž€แžถ), Old Era (แž†แžŸแŸแž€) โ† Animal Year changes
840
- April 17, 00:00 โ†’ BE 2567, Rooster (แžšแž€แžถ), New Era (แžŸแž”แŸ’แžแžŸแŸแž€) โ† Era changes
841
- May 22, 23:59 โ†’ BE 2567, Rooster (แžšแž€แžถ), New Era (แžŸแž”แŸ’แžแžŸแŸแž€)
842
- May 23, 00:00 โ†’ BE 2568, Rooster (แžšแž€แžถ), New Era (แžŸแž”แŸ’แžแžŸแŸแž€) โ† BE Year changes
845
+ April 13, 22:23 โ†’ BE 2567, Monkey (แžœแž€), Old Sak (แž†แžŸแŸแž€)
846
+ April 13, 22:24 โ†’ BE 2567, Rooster (แžšแž€แžถ), Old Sak (แž†แžŸแŸแž€) โ† Animal Year changes
847
+ April 17, 00:00 โ†’ BE 2567, Rooster (แžšแž€แžถ), New Sak (แžŸแž”แŸ’แžแžŸแŸแž€) โ† Sak changes
848
+ May 22, 23:59 โ†’ BE 2567, Rooster (แžšแž€แžถ), New Sak (แžŸแž”แŸ’แžแžŸแŸแž€)
849
+ May 23, 00:00 โ†’ BE 2568, Rooster (แžšแž€แžถ), New Sak (แžŸแž”แŸ’แžแžŸแŸแž€) โ† BE Year changes
843
850
  ```
844
851
 
845
852
  ---
@@ -848,26 +855,39 @@ May 23, 00:00 โ†’ BE 2568, Rooster (แžšแž€แžถ), New Era (แžŸแž”แŸ’แžแžŸแŸแž€
848
855
 
849
856
  Complete list of format tokens for the `format()` function:
850
857
 
851
- | Token | Output | Description | Example |
852
- | ---------------------- | ----------------- | --------------------------- | --------------------- |
858
+ | Token | Output | Description | Example |
859
+ | ---------------------- | ----------------- | ------------------------------ | --------------------- |
853
860
  | **๐Ÿ“… Date Components** |
854
- | `W` | แžแŸ’แž„แŸƒแž“แŸƒแžŸแž”แŸ’แžแžถแž แŸแž–แŸแž‰ | Weekday name (full) | แžขแžถแž‘แžทแžแŸ’แž™, แž…แž“แŸ’แž‘, แžขแž„แŸ’แž‚แžถแžš |
855
- | `w` | แžแŸ’แž„แŸƒแž“แŸƒแžŸแž”แŸ’แžแžถแž แŸแžแŸ’แž›แžธ | Weekday name (short) | แžขแžถ, แž…, แžข |
856
- | `d` | แžแŸ’แž„แŸƒแž‘แžธ | Lunar day number | แŸก, แŸฅ, แŸกแŸฅ |
857
- | `D` | แžแŸ’แž„แŸƒแž‘แžธ (แŸขแžแŸ’แž‘แž„แŸ‹) | Lunar day (zero-padded) | แŸ แŸก, แŸ แŸฅ, แŸกแŸฅ |
861
+ | `W` | แžแŸ’แž„แŸƒแž“แŸƒแžŸแž”แŸ’แžแžถแž แŸแž–แŸแž‰ | Weekday name (full) | แžขแžถแž‘แžทแžแŸ’แž™, แž…แž“แŸ’แž‘, แžขแž„แŸ’แž‚แžถแžš |
862
+ | `w` | แžแŸ’แž„แŸƒแž“แŸƒแžŸแž”แŸ’แžแžถแž แŸแžแŸ’แž›แžธ | Weekday name (short) | แžขแžถ, แž…, แžข |
863
+ | `d` | แžแŸ’แž„แŸƒแž‘แžธ | Lunar day number | แŸก, แŸฅ, แŸกแŸฅ |
864
+ | `D` | แžแŸ’แž„แŸƒแž‘แžธ (แŸขแžแŸ’แž‘แž„แŸ‹) | Lunar day (zero-padded) | แŸ แŸก, แŸ แŸฅ, แŸกแŸฅ |
858
865
  | **๐ŸŒ™ Moon Phase** |
859
- | `n` | แž€แžพแž/แžšแŸ„แž… (แžแŸ’แž›แžธ) | Moon phase (short) | แž€, แžš |
860
- | `N` | แž€แžพแž/แžšแŸ„แž… (แž–แŸแž‰) | Moon phase (full) | แž€แžพแž, แžšแŸ„แž… |
861
- | `o` | แž“แžทแž˜แžทแžแŸ’แžแžŸแž‰แŸ’แž‰แžถ | Moon day symbol | แงก, แงข, แงฃ ... แงฟ |
866
+ | `n` | แž€แžพแž/แžšแŸ„แž… (แžแŸ’แž›แžธ) | Moon phase (short) | แž€, แžš |
867
+ | `N` | แž€แžพแž/แžšแŸ„แž… (แž–แŸแž‰) | Moon phase (full) | แž€แžพแž, แžšแŸ„แž… |
868
+ | `o` | แž“แžทแž˜แžทแžแŸ’แžแžŸแž‰แŸ’แž‰แžถ | Moon day symbol | แงก, แงข, แงฃ ... แงฟ |
862
869
  | **๐Ÿ“† Month Names** |
863
- | `m` | แžแŸ‚แž…แž“แŸ’แž‘แž‚แžแžท | Lunar month name | แž˜แžทแž‚แžŸแžทแžš, แž”แžปแžŸแŸ’แžŸ, แž…แŸแžแŸ’แžš |
864
- | `M` | แžแŸ‚แžŸแžปแžšแžทแž™แž‚แžแžท | Solar month name | แž˜แž€แžšแžถ, แž€แžปแž˜แŸ’แž—แŸˆ, แž˜แŸแžŸแžถ |
870
+ | `m` | แžแŸ‚แž…แž“แŸ’แž‘แž‚แžแžท | Lunar month name | แž˜แžทแž‚แžŸแžทแžš, แž”แžปแžŸแŸ’แžŸ, แž…แŸแžแŸ’แžš |
871
+ | `ms` | แžแŸ‚ (แžŸแž„แŸ’แžแŸแž”) | Lunar month name (abbreviated) | แž˜แžท, แž”แžป |
872
+ | `Ms` | แžแŸ‚ (แžŸแž„แŸ’แžแŸแž”) | Solar month name (abbreviated) | แž˜แž€, แž€แž˜ |
873
+ | `M` | แžแŸ‚แžŸแžปแžšแžทแž™แž‚แžแžท | Solar month name | แž˜แž€แžšแžถ, แž€แžปแž˜แŸ’แž—แŸˆ, แž˜แŸแžŸแžถ |
865
874
  | **โฐ Year Components** |
866
- | `a` | แž†แŸ’แž“แžถแŸ†แžŸแžแŸ’แžœ | Animal year | แž‡แžผแž, แž†แŸ’แž›แžผแžœ, แžšแŸ„แž„ |
867
- | `e` | แžŸแŸแž€ | Era year | แžฏแž€แžŸแŸแž€, แž‘แŸ„แžŸแŸแž€ |
868
- | `b` | แž–.แžŸ. | Buddhist Era year | แŸขแŸฅแŸฆแŸจ |
869
- | `c` | แž‚.แžŸ. | Common Era (Gregorian) year | แŸขแŸ แŸขแŸค |
870
- | `j` | แž….แžŸ. | Jolak Sakaraj year | แŸกแŸฃแŸจแŸฆ |
875
+ | `a` | แž†แŸ’แž“แžถแŸ†แžŸแžแŸ’แžœ | Animal year | แž‡แžผแž, แž†แŸ’แž›แžผแžœ, แžšแŸ„แž„ |
876
+ | `as` | แž†แŸ’แž“แžถแŸ† (แžšแžผแž”) | Animal year emoji | ๐Ÿ€, ๐Ÿ‚, ๐Ÿ‰ |
877
+ | `e` | แžŸแŸแž€ | Sak | แžฏแž€แžŸแŸแž€, แž‘แŸ„แžŸแŸแž€ |
878
+ | `b` | แž–.แžŸ. | Buddhist Era year | แŸขแŸฅแŸฆแŸจ |
879
+ | `br` | BE | Buddhist Era year (Latin) | 2568 |
880
+ | `c` | แž‚.แžŸ. | Common Era (Gregorian) year | แŸขแŸ แŸขแŸค |
881
+ | `cr` | CE | Common Era year (Latin) | 2024 |
882
+ | `j` | แž….แžŸ. | Jolak Sakaraj year | แŸกแŸฃแŸจแŸฆ |
883
+ | `jr` | JS | Jolak Sakaraj year (Latin) | 1386 |
884
+ | **๐Ÿ“… Day Components** |
885
+ | `d` | แžแŸ’แž„แŸƒแž‘แžธ | Day of month | แŸก, แŸข, แŸกแŸค |
886
+ | `dr` | Day | Day of month (Latin) | 1, 2, 14 |
887
+ | `D` | แžแŸ’แž„แŸƒแž‘แžธ (แž˜แžถแž“แŸ ) | Day of month (padded) | แŸ แŸก, แŸ แŸข, แŸกแŸค |
888
+ | `Dr` | Day (0) | Day of month (padded Latin) | 01, 02, 14 |
889
+ | `W` | แžแŸ’แž„แŸƒแž“แŸƒแžŸแž”แŸ’แžแžถแž แŸ | Day of week (full) | แžขแžถแž‘แžทแžแŸ’แž™, แž…แž“แŸ’แž‘ |
890
+ | `w` | แžแŸ’แž„แŸƒ (แžŸแž„แŸ’แžแŸแž”) | Day of week (short) | แžขแžถ, แž…, แžข |
871
891
 
872
892
  **Format Examples:**
873
893
 
@@ -911,8 +931,13 @@ momentkh.constants.AnimalYearNames;
911
931
  // ['แž‡แžผแž', 'แž†แŸ’แž›แžผแžœ', 'แžแžถแž›', 'แžแŸ„แŸ‡', 'แžšแŸ„แž„', 'แž˜แŸ’แžŸแžถแž‰แŸ‹',
912
932
  // 'แž˜แž˜แžธ', 'แž˜แž˜แŸ‚', 'แžœแž€', 'แžšแž€แžถ', 'แž…', 'แž€แžปแžš']
913
933
 
914
- // Era year names array (indices 0-9)
915
- momentkh.constants.EraYearNames;
934
+ // Animal year emojis array (indices 0-11)
935
+ momentkh.constants.AnimalYearEmojis;
936
+ // ['๐Ÿ€', '๐Ÿ‚', '๐Ÿ…', '๐Ÿ‡', '๐Ÿ‰', '๐Ÿ',
937
+ // '๐ŸŽ', '๐Ÿ', '๐Ÿ’', '๐Ÿ“', '๐Ÿ•', '๐Ÿ–']
938
+
939
+ // Sak names array (indices 0-9)
940
+ momentkh.constants.SakNames;
916
941
  // ['แžŸแŸ†แžšแžนแž‘แŸ’แž’แžทแžŸแŸแž€', 'แžฏแž€แžŸแŸแž€', 'แž‘แŸ„แžŸแŸแž€', 'แžแŸ’แžšแžธแžŸแŸแž€', 'แž…แžแŸ’แžœแžถแžŸแŸแž€',
917
942
  // 'แž”แž‰แŸ’แž…แžŸแŸแž€', 'แž†แžŸแŸแž€', 'แžŸแž”แŸ’แžแžŸแŸแž€', 'แžขแžŠแŸ’แž‹แžŸแŸแž€', 'แž“แž–แŸ’แžœแžŸแŸแž€']
918
943
 
@@ -921,7 +946,7 @@ momentkh.constants.WeekdayNames;
921
946
  // ['แžขแžถแž‘แžทแžแŸ’แž™', 'แž…แž“แŸ’แž‘', 'แžขแž„แŸ’แž‚แžถแžš', 'แž–แžปแž’', 'แž–แŸ’แžšแž แžŸแŸ’แž”แžแžทแŸ', 'แžŸแžปแž€แŸ’แžš', 'แžŸแŸ…แžšแŸ']
922
947
 
923
948
  // Moon phase names array (indices 0-1)
924
- momentkh.constants.MoonStatusNames;
949
+ momentkh.constants.MoonPhaseNames;
925
950
  // ['แž€แžพแž', 'แžšแŸ„แž…']
926
951
  ```
927
952
 
@@ -1122,7 +1147,7 @@ console.log(
1122
1147
  );
1123
1148
  console.log("BE Year:", khmer.khmer.beYear);
1124
1149
  console.log("Animal Year:", khmer.khmer.animalYear);
1125
- console.log("Era:", khmer.khmer.eraYear);
1150
+ console.log("Sak:", khmer.khmer.sak);
1126
1151
  console.log("Month:", khmer.khmer.monthName);
1127
1152
  console.log(
1128
1153
  "Day:",
@@ -1133,7 +1158,7 @@ console.log(
1133
1158
  // Gregorian: 14/4/2024
1134
1159
  // BE Year: 2568
1135
1160
  // Animal Year: แžšแŸ„แž„
1136
- // Era: แž†แžŸแŸแž€
1161
+ // Sak: แž†แžŸแŸแž€
1137
1162
  // Month: แž…แŸแžแŸ’แžš
1138
1163
  // Day: 6แž€แžพแž
1139
1164
  ```
@@ -1270,7 +1295,7 @@ for (let day = 20; day <= 25; day++) {
1270
1295
 
1271
1296
  MIT License - Same as original momentkh
1272
1297
 
1273
- Copyright (c) 2024
1298
+ Copyright (c) 2025
1274
1299
 
1275
1300
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
1276
1301
 
@@ -1283,10 +1308,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
1283
1308
  ## ๐Ÿ™ Credits & References
1284
1309
 
1285
1310
  - **Original momentkh library** by [Thyrith Sor](https://github.com/ThyrithSor)
1286
- - **Algorithm based on:**
1287
- - Traditional Khmer astronomical calculations
1288
- - "Pratitin Soryakkatik-Chankatik 1900-1999" by Mr. Roath Kim Soeun
1289
- - Khmer calendar C++ reference implementation
1290
1311
  - **Resources:**
1291
1312
  - [CAM-CC: Khmer Calendar](http://www.cam-cc.org)
1292
1313
  - [Dahlina: Khmer New Year Calculation](http://www.dahlina.com/education/khmer_new_year_time.html)
@@ -1322,12 +1343,11 @@ node test_specific_dates.js
1322
1343
 
1323
1344
  ## ๐Ÿ“ž Support
1324
1345
 
1325
- - **Documentation:** See examples folder (`newYearMoment.js`, `index.html`)
1326
1346
  - **Issues:** [GitHub Issues](https://github.com/ThyrithSor/momentkh/issues)
1327
1347
  - **Comparison:** Check behavior against original momentkh for compatibility
1348
+ - **Contact** [E-mail](me@thyrith.com)
1328
1349
 
1329
1350
  ---
1330
1351
 
1331
- **Version:** 3.0.0
1332
- **Last Updated:** December 2024
1333
- **Status:** Production Ready โœ…
1352
+ **Version:** 3.0.2
1353
+ **Last Updated:** December 2025