@coreify/tarikh 1.0.1 → 1.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
@@ -1,464 +1,557 @@
1
- # @coreify/tarikh
2
-
3
- [![npm version](https://img.shields.io/npm/v/@coreify/tarikh)](https://www.npmjs.com/package/@coreify/tarikh)
4
- [![downloads](https://img.shields.io/npm/dm/@coreify/tarikh)](https://www.npmjs.com/package/@coreify/tarikh)
5
- [![license](https://img.shields.io/npm/l/@coreify/tarikh)](https://github.com/coreify/tarikh/blob/main/package/LICENSE)
6
-
7
- The first JavaScript date library with full Bangla calendar support.
8
-
9
- Built for Bangla dates, Bengali calendar conversion, and culturally correct formatting.
1
+ # @coreify/tarikh
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@coreify/tarikh)](https://www.npmjs.com/package/@coreify/tarikh)
4
+ [![downloads](https://img.shields.io/npm/dm/@coreify/tarikh)](https://www.npmjs.com/package/@coreify/tarikh)
5
+ [![license](https://img.shields.io/npm/l/@coreify/tarikh)](https://github.com/coreify/tarikh/blob/main/package/LICENSE)
6
+
7
+ > The first JavaScript date library with Bangla and Hijri calendar support.
8
+ > Built for Bangla dates, Bengali calendar conversion, and culturally correct formatting.
9
+
10
+ | Main export | What it does |
11
+ | ----------- | ------------ |
12
+ | `format()` | Standard, Bangla, Hijri, and hybrid date formatting |
13
+ | `toBanglaCalendar()` | Convert Gregorian dates into the Bangla calendar |
14
+ | `toHijriCalendar()` | Convert Gregorian dates into the Hijri calendar |
15
+ | `fromNow()` | Render relative time like today, yesterday, and tomorrow |
16
+ | `HIJRI_TIME_ZONES` | Canonical supported Hijri time zones |
10
17
 
11
18
  ## At a Glance
12
19
 
20
+ | Snapshot | Example |
21
+ | -------- | ------- |
22
+ | Bangla spoken format | `format("2026-04-14", { mode: "bangla", locale: "bn-BD", format: "spoken" })` |
23
+ | Rendered output | `পহেলা বৈশাখ ১৪৩৩ বঙ্গাব্দ` |
24
+
13
25
  ```ts
14
26
  format("2026-04-14", {
15
27
  mode: "bangla",
16
28
  locale: "bn-BD",
17
- format: "spoken"
18
- });
19
- // → "পহেলা বৈশাখ ১৪৩৩"
20
- ```
21
-
29
+ format: "spoken"
30
+ });
31
+ // → "পহেলা বৈশাখ ১৪৩৩ বঙ্গাব্দ"
32
+ ```
33
+
22
34
  ## Demo
23
35
 
24
- External demo: [tarikh.js.org](https://tarikh.js.org)
25
-
36
+ | Demo | Link |
37
+ | ---- | ---- |
38
+ | Live demo | [tarikh.js.org](https://tarikh.js.org) |
39
+
26
40
  ## Why this exists
27
41
 
28
- JavaScript's `Intl.DateTimeFormat` and libraries like Day.js / date-fns don't solve these problems:
29
-
30
- - **Bangla calendar** Convert Gregorian dates to Bengali calendar (বৈশাখ, চৈত্র, etc.)
31
- - **Bangla digits** Render `৩১ মার্চ ২০২৬` instead of `31 March 2026`
32
- - **Hybrid formatting** Mix English and Bangla in a single date string
33
- - **Weekday and time formatting** Render weekday, hour, minute, and second output
34
- - **Natural relative time** Use `yesterday`, `tomorrow`, `গতকাল`, `আগামীকাল`, etc.
35
- - **Cultural correctness** Bangladeshi locale-aware formatting out of the box
36
-
37
- `@coreify/tarikh` is a zero-dependency, tree-shakeable, SSR-safe toolkit purpose-built for Bangladesh.
38
-
39
- ## Installation
40
-
41
- ```bash
42
- npm install @coreify/tarikh
43
- ```
44
-
45
- ## Quick Start
46
-
47
- ```ts
42
+ | Why this exists | Summary |
43
+ | --------------- | ------- |
44
+ | Bangla calendar | Convert Gregorian dates to Bengali calendar values like বৈশাখ and চৈত্র |
45
+ | Hijri calendar | Render Islamic calendar dates alongside Bangla and Gregorian output |
46
+ | Bangla digits | Render `৩১শে মার্চ ২০২৬ খ্রিস্টাব্দ` instead of `31st March 2026` |
47
+ | Hybrid formatting | Mix English and Bangla in a single date string |
48
+ | Weekday/time | Render weekday, hour, minute, and second output |
49
+ | Relative time | Use `yesterday`, `tomorrow`, `গতকাল`, `আগামীকাল`, etc. |
50
+ | Cultural correctness | Bangladeshi locale-aware formatting out of the box |
51
+
52
+ > `@coreify/tarikh` is a zero-dependency, tree-shakeable, SSR-safe toolkit purpose-built for Bangladesh.
53
+
54
+ ## Installation
55
+
56
+ ```bash
57
+ npm install @coreify/tarikh
58
+ ```
59
+
60
+ ## Quick Start
61
+
62
+ ```ts
48
63
  import {
64
+ HIJRI_TIME_ZONES,
49
65
  format,
50
66
  fromNow,
51
- toBanglaCalendar
67
+ toBanglaCalendar,
68
+ toHijriCalendar
52
69
  } from "@coreify/tarikh";
53
70
 
54
- // Preferred entry points:
55
- format(new Date(), { mode: "standard" });
56
- format(new Date(), { mode: "bangla" });
57
- format(new Date(), { mode: "hybrid" });
58
-
59
- // Token-based output still works.
60
- format(new Date(), { pattern: "DD MMM YYYY" });
61
- // → "31 Mar 2026"
62
-
63
- // Structured Bangla calendar conversion
64
- // `monthIndex` stays numeric; `bn-BD` localizes `day`, `month`, and `year`.
65
- toBanglaCalendar("2026-03-31");
66
- // → { day: 17, month: "Chaitra", monthIndex: 12, year: 1432 }
67
-
68
- toBanglaCalendar("2026-03-31", { locale: "bn-BD" });
69
- // → { day: "১৭", month: "চৈত্র", monthIndex: 12, year: "১৪৩২" }
70
-
71
+ const [defaultHijriZone, utcHijriZone] = HIJRI_TIME_ZONES;
72
+
73
+ // Preferred entry points:
74
+ format("2026-03-31", { mode: "standard" });
71
75
  format("2026-03-31", { mode: "bangla" });
72
- // "17 Chaitra 1432"
73
-
74
- format("2026-03-31", { mode: "bangla", locale: "bn-BD" });
75
- // "১৭ই চৈত্র ১৪৩২"
76
-
76
+ format("2026-03-31", { mode: "hijri" });
77
+ format("2026-03-31", { mode: "hybrid" });
78
+
79
+ // Token-based output still works.
80
+ format("2026-03-31", { pattern: "DD MMM YYYY" });
81
+ // → "31 Mar 2026"
82
+
83
+ // Structured Bangla calendar conversion
84
+ // `monthIndex` stays numeric; `bn-BD` localizes `day`, `month`, and `year`.
85
+ toBanglaCalendar("2026-03-31");
86
+ // → { day: 17, month: "Chaitra", monthIndex: 12, year: 1432 }
87
+
88
+ toBanglaCalendar("2026-03-31", { locale: "bn-BD" });
89
+ // → { day: "১৭", month: "চৈত্র", monthIndex: 12, year: "১৪৩২" }
90
+
91
+ format("2026-03-31", { mode: "bangla" });
92
+ // → "17th Chaitra 1432"
93
+
94
+ format("2026-03-31", { mode: "bangla", locale: "bn-BD" });
95
+ // → "১৭ই চৈত্র ১৪৩২ বঙ্গাব্দ"
96
+
77
97
  format("2026-04-14", { mode: "bangla", locale: "bn-BD" });
78
98
  // → "১লা বৈশাখ ১৪৩৩"
79
99
 
80
- format(new Date(2026, 2, 31, 15, 4), {
81
- mode: "standard",
82
- weekday: "short",
83
- hour: "numeric",
84
- minute: "2-digit"
85
- });
86
- // → "Tue, 31 Mar 2026, 15:04"
87
-
88
- format(new Date(2026, 2, 31, 21, 4, 9), {
89
- mode: "standard",
90
- weekday: "long",
91
- hour: "2-digit",
92
- minute: "2-digit",
93
- second: "2-digit",
94
- hour12: true
95
- });
96
- // → "Tuesday, 31 Mar 2026, 09:04:09 PM"
100
+ toHijriCalendar("2026-03-31");
101
+ // → { day: 11, month: "Shawwal", monthIndex: 10, year: 1447 }
97
102
 
98
- fromNow(new Date(Date.now() - 86400000), { numeric: "auto" });
99
- // → "yesterday"
103
+ toHijriCalendar("2026-03-31", { locale: "bn-BD" });
104
+ // → { day: "১১", month: "শাওয়াল", monthIndex: 10, year: "১৪৪৭" }
100
105
 
101
- fromNow(new Date(), { numeric: "auto" });
102
- // → "today"
103
- ```
106
+ toHijriCalendar("2026-03-31", { timeZone: "UTC" });
107
+ // → { day: 11, month: "Shawwal", monthIndex: 10, year: 1447 }
104
108
 
105
- Use `format()` for everything. Choose a mode (`standard`, `bangla`, `hybrid`) or pass a token pattern.
109
+ format("2026-03-31", { mode: "hijri" });
110
+ // → "12th Shawwal 1447 AH"
106
111
 
107
- ```ts
108
- // Show today's Bangla date in your app header
109
- format(new Date(), { mode: "bangla", locale: "bn-BD" });
110
- // → "১৭ চৈত্র ১৪৩২"
111
- ```
112
+ format("2026-03-31", { mode: "hijri", timeZone: "UTC" });
113
+ // "11th Shawwal 1447 AH"
112
114
 
113
- ## Features
115
+ | Timezone support | Details |
116
+ | ---------------- | ------- |
117
+ | `timeZone` | Accepts `Asia/Dhaka` and `UTC` |
118
+ | Supported list | Exported as `HIJRI_TIME_ZONES` |
114
119
 
115
- ### Standard Formatting
116
-
117
- ```ts
118
- import { format } from "@coreify/tarikh";
120
+ format("2026-03-31", { mode: "hijri", locale: "bn-BD" });
121
+ // → "১২ই শাওয়াল ১৪৪৭ হিজরি"
119
122
 
120
- format(new Date(), { mode: "standard" });
121
- // → "31 Mar 2026"
122
-
123
- format(new Date(), { mode: "standard", locale: "bn-BD" });
124
- // → "৩১ মার্চ ২০২৬"
125
-
126
- format(new Date(), { mode: "standard", month: "long", year: "2-digit" });
127
- // → "31 March 26"
128
-
129
- format(new Date(2026, 2, 31, 15, 4, 9), {
123
+ format(new Date(2026, 2, 31, 15, 4), {
130
124
  mode: "standard",
131
- weekday: "long",
132
- hour: "2-digit",
133
- minute: "2-digit",
134
- second: "2-digit",
135
- hour12: true
136
- });
137
- // "Tuesday, 31 Mar 2026, 03:04:09 PM"
138
- ```
139
-
140
- **Options:** `locale` (`"en-BD"` | `"bn-BD"`), `month` (`"short"` | `"long"`), `year` (`"numeric"` | `"2-digit"`), `day` (`"numeric"` | `"2-digit"`), `weekday` (`"short"` | `"long"`), `hour` / `minute` / `second` (`"numeric"` | `"2-digit"`), `hour12` (`boolean`)
141
-
142
- ### Pattern Formatting
143
-
144
- ```ts
145
- import { format } from "@coreify/tarikh";
146
-
147
- format(new Date(), { pattern: "DD MMM YYYY" });
148
- // "31 Mar 2026"
149
-
150
- format(new Date(), { pattern: "DD MMMM YYYY", locale: "bn-BD" });
151
- // "৩১ মার্চ ২০২৬"
152
-
153
- format(new Date(), { pattern: "DD/MM/YYYY" });
154
- // "31/03/2026"
155
-
156
- format(new Date(2026, 2, 31, 15, 4, 9), {
157
- pattern: "ddd, D MMM YYYY HH:mm:ss"
158
- });
159
- // → "Tue, 31 Mar 2026 15:04:09"
160
-
161
- format(new Date(2026, 2, 31, 9, 4), {
162
- pattern: "ddd, D MMM YYYY h:mm a",
163
- locale: "bn-BD"
164
- });
165
- // → "মঙ্গল, ৩১ মার্চ ২০২৬ ৯:০৪ পূর্বাহ্ণ"
166
-
167
- format(new Date(2026, 2, 31, 21, 4, 9), {
168
- pattern: "dddd, D MMM YYYY hh:mm:ss A"
169
- });
170
- // → "Tuesday, 31 Mar 2026 09:04:09 PM"
171
- ```
172
-
173
- `format()` is the primary API. Use `{ mode }` for date behavior or `{ pattern }` for token formatting. `mode` and `pattern` are mutually exclusive.
174
-
175
- **Tokens:** `dddd`, `ddd`, `DD`, `D`, `MMMM`, `MMM`, `MM`, `M`, `YYYY`, `YY`, `HH`, `H`, `hh`, `h`, `mm`, `m`, `ss`, `s`, `A`, `a`
176
-
177
- Use square brackets to keep literal text untouched by token replacement:
178
-
179
- ```ts
180
- format(new Date(2026, 2, 31, 15, 4), { pattern: "[Today at] h:mm a" });
181
- // → "Today at 3:04 pm"
182
- ```
183
-
184
- Bracket literals are not nestable; the first `]` closes the literal block.
185
-
125
+ weekday: "short",
126
+ hour: "numeric",
127
+ minute: "2-digit"
128
+ });
129
+ // → "Tue, 31st Mar 2026, 15:04"
130
+
131
+ format(new Date(2026, 2, 31, 21, 4, 9), {
132
+ mode: "standard",
133
+ weekday: "long",
134
+ hour: "2-digit",
135
+ minute: "2-digit",
136
+ second: "2-digit",
137
+ hour12: true
138
+ });
139
+ // "Tuesday, 31st Mar 2026, 09:04:09 PM"
140
+
141
+ fromNow(new Date(Date.now() - 86400000), { numeric: "auto" });
142
+ // Output depends on the current clock.
143
+
144
+ fromNow(new Date(), { numeric: "auto" });
145
+ // Output depends on the current clock.
146
+ ```
147
+
148
+ > Use `format()` for everything. Choose a mode (`standard`, `bangla`, `hijri`, `hybrid`) or pass a token pattern.
149
+
150
+ ```ts
151
+ // Show today's Bangla date in your app header
152
+ format("2026-03-31", { mode: "bangla", locale: "bn-BD" });
153
+ // → "১৭ চৈত্র ১৪৩২ বঙ্গাব্দ"
154
+ ```
155
+
156
+ ## Features
157
+
158
+ ### Standard Formatting
159
+
160
+ ```ts
161
+ import { format } from "@coreify/tarikh";
162
+
163
+ format("2026-03-31", { mode: "standard" });
164
+ // → "31st Mar 2026"
165
+
166
+ format("2026-03-31", { mode: "standard", locale: "bn-BD" });
167
+ // "৩১শে মার্চ ২০২৬ খ্রিস্টাব্দ"
168
+
169
+ format("2026-03-31", { mode: "standard", month: "long", year: "2-digit" });
170
+ // → "31st March 26"
171
+
172
+ format(new Date(2026, 2, 31, 15, 4, 9), {
173
+ mode: "standard",
174
+ weekday: "long",
175
+ hour: "2-digit",
176
+ minute: "2-digit",
177
+ second: "2-digit",
178
+ hour12: true
179
+ });
180
+ // → "Tuesday, 31st Mar 2026, 03:04:09 PM"
181
+ ```
182
+
183
+ **Options:** `locale` (`"en-BD"` | `"bn-BD"`), `month` (`"short"` | `"long"`), `year` (`"numeric"` | `"2-digit"`), `day` (`"numeric"` | `"2-digit"`), `weekday` (`"short"` | `"long"`), `hour` / `minute` / `second` (`"numeric"` | `"2-digit"`), `hour12` (`boolean`)
184
+
185
+ ### Pattern Formatting
186
+
187
+ ```ts
188
+ import { format } from "@coreify/tarikh";
189
+
190
+ format("2026-03-31", { pattern: "DD MMM YYYY" });
191
+ // → "31 Mar 2026"
192
+
193
+ format("2026-03-31", { pattern: "DD MMMM YYYY", locale: "bn-BD" });
194
+ // → "৩১ মার্চ ২০২৬"
195
+
196
+ format("2026-03-31", { pattern: "DD/MM/YYYY" });
197
+ // → "31/03/2026"
198
+
199
+ format(new Date(2026, 2, 31, 15, 4, 9), {
200
+ pattern: "ddd, D MMM YYYY HH:mm:ss"
201
+ });
202
+ // → "Tue, 31 Mar 2026 15:04:09"
203
+
204
+ format(new Date(2026, 2, 31, 9, 4), {
205
+ pattern: "ddd, D MMM YYYY h:mm a",
206
+ locale: "bn-BD"
207
+ });
208
+ // → "মঙ্গল, ৩১ মার্চ ২০২৬ ৯:০৪ পূর্বাহ্ণ"
209
+
210
+ format(new Date(2026, 2, 31, 21, 4, 9), {
211
+ pattern: "dddd, D MMM YYYY hh:mm:ss A"
212
+ });
213
+ // → "Tuesday, 31 Mar 2026 09:04:09 PM"
214
+ ```
215
+
216
+ > `format()` is the primary API. Use `{ mode }` for date behavior or `{ pattern }` for token formatting. `mode` and `pattern` are mutually exclusive.
217
+
218
+ **Tokens:** `dddd`, `ddd`, `DD`, `D`, `MMMM`, `MMM`, `MM`, `M`, `YYYY`, `YY`, `HH`, `H`, `hh`, `h`, `mm`, `m`, `ss`, `s`, `A`, `a`
219
+
220
+ > Use square brackets to keep literal text untouched by token replacement:
221
+
222
+ ```ts
223
+ format(new Date(2026, 2, 31, 15, 4), { pattern: "[Today at] h:mm a" });
224
+ // → "Today at 3:04 pm"
225
+ ```
226
+
227
+ > Bracket literals are not nestable; the first `]` closes the literal block.
228
+
186
229
  ## 🇧🇩 Bangla Calendar (Core Feature)
187
230
 
188
- This is the reason `@coreify/tarikh` exists.
189
-
190
- Convert Gregorian dates to the Bengali calendar (Bangladesh Revised Calendar, 1987).
191
-
192
- - **Top feature:** `format("2026-04-14", { mode: "bangla", locale: "bn-BD", format: "spoken" })` returns `পহেলা বৈশাখ ১৪৩৩`.
193
- - `toBanglaCalendar()` returns a structured object.
194
- - Default output: English digits + Latin month names (`en-BD`).
195
- - Locale-aware output: Bangla date words like `১লা`, `২রা`, `৩রা`, `৪ঠা`, `৫ই`, `১৯শে` plus Bangla month names (`bn-BD`).
196
- - `monthIndex` remains numeric in both cases.
197
- - `format(..., { mode: "bangla", locale: "bn-BD", format: "spoken" })` returns spoken day words like `পহেলা`, `দোসরা`, `তেসরা`, `চৌঠা`.
198
- - `formatBanglaCalendarDay(day, { format: "spoken" })` returns colloquial spoken forms for the first four days: `পহেলা`, `দোসরা`, `তেসরা`, `চৌঠা`.
199
- - Pass `{ variant: "pohela" }` to keep the standard `পহেলা` spelling explicitly, or `{ variant: "poyla" }` to get `পয়লা` for day 1. The parser also accepts the common `পয়লা` spelling.
231
+ | Bangla calendar | Behavior |
232
+ | --------------- | -------- |
233
+ | `toBanglaCalendar()` | Returns a structured object |
234
+ | Default output | English digits + Latin month names (`en-BD`) |
235
+ | `bn-BD` output | Bangla day forms like `১লা`, `২রা`, `৩রা`, `৪ঠা`, `৫ই`, `১৯শে` |
236
+ | Spoken mode | Returns `পহেলা`, `দোসরা`, `তেসরা`, `চৌঠা` |
237
+ | `variant: "pohela"` | Keeps the standard `পহেলা` spelling |
238
+ | `variant: "poyla"` | Uses `পয়লা` for day 1 |
239
+ | `monthIndex` | Stays numeric in both cases |
200
240
 
201
241
  ```ts
202
242
  import {
203
243
  format,
204
- formatBanglaCalendarDay,
205
- toBanglaCalendar
206
- } from "@coreify/tarikh";
207
-
208
- toBanglaCalendar("2026-03-31");
209
- // → { day: 17, month: "Chaitra", monthIndex: 12, year: 1432 }
210
-
211
- toBanglaCalendar("2026-03-31", { locale: "bn-BD" });
212
- // → { day: "১৭", month: "চৈত্র", monthIndex: 12, year: "১৪৩২" }
213
-
214
- format("2026-03-31", { mode: "bangla" });
215
- // → "17 Chaitra 1432"
216
-
244
+ formatBanglaCalendarDay,
245
+ toBanglaCalendar
246
+ } from "@coreify/tarikh";
247
+
248
+ toBanglaCalendar("2026-03-31");
249
+ // → { day: 17, month: "Chaitra", monthIndex: 12, year: 1432 }
250
+
251
+ toBanglaCalendar("2026-03-31", { locale: "bn-BD" });
252
+ // → { day: "১৭", month: "চৈত্র", monthIndex: 12, year: "১৪৩২" }
253
+
254
+ format("2026-03-31", { mode: "bangla" });
255
+ // → "17th Chaitra 1432"
256
+
257
+ format("2026-03-31", { mode: "bangla", locale: "bn-BD" });
258
+ // → "১৭ই চৈত্র ১৪৩২ বঙ্গাব্দ"
259
+
260
+ format("2026-04-14", { mode: "bangla" });
261
+ // → "1st Baishakh 1433"
262
+
263
+ format("2026-04-14", { mode: "bangla", locale: "bn-BD", format: "spoken" });
264
+ // → "পহেলা বৈশাখ ১৪৩৩ বঙ্গাব্দ"
265
+
266
+ format("2026-04-14", {
267
+ mode: "bangla",
268
+ locale: "bn-BD",
269
+ format: "spoken",
270
+ variant: "poyla"
271
+ });
272
+ // → "পয়লা বৈশাখ ১৪৩৩ বঙ্গাব্দ"
273
+
274
+ // Show today's Bangla date in your app header
217
275
  format("2026-03-31", { mode: "bangla", locale: "bn-BD" });
218
- // → "১৭ই চৈত্র ১৪৩২"
219
-
220
- format("2026-04-14", { mode: "bangla" });
221
- // → "1 Baishakh 1433"
222
-
223
- format("2026-04-14", { mode: "bangla", locale: "bn-BD", format: "spoken" });
224
- // → "পহেলা বৈশাখ ১৪৩৩"
225
-
226
- format("2026-04-14", {
227
- mode: "bangla",
228
- locale: "bn-BD",
229
- format: "spoken",
230
- variant: "poyla"
231
- });
232
- // → "পয়লা বৈশাখ ১৪৩৩"
233
-
234
- // Show today's Bangla date in your app header
235
- format(new Date(), { mode: "bangla", locale: "bn-BD" });
236
- // → "১৭ চৈত্র ১৪৩২" (example; depends on the current date)
237
-
238
- formatBanglaCalendarDay(21);
239
- // → "২১শে"
240
-
241
- formatBanglaCalendarDay(1, { format: "spoken" });
242
- // → "পহেলা"
243
-
244
- formatBanglaCalendarDay(1, { format: "spoken", variant: "poyla" });
245
- // → "পয়লা"
246
-
276
+ // → "১৭ চৈত্র ১৪৩২ বঙ্গাব্দ" (example; depends on the current date)
277
+
278
+ formatBanglaCalendarDay(21);
279
+ // → "২১শে"
280
+
281
+ formatBanglaCalendarDay(1, { format: "spoken" });
282
+ // → "পহেলা"
283
+
284
+ formatBanglaCalendarDay(1, { format: "spoken", variant: "poyla" });
285
+ // "পয়লা"
286
+
247
287
  formatBanglaCalendarDay(1, { format: "spoken", variant: "pohela" });
248
288
  // → "পহেলা"
249
289
  ```
250
290
 
251
- ### Hybrid Formatting
291
+ ### Hijri Calendar
252
292
 
253
- Mix English and Bangla independently for day, month, and year.
293
+ | Hijri calendar | Behavior |
294
+ | -------------- | -------- |
295
+ | `toHijriCalendar()` | Returns a structured object |
296
+ | Default timezone | `Asia/Dhaka` |
297
+ | `timeZone` override | Accepts the exported `HIJRI_TIME_ZONES` values |
298
+ | Default output | English month/day/year with `AH` |
299
+ | `bn-BD` output | Bangla digits and the `হিজরি` suffix |
300
+ | `UTC` override | Exposes the alternative canonical Hijri result |
254
301
 
255
302
  ```ts
256
- import { format } from "@coreify/tarikh";
303
+ import { HIJRI_TIME_ZONES, format, toHijriCalendar } from "@coreify/tarikh";
257
304
 
258
- format(new Date(), { mode: "hybrid" });
259
- // → "31 মার্চ 2026"
305
+ const [defaultHijriZone, alternateHijriZone] = HIJRI_TIME_ZONES;
260
306
 
261
- format(new Date(), {
262
- mode: "hybrid",
263
- digits: "bn",
264
- month: "bn",
265
- year: "en"
266
- });
267
- // → "৩১ মার্চ 2026"
268
- ```
307
+ toHijriCalendar("2026-03-31");
308
+ // → { day: 11, month: "Shawwal", monthIndex: 10, year: 1447 }
269
309
 
270
- ### Bangla Digits
310
+ toHijriCalendar("2026-03-31", { locale: "bn-BD" });
311
+ // → { day: "১১", month: "শাওয়াল", monthIndex: 10, year: "১৪৪৭" }
271
312
 
272
- ```ts
273
- import { toBanglaDigits, toEnglishDigits } from "@coreify/tarikh";
313
+ toHijriCalendar("2026-03-31", { timeZone: "UTC" });
314
+ // { day: 11, month: "Shawwal", monthIndex: 10, year: 1447 }
274
315
 
275
- toBanglaDigits("31 March 2026");
276
- // → "৩১ March ২০২৬"
316
+ // Supported values: defaultHijriZone === "Asia/Dhaka", alternateHijriZone === "UTC"
277
317
 
278
- toEnglishDigits("৩১ মার্চ ২০২৬");
279
- // → "31 মার্চ 2026"
280
- ```
318
+ format("2026-03-31", { mode: "hijri" });
319
+ // → "12th Shawwal 1447 AH"
281
320
 
282
- ### Relative Time
321
+ format("2026-03-31", { mode: "hijri", timeZone: "UTC" });
322
+ // → "11th Shawwal 1447 AH"
283
323
 
284
- ```ts
285
- import { fromNow } from "@coreify/tarikh";
324
+ format("2026-03-31", { mode: "hijri", locale: "bn-BD" });
325
+ // "১২ই শাওয়াল ১৪৪৭ হিজরি"
326
+ ```
286
327
 
328
+ ### Hybrid Formatting
329
+
330
+ | Mixing rule | Summary |
331
+ | ----------- | ------- |
332
+ | Hybrid formatting | Mix English and Bangla independently for day, month, and year |
333
+
334
+ ```ts
335
+ import { format } from "@coreify/tarikh";
336
+
337
+ format("2026-03-31", { mode: "hybrid" });
338
+ // → "31 মার্চ 2026"
339
+
340
+ format("2026-03-31", {
341
+ mode: "hybrid",
342
+ digits: "bn",
343
+ month: "bn",
344
+ year: "en"
345
+ });
346
+ // → "৩১ মার্চ 2026"
347
+ ```
348
+
349
+ ### Bangla Digits
350
+
351
+ ```ts
352
+ import { toBanglaDigits, toEnglishDigits } from "@coreify/tarikh";
353
+
354
+ toBanglaDigits("31 March 2026");
355
+ // → "৩১ March ২০২৬"
356
+
357
+ toEnglishDigits("৩১ মার্চ ২০২৬");
358
+ // → "31 মার্চ 2026"
359
+ ```
360
+
361
+ ### Relative Time
362
+
363
+ ```ts
364
+ import { fromNow } from "@coreify/tarikh";
365
+
287
366
  fromNow(new Date(Date.now() - 86400000));
288
- // "1 day ago"
289
-
367
+ // Output depends on the current clock.
368
+
290
369
  fromNow(new Date(Date.now() - 86400000), { locale: "bn-BD" });
291
- // "১ দিন আগে"
292
-
370
+ // Output depends on the current clock.
371
+
293
372
  fromNow(new Date(Date.now() + 3600000));
294
- // "in 1 hour"
295
-
373
+ // Output depends on the current clock.
374
+
296
375
  fromNow(new Date(Date.now() - 86400000), { numeric: "auto" });
297
- // "yesterday"
298
-
376
+ // Output depends on the current clock.
377
+
299
378
  fromNow(new Date(Date.now() + 86400000), {
300
379
  locale: "bn-BD",
301
380
  numeric: "auto"
302
381
  });
303
- // "আগামীকাল"
304
- ```
305
-
306
- ### Parsing
307
-
308
- ```ts
309
- import { parseDate } from "@coreify/tarikh";
310
-
311
- parseDate("৩১ মার্চ ২০২৬");
312
- // → Date object (March 31, 2026)
313
-
314
- parseDate("17 Chaitra 1432", { calendar: "bangla" });
315
- // → Date object (March 31, 2026)
316
-
317
- // Legacy spellings (Boishakh, Joishtho, Choitro, etc.) are still accepted.
318
-
319
- parseDate("১৭ চৈত্র ১৪৩২", { calendar: "bangla" });
320
- // → Date object (March 31, 2026)
321
-
322
- parseDate("31 March 2026");
323
- // → Date object (March 31, 2026)
324
-
325
- parseDate("March 31, 2026");
326
- // → Date object (March 31, 2026)
327
-
328
- parseDate("31-Mar-2026");
329
- // → Date object (March 31, 2026)
330
-
331
- parseDate("2026/03/31");
332
- // → Date object (March 31, 2026)
333
-
334
- parseDate("2026.03.31");
335
- // → Date object (March 31, 2026)
336
-
337
- parseDate("2026-03-31T15:30:00Z");
338
- // → Date object (March 31, 2026, 3:30 PM UTC)
339
-
340
- // `toDate()` accepts the same Gregorian string forms as `parseDate()`,
341
- // plus `Date` objects and timestamps.
342
- // Supported string shapes:
343
- // - `YYYY-MM-DD`
344
- // - `YYYY/MM/DD`
345
- // - `YYYY.MM.DD`
346
- // - `YYYY-M-D`, `YYYY/M/D`, `YYYY.M.D`
347
- // - `YYYY-MM-DDTHH:mm[:ss[.fraction]][Z|±HH:mm]`
348
- // - `DD Month YYYY`
349
- // - `Month DD, YYYY`
350
- // - `DD-Month-YYYY`
351
- // - Bangla calendar strings like `১৭ চৈত্র ১৪৩২`
352
- // - Common Bangla month aliases like `Boishakh`, `Poush`, `Falgun`, `Asharh`
353
- ```
354
-
355
- ### Utilities
356
-
357
- ```ts
358
- import {
359
- isToday,
360
- isYesterday,
361
- isTomorrow,
362
- startOfDay,
363
- endOfDay,
364
- startOfMonth,
365
- endOfMonth,
366
- startOfYear,
367
- endOfYear,
368
- addDays,
369
- subDays,
370
- addMonths,
371
- subMonths,
372
- addYears,
373
- subYears,
374
- getBanglaMonth
375
- } from "@coreify/tarikh";
376
-
377
- isToday(new Date()); // → true
378
- isYesterday(subDays(new Date(), 1)); // → true
379
- isTomorrow(addDays(new Date(), 1)); // → true
380
- startOfMonth(new Date()); // → Date at the start of this month
381
- endOfMonth(new Date()); // → Date at the end of this month
382
- addMonths("2026-01-31", 1); // → 2026-02-28
383
- addYears(new Date(2024, 1, 29), 1); // → 2025-02-28
384
-
385
- getBanglaMonth(3); // → "মার্চ"
386
- getBanglaMonth(3, "short"); // → "মার্চ"
387
- getBanglaMonth(12); // → "ডিসেম্বর"
388
- ```
389
-
390
- ### Constants
391
-
392
- ```ts
393
- import {
394
- BANGLA_MONTHS_FULL,
395
- BANGLA_MONTHS_SHORT,
396
- BANGLA_CALENDAR_MONTHS,
397
- BANGLA_CALENDAR_MONTHS_EN,
398
- BANGLA_WEEKDAYS_FULL,
399
- BANGLA_WEEKDAYS_SHORT,
400
- ENGLISH_WEEKDAYS_FULL,
401
- ENGLISH_WEEKDAYS_SHORT,
402
- BANGLA_DIGITS,
403
- ENGLISH_DIGITS
404
- } from "@coreify/tarikh";
405
- ```
406
-
382
+ // Output depends on the current clock.
383
+ ```
384
+
385
+ ### Parsing
386
+
387
+ ```ts
388
+ import { parseDate } from "@coreify/tarikh";
389
+
390
+ parseDate("৩১ মার্চ ২০২৬");
391
+ // → Date object (March 31, 2026)
392
+
393
+ parseDate("17 Chaitra 1432", { calendar: "bangla" });
394
+ // → Date object (March 31, 2026)
395
+
396
+ // Legacy spellings (Boishakh, Joishtho, Choitro, etc.) are still accepted.
397
+
398
+ parseDate("১৭ চৈত্র ১৪৩২", { calendar: "bangla" });
399
+ // → Date object (March 31, 2026)
400
+
401
+ parseDate("31 March 2026");
402
+ // → Date object (March 31, 2026)
403
+
404
+ parseDate("March 31, 2026");
405
+ // → Date object (March 31, 2026)
406
+
407
+ parseDate("31-Mar-2026");
408
+ // → Date object (March 31, 2026)
409
+
410
+ parseDate("2026/03/31");
411
+ // → Date object (March 31, 2026)
412
+
413
+ parseDate("2026.03.31");
414
+ // → Date object (March 31, 2026)
415
+
416
+ parseDate("2026-03-31T15:30:00Z");
417
+ // → Date object (March 31, 2026, 3:30 PM UTC)
418
+
419
+ // `toDate()` accepts the same Gregorian string forms as `parseDate()`,
420
+ // plus `Date` objects and timestamps.
421
+ // Supported string shapes:
422
+ // - `YYYY-MM-DD`
423
+ // - `YYYY/MM/DD`
424
+ // - `YYYY.MM.DD`
425
+ // - `YYYY-M-D`, `YYYY/M/D`, `YYYY.M.D`
426
+ // - `YYYY-MM-DDTHH:mm[:ss[.fraction]][Z|±HH:mm]`
427
+ // - `DD Month YYYY`
428
+ // - `Month DD, YYYY`
429
+ // - `DD-Month-YYYY`
430
+ // - Bangla calendar strings like `১৭ চৈত্র ১৪৩২`
431
+ // - Common Bangla month aliases like `Boishakh`, `Poush`, `Falgun`, `Asharh`
432
+ ```
433
+
434
+ ### Utilities
435
+
436
+ ```ts
437
+ import {
438
+ isToday,
439
+ isYesterday,
440
+ isTomorrow,
441
+ startOfDay,
442
+ endOfDay,
443
+ startOfMonth,
444
+ endOfMonth,
445
+ startOfYear,
446
+ endOfYear,
447
+ addDays,
448
+ subDays,
449
+ addMonths,
450
+ subMonths,
451
+ addYears,
452
+ subYears,
453
+ getBanglaMonth
454
+ } from "@coreify/tarikh";
455
+
456
+ isToday(new Date()); // → true
457
+ isYesterday(subDays(new Date(), 1)); // → true
458
+ isTomorrow(addDays(new Date(), 1)); // → true
459
+ startOfMonth(new Date()); // → Date at the start of this month
460
+ endOfMonth(new Date()); // → Date at the end of this month
461
+ addMonths("2026-01-31", 1); // → 2026-02-28
462
+ addYears(new Date(2024, 1, 29), 1); // → 2025-02-28
463
+
464
+ getBanglaMonth(3); // → "মার্চ"
465
+ getBanglaMonth(3, "short"); // → "মার্চ"
466
+ getBanglaMonth(12); // → "ডিসেম্বর"
467
+ ```
468
+
469
+ ### Constants
470
+
471
+ ```ts
472
+ import {
473
+ BANGLA_MONTHS_FULL,
474
+ BANGLA_MONTHS_SHORT,
475
+ BANGLA_CALENDAR_MONTHS,
476
+ BANGLA_CALENDAR_MONTHS_EN,
477
+ BANGLA_WEEKDAYS_FULL,
478
+ BANGLA_WEEKDAYS_SHORT,
479
+ ENGLISH_WEEKDAYS_FULL,
480
+ ENGLISH_WEEKDAYS_SHORT,
481
+ BANGLA_DIGITS,
482
+ ENGLISH_DIGITS
483
+ } from "@coreify/tarikh";
484
+ ```
485
+
407
486
  ## React Components
408
487
 
409
- Optional entry point only included if you import from `@coreify/tarikh/react`.
488
+ | React export | Purpose |
489
+ | ------------ | ------- |
490
+ | `Tarikh` | Default semantic `<time>` formatter |
491
+ | `Tarikh.Relative` | Relative time rendering |
492
+ | `Tarikh.Bangla` | Bangla calendar rendering |
493
+ | `Tarikh.Hijri` | Hijri calendar rendering |
410
494
 
411
- Primary React API:
412
-
413
- Use `Tarikh` for the default formatter, then reach for the nested variants when you want relative time or Bangla calendar rendering.
495
+ > Import from `@coreify/tarikh/react` only when you need the React components.
414
496
 
415
497
  ```tsx
416
498
  import { Tarikh } from "@coreify/tarikh/react";
417
499
 
418
- <Tarikh value={new Date()} />
419
- <Tarikh.Relative value={new Date()} />
420
- <Tarikh.Bangla value={new Date()} locale="bn-BD" />
421
- ```
500
+ const date = "2026-03-31";
422
501
 
423
- ```bash
424
- npm install @coreify/tarikh react
502
+ <Tarikh value={date} />
503
+ <Tarikh.Relative value={date} />
504
+ <Tarikh.Bangla value={date} locale="bn-BD" />
505
+ <Tarikh.Hijri value={date} locale="bn-BD" />
425
506
  ```
426
-
427
- All components render semantic `<time>` elements with `dateTime` and `aria-label` attributes. They are SSR-safe, tree-shakeable, and have zero runtime dependencies beyond React.
428
-
429
- `Tarikh` handles standard date formatting, `Tarikh.Relative` handles relative time, and `Tarikh.Bangla` handles Bangla calendar output.
430
-
507
+
508
+ ```bash
509
+ npm install @coreify/tarikh react
510
+ ```
511
+
512
+ | React detail | Notes |
513
+ | ------------ | ----- |
514
+ | Semantics | Renders `<time>` elements with `dateTime` and `aria-label` |
515
+ | Runtime | SSR-safe, tree-shakeable, zero runtime dependencies beyond React |
516
+ | Roles | `Tarikh` standard formatting, `Tarikh.Relative` relative time, `Tarikh.Bangla` Bangla calendar, `Tarikh.Hijri` Hijri calendar |
517
+
431
518
  ## What `Intl.DateTimeFormat` cannot do
432
519
 
433
- If you're building for Bangladesh, existing libraries are not enough.
520
+ | Why `Intl` falls short | Summary |
521
+ | --------------------- | ------- |
522
+ | Bangladesh-focused formatting | Needs Bangla calendar and culturally correct output |
434
523
 
435
524
  | Feature | Intl | @coreify/tarikh |
436
525
  | ------------------------------- | ------- | --------------- |
437
526
  | Bangla calendar (বৈশাখ → চৈত্র) | No | Yes |
527
+ | Hijri calendar | Partial | Yes |
438
528
  | Bangla digits in dates | Partial | Yes |
439
- | Hybrid formatting (mixed en/bn) | No | Yes |
440
- | Bangla calendar date parsing | No | Yes |
441
- | Relative time in Bangla | No | Yes |
442
- | SSR-safe React components | N/A | Yes |
443
-
529
+ | Hybrid formatting (mixed en/bn) | No | Yes |
530
+ | Bangla calendar date parsing | No | Yes |
531
+ | Relative time in Bangla | No | Yes |
532
+ | SSR-safe React components | N/A | Yes |
533
+
444
534
  ## TypeScript
445
535
 
446
- Fully typed with strict mode. Start with the primary types below; the package also exports the lower-level calendar and helper types for advanced use.
447
-
448
- Type-level contract note: when using `pattern`, `mode` is intentionally disallowed in TypeScript.
536
+ | Type | Purpose |
537
+ | ---- | ------- |
538
+ | `FormatOptions` | Primary object-based formatting contract |
539
+ | `TarikhProps` | Props for the main React `<Tarikh />` component |
540
+ | `HIJRI_TIME_ZONES` | Canonical supported Hijri time zones (`Asia/Dhaka`, `UTC`) |
541
+ | Type-level contract | When using `pattern`, `mode` is intentionally disallowed in TypeScript |
449
542
 
450
543
  ```ts
451
544
  import type {
452
- Locale,
453
- FormatMode,
454
- FormatOptions,
455
- DateInput,
456
- RelativeTimeOptions
457
- } from "@coreify/tarikh";
458
-
459
- import type { TarikhProps } from "@coreify/tarikh/react";
460
- ```
461
-
462
- ## License
463
-
464
- MIT
545
+ Locale,
546
+ FormatMode,
547
+ FormatOptions,
548
+ DateInput,
549
+ RelativeTimeOptions
550
+ } from "@coreify/tarikh";
551
+
552
+ import type { TarikhProps } from "@coreify/tarikh/react";
553
+ ```
554
+
555
+ ## License
556
+
557
+ MIT