@bereasoftware/time-guard 1.0.1

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 ADDED
@@ -0,0 +1,1315 @@
1
+ # TimeGuard 🕐
2
+
3
+ > 📚 **Documentación disponible en otros idiomas:**
4
+ > - 🇪🇸 **Español** (este archivo - README.md)
5
+ > - 🇬🇧 [English](README.en.md)
6
+
7
+ Una biblioteca moderna y de nivel producción para manipulación de fechas/horas construida con **TypeScript**, **Temporal API** y **SOLID principles**. TimeGuard aprovecha los estándares de JavaScript modernos y las mejores prácticas.
8
+
9
+ [![Pruebas](https://img.shields.io/badge/Pruebas-530%2B-green?style=for-the-badge)](#testing)
10
+ [![Locales](https://img.shields.io/badge/Locales-40%2B-orange?style=for-the-badge)](#locales-soportadas)
11
+ [![Calendarios](https://img.shields.io/badge/Calendarios-6+-blue?style=for-the-badge)](#sistemas-de-calendario)
12
+ [![Versión NPM](https://img.shields.io/npm/v/@bereasoftware/time-guard?style=for-the-badge)](https://www.npmjs.com/package/@bereasoftware/time-guard)
13
+ [![Tamaño bundle](https://img.shields.io/bundlephobia/minzip/@bereasoftware/time-guard?style=for-the-badge)](https://www.npmjs.com/package/@bereasoftware/time-guard)
14
+ [![Descargas NPM](https://img.shields.io/npm/dm/@bereasoftware/time-guard?style=for-the-badge)](https://www.npmjs.com/package/@bereasoftware/time-guard)
15
+ [![CI](https://img.shields.io/github/actions/workflow/status/Berea-Soft/time-guard/ci.yml?style=for-the-badge)](https://github.com/Berea-Soft/time-guard/actions/workflows/ci.yml)
16
+ [![Node](https://img.shields.io/node/v/@bereasoftware/time-guard?style=for-the-badge)](https://www.npmjs.com/package/@bereasoftware/time-guard)
17
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-3178C6?style=for-the-badge)](https://www.typescriptlang.org/)
18
+ [![Licencia](https://img.shields.io/github/license/Berea-Soft/email-validator?style=for-the-badge)](https://github.com/Berea-Soft/email-validator/blob/main/LICENSE)
19
+ [![Último commit](https://img.shields.io/github/last-commit/Berea-Soft/time-guard?style=for-the-badge)](https://github.com/Berea-Soft/time-guard/commits/main)
20
+ [![Repositorio](https://img.shields.io/badge/github-repo-blue?logo=github&style=for-the-badge)](https://github.com/Berea-Soft/time-guard)
21
+ [![Cobertura](https://img.shields.io/badge/coverage-95%25-orange?style=for-the-badge)](https://github.com/Berea-Soft/time-guard)
22
+
23
+ ---
24
+
25
+ ## 🎯 Características
26
+
27
+ - ✨ **JavaScript Moderno** - Construido sobre Temporal API (estándar TC39)
28
+ - 🏛️ **Principios SOLID** - Arquitectura limpia, mantenible y extensible
29
+ - 🌍 **40+ Locales** - Soporte completo de internacionalización
30
+ - 📦 **TypeScript** - Seguridad de tipos completa con modo estricto
31
+ - 🧪 **530+ Tests** - Cobertura completa BDD/TDD
32
+ - 🎨 **Múltiples Formatos** - ISO, RFC2822, RFC3339, UTC y patrones personalizados
33
+ - ⚡ **Tree-Shakeable** - Estructura modular para tamaño óptimo del bundle
34
+ - 📚 **Bien Documentado** - Guías extensas, ejemplos y referencia API
35
+ - 🔌 **Sistema de Plugins** - Extiende con plugins opcionales (tiempo relativo, duración, formato avanzado)
36
+ - 📅 **Múltiples Calendarios** - Gregoriano, Islámico, Hebreo, Chino, Japonés, Budista y más
37
+ - ⏱️ **Precisión de Nanosegundos** - Soporte completo de Temporal API
38
+ - 🔄 **API de Duración** - Métodos `until()` y `round()` para cálculos avanzados
39
+
40
+ ---
41
+
42
+ ## 📋 Tabla de Contenidos
43
+
44
+ - [Inicio Rápido](#inicio-rápido)
45
+ - [Instalación](#instalación)
46
+ - [Conceptos Clave](#conceptos-clave)
47
+ - [Accesores de Componentes](#accesores-de-componentes)
48
+ - [Cálculos Avanzados](#cálculos-avanzados)
49
+ - [Sistemas de Calendario](#sistemas-de-calendario)
50
+ - [Plugins](#plugins)
51
+ - [Documentación](#documentación)
52
+ - [Locales Soportadas](#locales-soportadas)
53
+ - [Referencia API](#referencia-api)
54
+ - [Testing](#testing)
55
+ - [Arquitectura](#arquitectura)
56
+ - [Contribuir](#contribuir)
57
+ - [Licencia](#licencia)
58
+
59
+ ---
60
+
61
+ ## 🚀 Inicio Rápido
62
+
63
+ ```typescript
64
+ import { TimeGuard } from "time-guard";
65
+
66
+ // Crear una fecha
67
+ const now = TimeGuard.now();
68
+ const date = TimeGuard.from("2024-03-13");
69
+
70
+ // Manipular fechas
71
+ const tomorrow = date.add(1, "day");
72
+ const nextMonth = date.add(1, "month");
73
+
74
+ // Formatear con locales
75
+ const spanish = date.locale("es").format("dddd, DD MMMM YYYY");
76
+ // Resultado: miércoles, 13 marzo 2024
77
+
78
+ const japanese = date.locale("ja").format("YYYY年M月D日");
79
+ // Resultado: 2024年3月13日
80
+
81
+ // Obtener componentes
82
+ console.log(date.year()); // 2024
83
+ console.log(date.month()); // 3
84
+ console.log(date.day()); // 13
85
+ console.log(date.dayOfWeek()); // 3 (miércoles)
86
+
87
+ // Comparar fechas
88
+ console.log(date.isBefore(tomorrow)); // true
89
+ console.log(date.isSame(date.clone())); // true
90
+ console.log(date.isAfter(new Date("2020-01-01"))); // true
91
+ ```
92
+
93
+ ---
94
+
95
+ ## 📦 Instalación
96
+
97
+ ```bash
98
+ npm install time-guard
99
+ # o
100
+ yarn add time-guard
101
+ # o
102
+ pnpm add time-guard
103
+ ```
104
+
105
+ ### Requisitos
106
+
107
+ - **Node.js** 16+ (soporte de Temporal API)
108
+ - **TypeScript** 5.0+ (opcional pero recomendado)
109
+
110
+ ---
111
+
112
+ ## 🏗️ Conceptos Clave
113
+
114
+ ### 1. Inmutabilidad
115
+
116
+ Todas las instancias de TimeGuard son inmutables. Cada operación devuelve una nueva instancia:
117
+
118
+ ```typescript
119
+ const date = TimeGuard.from("2024-03-13");
120
+ const modified = date.add(1, "day");
121
+
122
+ console.log(date.day()); // 13 (sin cambios)
123
+ console.log(modified.day()); // 14 (nueva instancia)
124
+ ```
125
+
126
+ ### 2. Soporte de Zonas Horarias
127
+
128
+ Maneja zonas horarias con soporte completo de Temporal API:
129
+
130
+ ```typescript
131
+ const date = TimeGuard.from("2024-03-13 10:30:00");
132
+
133
+ // Set timezone
134
+ const inNYC = date.timezone("America/New_York");
135
+ const inTokyo = date.timezone("Asia/Tokyo");
136
+
137
+ console.log(inNYC.format("YYYY-MM-DD HH:mm:ss Z"));
138
+ console.log(inTokyo.format("YYYY-MM-DD HH:mm:ss Z"));
139
+ ```
140
+
141
+ ### 3. Localización
142
+
143
+ Soporte para 40+ idiomas y locales:
144
+
145
+ ```typescript
146
+ const date = TimeGuard.from("2024-03-13");
147
+
148
+ date.locale("en").format("MMMM DD, YYYY"); // March 13, 2024
149
+ date.locale("es").format("DD MMMM YYYY"); // 13 marzo 2024
150
+ date.locale("fr").format("DD MMMM YYYY"); // 13 mars 2024
151
+ date.locale("de").format("DD. MMMM YYYY"); // 13. März 2024
152
+ date.locale("ja").format("YYYY年M月D日"); // 2024年3月13日
153
+ date.locale("zh-cn").format("YYYY年M月D日"); // 2024年3月13日
154
+ date.locale("ar").format("DD MMMM YYYY"); // 13 مارس 2024
155
+ ```
156
+
157
+ ### 4. Estrategias de Formato
158
+
159
+ Múltiples formatos preestablecidos y patrones personalizados:
160
+
161
+ ```typescript
162
+ const date = TimeGuard.from("2024-03-13 14:30:45");
163
+
164
+ // Preestablecidos
165
+ date.format("iso"); // 2024-03-13T14:30:45
166
+ date.format("date"); // 2024-03-13
167
+ date.format("time"); // 14:30:45
168
+ date.format("datetime"); // 2024-03-13 14:30:45
169
+ date.format("rfc2822"); // Wed, 13 Mar 2024 14:30:45 GMT
170
+ date.format("rfc3339"); // 2024-03-13T14:30:45Z
171
+ date.format("utc"); // 2024-03-13T14:30:45Z
172
+
173
+ // Patrones personalizados
174
+ date.format("YYYY-MM-DD HH:mm:ss");
175
+ date.format("dddd, MMMM DD, YYYY");
176
+ date.format("MM/DD/YYYY");
177
+ ```
178
+
179
+ ---
180
+
181
+ ## 🎯 Accesores de Componentes
182
+
183
+ Acceso rápido a componentes individuales de la fecha:
184
+
185
+ ```typescript
186
+ const date = TimeGuard.from("2024-03-13 14:30:45.123");
187
+
188
+ // Componentes individuales
189
+ console.log(date.year()); // 2024
190
+ console.log(date.month()); // 3
191
+ console.log(date.day()); // 13
192
+ console.log(date.hour()); // 14
193
+ console.log(date.minute()); // 30
194
+ console.log(date.second()); // 45
195
+ console.log(date.millisecond()); // 123
196
+
197
+ // Información de la semana
198
+ console.log(date.dayOfWeek()); // 3 (Mié: 1=Dom, 7=Sáb)
199
+ console.log(date.dayOfYear()); // 73
200
+ console.log(date.weekOfYear()); // 11
201
+
202
+ // Información de mes/año
203
+ console.log(date.daysInMonth()); // 31
204
+ console.log(date.daysInYear()); // 366 (año bisiesto)
205
+ console.log(date.inLeapYear()); // true
206
+ ```
207
+
208
+ ---
209
+
210
+ ## ⏱️ Cálculos Avanzados
211
+
212
+ ### Duración: Calcular tiempo entre fechas
213
+
214
+ ```typescript
215
+ const start = TimeGuard.from("2024-01-15");
216
+ const end = TimeGuard.from("2024-03-20");
217
+
218
+ const duration = start.until(end);
219
+
220
+ console.log(duration);
221
+ // {
222
+ // years: 0,
223
+ // months: 2,
224
+ // days: 5,
225
+ // hours: 0,
226
+ // minutes: 0,
227
+ // seconds: 0,
228
+ // milliseconds: 0
229
+ // }
230
+ ```
231
+
232
+ ### Redondeo: Control de precisión
233
+
234
+ ```typescript
235
+ const date = TimeGuard.from("2024-03-13 14:35:47.654");
236
+
237
+ // Redondear a diferentes unidades
238
+ date.round({ smallestUnit: "second" }); // 2024-03-13 14:35:48
239
+ date.round({ smallestUnit: "minute" }); // 2024-03-13 14:36:00
240
+ date.round({ smallestUnit: "hour" }); // 2024-03-13 15:00:00
241
+ date.round({ smallestUnit: "day" }); // 2024-03-14 00:00:00
242
+
243
+ // Modos de redondeo: 'ceil', 'floor', 'trunc', 'half' (predeterminado)
244
+ date.round({
245
+ smallestUnit: "minute",
246
+ roundingMode: "ceil",
247
+ });
248
+ ```
249
+
250
+ ---
251
+
252
+ ## 📅 Sistemas de Calendario
253
+
254
+ TimeGuard incluye soporte para múltiples sistemas de calendario, extensible a través del gestor de calendarios:
255
+
256
+ ### Supported Calendars
257
+
258
+ ```typescript
259
+ import { TimeGuard, CalendarManager } from "time-guard";
260
+ import {
261
+ IslamicCalendar,
262
+ HebrewCalendar,
263
+ ChineseCalendar,
264
+ JapaneseCalendar,
265
+ BuddhistCalendar,
266
+ } from "time-guard/calendars";
267
+
268
+ // Get calendar manager
269
+ const calendarMgr = CalendarManager.getInstance();
270
+
271
+ // List available calendars
272
+ console.log(calendarMgr.list());
273
+ // ['gregory', 'islamic', 'hebrew', 'chinese', 'japanese', 'buddhist']
274
+
275
+ // Register custom calendar
276
+ const islamic = new IslamicCalendar();
277
+ calendarMgr.register(islamic);
278
+
279
+ // Get calendar info
280
+ const gregorian = calendarMgr.get("gregory");
281
+ console.log(gregorian.getMonthName(3)); // "March"
282
+ console.log(gregorian.getMonthName(3, true)); // "Mar"
283
+ console.log(gregorian.getWeekdayName(1)); // "Sunday"
284
+ console.log(gregorian.isLeapYear(2024)); // true
285
+ ```
286
+
287
+ ### Calendar Objects
288
+
289
+ #### Gregorian Calendar
290
+
291
+ ```typescript
292
+ import { GregorianCalendar } from "time-guard/calendars";
293
+
294
+ const calendar = new GregorianCalendar();
295
+ console.log(calendar.daysInMonth(2024, 2)); // 29 (leap year)
296
+ console.log(calendar.daysInYear(2024)); // 366
297
+ ```
298
+
299
+ #### Islamic Calendar (Hijri)
300
+
301
+ ```typescript
302
+ import { IslamicCalendar } from "time-guard/calendars";
303
+
304
+ const calendar = new IslamicCalendar();
305
+ console.log(calendar.getMonthName(9)); // "Ramadan"
306
+ console.log(calendar.isLeapYear(1445)); // true
307
+ ```
308
+
309
+ #### Hebrew Calendar
310
+
311
+ ```typescript
312
+ import { HebrewCalendar } from "time-guard/calendars";
313
+
314
+ const calendar = new HebrewCalendar();
315
+ console.log(calendar.getMonthName(1)); // "Tishrei"
316
+ console.log(calendar.isLeapYear(5784)); // true
317
+ ```
318
+
319
+ #### Chinese Calendar
320
+
321
+ ```typescript
322
+ import { ChineseCalendar } from "time-guard/calendars";
323
+
324
+ const calendar = new ChineseCalendar();
325
+ const zodiac = calendar.getZodiacSign(2024); // "龙" (Dragon)
326
+ ```
327
+
328
+ #### Japanese Calendar
329
+
330
+ ```typescript
331
+ import { JapaneseCalendar } from "time-guard/calendars";
332
+
333
+ const calendar = new JapaneseCalendar();
334
+ console.log(calendar.getMonthName(3)); // "3月"
335
+ ```
336
+
337
+ #### Buddhist Calendar
338
+
339
+ ```typescript
340
+ import { BuddhistCalendar } from "time-guard/calendars";
341
+
342
+ const calendar = new BuddhistCalendar();
343
+ // Year 2567 BE = 2024 CE
344
+ console.log(calendar.isLeapYear(2567)); // true
345
+ ```
346
+
347
+ ---
348
+
349
+ ## � Plugins
350
+
351
+ TimeGuard includes an optional plugin system for extended functionality:
352
+
353
+ ### Available Plugins
354
+
355
+ 1. **Relative Time Plugin** - Human-readable time differences
356
+
357
+ ```typescript
358
+ import { TimeGuard, PluginManager } from "time-guard";
359
+ import relativeTimePlugin from "time-guard/plugins/relative-time";
360
+
361
+ PluginManager.use(relativeTimePlugin, TimeGuard);
362
+
363
+ TimeGuard.from("2024-01-01").fromNow(); // "2 months ago"
364
+ TimeGuard.from("2024-04-01").toNow(); // "in 19 days"
365
+ ```
366
+
367
+ 2. **Duration Plugin** - ISO 8601 duration support
368
+
369
+ ```typescript
370
+ import { Duration } from "time-guard/plugins/duration";
371
+
372
+ const duration = Duration.fromISO("P2Y3M4D");
373
+ duration.humanize(); // "2 years, 3 months, 4 days"
374
+ duration.asDays(); // 1159
375
+ ```
376
+
377
+ 3. **Advanced Format Plugin** - Extended format tokens
378
+
379
+ ```typescript
380
+ import advancedFormatPlugin from "time-guard/plugins/advanced-format";
381
+
382
+ PluginManager.use(advancedFormatPlugin, TimeGuard);
383
+
384
+ date.format("Do MMMM YYYY"); // "13th March 2024"
385
+ date.format("Q [Q] YYYY"); // "1 Q 2024"
386
+ ```
387
+
388
+ **📖 Full Details:** See [PLUGINS.md](PLUGINS.md) for complete plugin documentation.
389
+
390
+ ---
391
+
392
+ ## �📚 Documentation
393
+
394
+ ### Main Documentation Files
395
+
396
+ | Document | Purpose |
397
+ | ------------------------------------- | ------------------------------------------------------------------------- |
398
+ | [📖 ARCHITECTURE.md](ARCHITECTURE.md) | Deep dive into design patterns, SOLID principles, and system architecture |
399
+ | [💡 EXAMPLES.md](EXAMPLES.md) | Real-world usage examples and common scenarios |
400
+ | [🌍 LOCALES.md](LOCALES.md) | Complete guide to localization and supported languages |
401
+ | [� PLUGINS.md](PLUGINS.md) | Plugin system documentation and usage guide |
402
+ | [�📖 API Reference](#api-overview) | Quick API reference (below) |
403
+
404
+ ### Quick Navigation
405
+
406
+ - **Getting Started** → Start with [Quick Start](#quick-start) above
407
+ - **Advanced Usage** → See [EXAMPLES.md](EXAMPLES.md)
408
+ - **Localization** → See [LOCALES.md](LOCALES.md)
409
+ - **Architecture** → See [ARCHITECTURE.md](ARCHITECTURE.md)
410
+
411
+ ## 🌍 Supported Locales - Complete Guide
412
+
413
+ TimeGuard provides **40+ languages and regional variants** with full internationalization support. Locales are organized by language family for easy discovery.
414
+
415
+ ### Locale Code Format
416
+
417
+ Locale codes follow the standard `[language]-[region]` pattern:
418
+
419
+ - `en` - Default form (used if region variant not specified)
420
+ - `en-gb` - Specific region variant (Great Britain)
421
+ - `es-mx` - Spanish variant for Mexico
422
+ - `zh-cn` - Simplified Chinese
423
+
424
+ ### Available Locales by Family
425
+
426
+ #### 🇬🇧 English (4 variants)
427
+
428
+ - `en` - English (US)
429
+ - `en-au` - English (Australia)
430
+ - `en-gb` - English (Great Britain)
431
+ - `en-ca` - English (Canada)
432
+
433
+ ### Spanish (3 variants)
434
+
435
+ - `es` - Spanish (Spain)
436
+ - `es-mx` - Spanish (Mexico)
437
+ - `es-us` - Spanish (US)
438
+
439
+ ### Romance Languages (5)
440
+
441
+ - `fr` - French
442
+ - `it` - Italian
443
+ - `pt` - Portuguese (Portugal)
444
+ - `pt-br` - Portuguese (Brazil)
445
+ - `ro` - Romanian
446
+
447
+ ### Slavic Languages (4)
448
+
449
+ - `ru` - Russian
450
+ - `pl` - Polish
451
+ - `cs` - Czech
452
+ - `sk` - Slovak
453
+
454
+ ### Nordic Languages (4)
455
+
456
+ - `sv` - Swedish
457
+ - `nb` - Norwegian (Bokmål)
458
+ - `da` - Danish
459
+ - `fi` - Finnish
460
+
461
+ ### Asian Languages (7)
462
+
463
+ - `ja` - Japanese
464
+ - `zh-cn` - Chinese (Simplified)
465
+ - `zh-tw` - Chinese (Traditional)
466
+ - `ko` - Korean
467
+ - `th` - Thai
468
+ - `vi` - Vietnamese
469
+ - `id` - Indonesian
470
+
471
+ ### European Languages (7)
472
+
473
+ - `de` - German
474
+ - `nl` - Dutch
475
+ - `el` - Greek
476
+ - `hu` - Hungarian
477
+ - `eu` - Basque
478
+ - `ca` - Catalan
479
+ - `tr` - Turkish
480
+
481
+ ### Middle Eastern & South Asian (3)
482
+
483
+ - `ar` - Arabic
484
+ - `he` - Hebrew
485
+ - `hi` - Hindi
486
+
487
+ ---
488
+
489
+ ### Locale Usage Guide
490
+
491
+ #### Setting Locales
492
+
493
+ ```typescript
494
+ import { TimeGuard } from "time-guard";
495
+
496
+ const date = TimeGuard.from("2024-03-13 14:30:00");
497
+
498
+ // Get current locale
499
+ const currentLocale = date.locale(); // "en"
500
+
501
+ // Change locale (returns new instance)
502
+ const spanish = date.locale("es");
503
+ const french = date.locale("fr");
504
+ const japanese = date.locale("ja");
505
+ const arabic = date.locale("ar");
506
+
507
+ // Chain operations
508
+ date.locale("es").format("dddd, DD MMMM YYYY"); // miércoles, 13 marzo 2024
509
+
510
+ // Or use constructor config
511
+ TimeGuard.from("2024-03-13", { locale: "de" });
512
+ TimeGuard.now({ locale: "ja" });
513
+ ```
514
+
515
+ #### Formatting in Different Locales
516
+
517
+ ```typescript
518
+ const date = TimeGuard.from("2024-03-13");
519
+
520
+ // English variants
521
+ date.locale("en").format("MMMM DD, YYYY"); // March 13, 2024
522
+ date.locale("en-gb").format("DD MMMM YYYY"); // 13 March 2024
523
+ date.locale("en-au").format("DD/MM/YYYY"); // 13/03/2024
524
+ date.locale("en-ca").format("YYYY-MM-DD"); // 2024-03-13
525
+
526
+ // Spanish variants
527
+ date.locale("es").format("DD MMMM YYYY"); // 13 marzo 2024
528
+ date.locale("es-mx").format("DD/MM/YYYY"); // 13/03/2024
529
+ date.locale("es-us").format("MMMM D"); // marzo 13
530
+
531
+ // Romance languages
532
+ date.locale("fr").format("dddd D MMMM YYYY"); // mercredi 13 mars 2024
533
+ date.locale("it").format("dddd, D MMMM YYYY"); // mercoledì, 13 marzo 2024
534
+ date.locale("pt").format("dddd, D MMMM YYYY"); // quarta-feira, 13 de março de 2024
535
+ date.locale("pt-br").format("DD/MM/YYYY"); // 13/03/2024
536
+ date.locale("ro").format("DD MMMM YYYY"); // 13 martie 2024
537
+
538
+ // Slavic languages
539
+ date.locale("ru").format("DD MMMM YYYY"); // 13 марта 2024
540
+ date.locale("pl").format("DD MMMM YYYY"); // 13 marca 2024
541
+ date.locale("cs").format("DD. MMMM YYYY"); // 13. března 2024
542
+ date.locale("sk").format("DD. MMMM YYYY"); // 13. marca 2024
543
+
544
+ // Nordic languages
545
+ date.locale("sv").format("DD MMMM YYYY"); // 13 mars 2024
546
+ date.locale("nb").format("DD. MMMM YYYY"); // 13. mars 2024
547
+ date.locale("da").format("DD. MMMM YYYY"); // 13. marts 2024
548
+ date.locale("fi").format("DD. MMMM YYYY"); // 13. maaliskuuta 2024
549
+
550
+ // Asian languages
551
+ date.locale("ja").format("YYYY年M月D日"); // 2024年3月13日
552
+ date.locale("zh-cn").format("YYYY年M月D日"); // 2024年3月13日
553
+ date.locale("zh-tw").format("YYYY年M月D日"); // 2024年3月13日
554
+ date.locale("ko").format("YYYY년 M월 D일"); // 2024년 3월 13일
555
+ date.locale("th").format("DD MMMM YYYY"); // 13 มีนาคม 2567 (BE)
556
+ date.locale("vi").format("DD/MM/YYYY"); // 13/03/2024
557
+ date.locale("id").format("DD MMMM YYYY"); // 13 Maret 2024
558
+
559
+ // European languages
560
+ date.locale("de").format("DD. MMMM YYYY"); // 13. März 2024
561
+ date.locale("nl").format("DD MMMM YYYY"); // 13 maart 2024
562
+ date.locale("el").format("DD MMMM YYYY"); // 13 Μαρτίου 2024
563
+ date.locale("hu").format("YYYY. MMMM DD."); // 2024. március 13.
564
+ date.locale("eu").format("YYYY[ko] MMMM[ren] DD"); // 2024ko martsaren 13
565
+ date.locale("ca").format("DD MMMM YYYY"); // 13 de març de 2024
566
+ date.locale("tr").format("DD MMMM YYYY"); // 13 Mart 2024
567
+
568
+ // Middle Eastern & South Asian
569
+ date.locale("ar").format("DD MMMM YYYY"); // 13 مارس 2024
570
+ date.locale("he").format("DD.MM.YYYY"); // 13.03.2024
571
+ date.locale("hi").format("DD MMMM YYYY"); // 13 मार्च 2024
572
+ ```
573
+
574
+ #### Day and Month Names
575
+
576
+ ```typescript
577
+ // Get localized day names
578
+ date.locale("es").format("dddd"); // miércoles
579
+ date.locale("es").format("ddd"); // mié
580
+ date.locale("fr").format("dddd"); // mercredi
581
+ date.locale("de").format("dddd"); // Mittwoch
582
+ date.locale("ja").format("dddd"); // 水曜日
583
+
584
+ // Get localized month names
585
+ date.locale("es").format("MMMM"); // marzo
586
+ date.locale("es").format("MMM"); // mar
587
+ date.locale("fr").format("MMMM"); // mars
588
+ date.locale("de").format("MMMM"); // März
589
+ date.locale("ru").format("MMMM"); // марта
590
+ ```
591
+
592
+ #### Multi-Locale Applications
593
+
594
+ ```typescript
595
+ // Switch language at runtime (user preference)
596
+ let currentLocale = "en";
597
+
598
+ function formatUserDate(
599
+ date: TimeGuard,
600
+ locale: string = currentLocale,
601
+ ): string {
602
+ return date.locale(locale).format("dddd, MMMM D, YYYY [at] HH:mm");
603
+ }
604
+
605
+ const date = TimeGuard.now();
606
+
607
+ // English user
608
+ console.log(formatUserDate(date, "en")); // Wednesday, March 13, 2024 at 14:30
609
+
610
+ // Spanish user
611
+ currentLocale = "es";
612
+ console.log(formatUserDate(date, "es")); // miércoles, 13 de marzo de 2024 a las 14:30
613
+
614
+ // French user
615
+ console.log(formatUserDate(date, "fr")); // mercredi, 13 mars 2024 à 14:30
616
+
617
+ // Japanese user
618
+ console.log(formatUserDate(date, "ja")); // 水曜日、2024年3月13日 14:30
619
+ ```
620
+
621
+ #### Getting Available Locales Programmatically
622
+
623
+ ```typescript
624
+ // Get all available locales
625
+ const locales = TimeGuard.getAvailableLocales();
626
+ // Returns: ['en', 'en-au', 'en-gb', 'en-ca', 'es', 'es-mx', 'es-us', ...]
627
+
628
+ // Filter by prefix
629
+ const englishLocales = locales.filter((l) => l.startsWith("en"));
630
+ const spanishLocales = locales.filter((l) => l.startsWith("es"));
631
+ const asianLocales = locales.filter((l) =>
632
+ ["ja", "zh-cn", "zh-tw", "ko"].includes(l),
633
+ );
634
+
635
+ // Create locale selector UI
636
+ function createLocaleSelector() {
637
+ const locales = TimeGuard.getAvailableLocales();
638
+ return locales.map((locale) => ({
639
+ code: locale,
640
+ label: new Intl.DisplayNames("en", { type: "language" }).of(locale),
641
+ }));
642
+ }
643
+ ```
644
+
645
+ **📖 Full Details:** See [LOCALES.md](LOCALES.md) for locale-specific usage and characteristics.
646
+
647
+ ---
648
+
649
+ ## 🔌 Plugins - Complete Guide
650
+
651
+ TimeGuard includes a powerful plugin system for extending functionality. Plugins follow SOLID principles and are fully optional.
652
+
653
+ ### Plugin Manager
654
+
655
+ ```typescript
656
+ import { TimeGuard, PluginManager } from "time-guard";
657
+
658
+ // Use a plugin
659
+ PluginManager.use(myPlugin, TimeGuard);
660
+
661
+ // Check if plugin is installed
662
+ PluginManager.isInstalled(pluginName);
663
+
664
+ // List installed plugins
665
+ PluginManager.listInstalled();
666
+ ```
667
+
668
+ ### 1️⃣ Relative Time Plugin
669
+
670
+ Adds human-readable time differences like "2 hours ago" or "in 3 days".
671
+
672
+ ```typescript
673
+ import { TimeGuard, PluginManager } from "time-guard";
674
+ import relativeTimePlugin from "time-guard/plugins/relative-time";
675
+
676
+ // Install plugin once
677
+ PluginManager.use(relativeTimePlugin, TimeGuard);
678
+
679
+ // Now use relative time methods
680
+ const date = TimeGuard.from("2024-01-15");
681
+
682
+ // Relative to now
683
+ date.fromNow(); // "2 months ago"
684
+ date.toNow(); // "in 2 months"
685
+
686
+ // Without suffix
687
+ date.fromNow(true); // "2 months"
688
+ date.toNow(true); // "2 months"
689
+
690
+ // Relative to another date
691
+ const other = TimeGuard.from("2024-02-15");
692
+ date.from(other); // "a month ago"
693
+ date.to(other); // "in a month"
694
+
695
+ // Humanize duration
696
+ date.humanize(other); // "a month"
697
+ date.humanize(other, true); // "a month" (exact mode)
698
+ ```
699
+
700
+ **Supported Relative Time Formats:**
701
+
702
+ ```
703
+ "a few seconds ago" // Very recent
704
+ "a minute ago" / "2 minutes ago"
705
+ "an hour ago" / "3 hours ago"
706
+ "a day ago" / "5 days ago"
707
+ "a month ago" / "2 months ago"
708
+ "a year ago" / "3 years ago"
709
+ "in a few seconds" // Future
710
+ "in a minute" / "in 2 minutes"
711
+ "in an hour" / "in 3 hours"
712
+ "in a day" / "in 5 days"
713
+ "in a month" / "in 2 months"
714
+ "in a year" / "in 3 years"
715
+ ```
716
+
717
+ ---
718
+
719
+ ### 2️⃣ Duration Plugin
720
+
721
+ ISO 8601 duration support with advanced calculations.
722
+
723
+ ```typescript
724
+ import { TimeGuard } from "time-guard";
725
+ import { Duration, durationPlugin } from "time-guard/plugins/duration";
726
+ import { PluginManager } from "time-guard";
727
+
728
+ // Install plugin
729
+ PluginManager.use(durationPlugin, TimeGuard);
730
+
731
+ // ===== Create Durations =====
732
+
733
+ // From object
734
+ const duration1 = new Duration({
735
+ years: 2,
736
+ months: 3,
737
+ days: 4,
738
+ hours: 12,
739
+ minutes: 30,
740
+ });
741
+
742
+ // From ISO 8601 string
743
+ const duration2 = Duration.fromISO("P3Y6M4DT12H30M5S");
744
+ // P = Period marker
745
+ // 3Y = 3 years
746
+ // 6M = 6 months
747
+ // 4D = 4 days
748
+ // T = Time marker
749
+ // 12H = 12 hours
750
+ // 30M = 30 minutes
751
+ // 5S = 5 seconds
752
+
753
+ // From TimeGuard dates
754
+ const start = TimeGuard.from("2024-01-15");
755
+ const end = TimeGuard.from("2024-05-20");
756
+ const between = Duration.between(start, end);
757
+ // { years: 0, months: 4, days: 5, ... }
758
+
759
+ // ===== Duration Operations =====
760
+
761
+ // Get ISO string
762
+ duration1.toISO(); // "P2Y3M4DT12H30M"
763
+
764
+ // Get total in different units
765
+ duration1.asDays(); // Total days
766
+ duration1.asHours(); // Total hours
767
+ duration1.asSeconds(); // Total seconds
768
+ duration1.asMilliseconds(); // Total milliseconds
769
+
770
+ // Humanize
771
+ duration1.humanize(); // "2 years, 3 months, 4 days, 12 hours, 30 minutes"
772
+ duration1.humanize("es"); // Spanish: "2 años, 3 meses..."
773
+ duration1.humanize("fr"); // French: "2 ans, 3 mois..."
774
+
775
+ // Get components
776
+ duration1.years;
777
+ duration1.months;
778
+ duration1.days;
779
+ duration1.hours;
780
+ duration1.minutes;
781
+ duration1.seconds;
782
+ duration1.milliseconds;
783
+
784
+ // Clone
785
+ const copy = duration1.clone();
786
+
787
+ // Arithmetic
788
+ duration1.add(new Duration({ days: 5 }));
789
+ duration1.subtract(new Duration({ hours: 2 }));
790
+ duration1.multiply(2); // Double the duration
791
+ duration1.negate(); // Reverse direction
792
+ ```
793
+
794
+ **ISO 8601 Duration Examples:**
795
+
796
+ ```typescript
797
+ Duration.fromISO("P1Y"); // 1 year
798
+ Duration.fromISO("P3M"); // 3 months
799
+ Duration.fromISO("P1W"); // 1 week (7 days)
800
+ Duration.fromISO("P1D"); // 1 day
801
+ Duration.fromISO("PT1H"); // 1 hour
802
+ Duration.fromISO("PT30M"); // 30 minutes
803
+ Duration.fromISO("PT45S"); // 45 seconds
804
+ Duration.fromISO("P1Y2M3DT4H5M6S"); // Complex: 1 year, 2 months, ...
805
+ Duration.fromISO("-P1D"); // Negative: -1 day
806
+ ```
807
+
808
+ ---
809
+
810
+ ### 3️⃣ Advanced Format Plugin
811
+
812
+ Extended format tokens for specialized formatting needs.
813
+
814
+ ```typescript
815
+ import { TimeGuard, PluginManager } from "time-guard";
816
+ import advancedFormatPlugin from "time-guard/plugins/advanced-format";
817
+
818
+ // Install plugin
819
+ PluginManager.use(advancedFormatPlugin, TimeGuard);
820
+
821
+ const date = TimeGuard.from("2024-03-13 14:30:00");
822
+
823
+ // Advanced tokens become available
824
+ date.format("Do MMMM YYYY"); // "13th March 2024"
825
+ date.format("Q [Q] YYYY"); // "1 Q 2024"
826
+ date.format("[Week] w, YYYY"); // "Week 11, 2024"
827
+ date.format("W [of] ww"); // "11 of 11"
828
+ date.format("gggg-[W]ww"); // "2024-W11" (ISO week)
829
+ date.format("GGGG-[W]WW"); // 2024-W11 (alternative)
830
+
831
+ // Timezone abbreviation
832
+ date.format("HH:mm zzz"); // "14:30 UTC"
833
+
834
+ // 24-hour (k = 1-24 instead of 0-23)
835
+ date.format("k:mm"); // "14:30"
836
+
837
+ // Unix timestamps
838
+ date.format("X"); // Unix seconds
839
+ date.format("x"); // Unix milliseconds
840
+ ```
841
+
842
+ **Advanced Format Tokens:**
843
+
844
+ ```
845
+ Q // Quarter (1, 2, 3, 4)
846
+ Do // Ordinal day (1st, 2nd, 3rd, etc.)
847
+ w // Week of year (no padding)
848
+ ww // Week of year (zero-padded)
849
+ W // ISO week number
850
+ gggg // ISO week year
851
+ GGGG // Alternative ISO week year
852
+ k / kk // 24-hour format (1-24)
853
+ X // Unix seconds
854
+ x // Unix milliseconds
855
+ zzz // Timezone abbreviation (UTC, EST, etc.)
856
+ ```
857
+
858
+ ---
859
+
860
+ ### Plugin Architecture
861
+
862
+ All plugins implement `ITimeGuardPlugin`:
863
+
864
+ ```typescript
865
+ interface ITimeGuardPlugin {
866
+ name: string;
867
+ version: string;
868
+ install(TimeGuardClass: typeof TimeGuard): void;
869
+ }
870
+ ```
871
+
872
+ ### Creating Custom Plugins
873
+
874
+ ```typescript
875
+ import { TimeGuard } from "time-guard";
876
+ import type { ITimeGuardPlugin } from "time-guard/types";
877
+
878
+ class MyCustomPlugin implements ITimeGuardPlugin {
879
+ name = "my-plugin";
880
+ version = "1.0.0";
881
+
882
+ install(TimeGuardClass: typeof TimeGuard): void {
883
+ // Add method to TimeGuard prototype
884
+ (TimeGuardClass.prototype as any).myMethod = function () {
885
+ return "Hello from my plugin!";
886
+ };
887
+ }
888
+ }
889
+
890
+ // Use it
891
+ const plugin = new MyCustomPlugin();
892
+ PluginManager.use(plugin, TimeGuard);
893
+
894
+ // Now available
895
+ const date = TimeGuard.now();
896
+ date.myMethod(); // "Hello from my plugin!"
897
+ ```
898
+
899
+ **📖 Full Plugin Details:** See [PLUGINS.md](PLUGINS.md) for extended documentation.
900
+
901
+ ---
902
+
903
+ ## 🎯 Complete API Reference
904
+
905
+ ### Factory Methods
906
+
907
+ ```typescript
908
+ // Create current date/time
909
+ TimeGuard.now();
910
+ TimeGuard.now({ locale: "es", timezone: "America/Mexico_City" });
911
+
912
+ // Create from various inputs
913
+ TimeGuard.from("2024-03-13");
914
+ TimeGuard.from("2024-03-13T14:30:00");
915
+ TimeGuard.from(new Date());
916
+ TimeGuard.from(1234567890000); // milliseconds
917
+ TimeGuard.from(1234567890, { timezone: "UTC" }); // seconds
918
+ TimeGuard.from("2024-03-13", { locale: "es" });
919
+
920
+ // Create from Temporal object
921
+ TimeGuard.fromTemporal(temporalPlainDateTime, config);
922
+ ```
923
+
924
+ ### 🔄 Conversion Methods
925
+
926
+ ```typescript
927
+ const date = TimeGuard.from("2024-03-13 14:30:45");
928
+
929
+ date.toDate(); // Convert to JavaScript Date
930
+ date.toTemporal(); // Get underlying Temporal object
931
+ date.toISOString(); // ISO 8601: "2024-03-13T14:30:45Z"
932
+ date.toJSON(); // JSON serialization (ISO string)
933
+ date.toString(); // Human readable: "2024-03-13 14:30:45"
934
+
935
+ date.valueOf(); // Milliseconds since epoch
936
+ date.unix(); // Seconds since epoch
937
+ ```
938
+
939
+ ### ➕ Manipulation Methods
940
+
941
+ ```typescript
942
+ const date = TimeGuard.from("2024-03-13 14:30:00");
943
+
944
+ // Add time - accepts partial record of units
945
+ date.add({ days: 5 });
946
+ date.add({ months: 1, days: 5 });
947
+ date.add({ years: 1, hours: 2, minutes: 30 });
948
+
949
+ // Subtract time - same syntax as add
950
+ date.subtract({ days: 5 });
951
+ date.subtract({ months: 1 });
952
+
953
+ // Set specific component(s)
954
+ date.set({ day: 15 }); // Keep other components
955
+ date.set({ hour: 10, minute: 0 });
956
+ date.set({ year: 2025, month: 1, day: 1 });
957
+
958
+ // Start/End of period
959
+ date.startOf("year"); // 2024-01-01 00:00:00
960
+ date.startOf("month"); // 2024-03-01 00:00:00
961
+ date.startOf("day"); // 2024-03-13 00:00:00
962
+ date.startOf("hour"); // 2024-03-13 14:00:00
963
+ date.endOf("year"); // 2024-12-31 23:59:59
964
+ date.endOf("month"); // 2024-03-31 23:59:59
965
+
966
+ date.clone(); // Create independent copy
967
+ ```
968
+
969
+ ### 🔍 Component Accessors (Getters)
970
+
971
+ ```typescript
972
+ const date = TimeGuard.from("2024-03-13 14:30:45.123");
973
+
974
+ // Date components
975
+ date.year(); // 2024
976
+ date.month(); // 3 (January = 1, December = 12)
977
+ date.day(); // 13
978
+ date.quarter(); // 1 (Q1, Q2, Q3, or Q4)
979
+
980
+ // Time components
981
+ date.hour(); // 14
982
+ date.minute(); // 30
983
+ date.second(); // 45
984
+ date.millisecond(); // 123
985
+
986
+ // Week/Day information
987
+ date.dayOfWeek(); // 3 (1=Sunday, 7=Saturday)
988
+ date.dayOfYear(); // 73
989
+ date.weekOfYear(); // 11
990
+
991
+ // Month/Year information
992
+ date.daysInMonth(); // 31
993
+ date.daysInYear(); // 366 (leap year)
994
+ date.inLeapYear(); // true
995
+ ```
996
+
997
+ ### ⚖️ Comparison Methods
998
+
999
+ ```typescript
1000
+ const date1 = TimeGuard.from("2024-03-13");
1001
+ const date2 = TimeGuard.from("2024-03-20");
1002
+
1003
+ // Direct comparison
1004
+ date1.isBefore(date2); // true
1005
+ date1.isAfter(date2); // false
1006
+ date1.isSame(date1); // true
1007
+
1008
+ // Unit-specific comparison
1009
+ date1.isSame(date2, "month"); // true (same month)
1010
+ date1.isSame(date2, "year"); // true (same year)
1011
+ date1.isSame(date2, "day"); // false (different day)
1012
+
1013
+ // Range checking
1014
+ date1.isBetween(date1, date2); // true
1015
+ date1.isBetween(date1, date2, undefined, "[]"); // inclusive both ends
1016
+ date1.isBetween(date1, date2, undefined, "()"); // exclusive both ends
1017
+ date1.isBetween(date1, date2, "month", "[]"); // granular range
1018
+
1019
+ // Calculate difference
1020
+ date1.diff(date2, "days"); // -7
1021
+ date1.diff(date2, "millisecond"); // difference in ms
1022
+ date1.diff(date2, "months"); // -0
1023
+ ```
1024
+
1025
+ ### 📊 Advanced Calculations
1026
+
1027
+ ```typescript
1028
+ const date = TimeGuard.from("2024-01-15");
1029
+ const future = TimeGuard.from("2024-05-20");
1030
+
1031
+ // Duration: Get complete breakdown
1032
+ const duration = date.until(future);
1033
+ // { years: 0, months: 4, days: 5, hours: 0, minutes: 0, seconds: 0, milliseconds: 0 }
1034
+
1035
+ // Rounding: Precision control
1036
+ date.round({ smallestUnit: "millisecond" }); // Default, no change
1037
+ date.round({ smallestUnit: "second" }); // Removes milliseconds
1038
+ date.round({ smallestUnit: "minute" }); // 2024-03-13 14:30:00
1039
+ date.round({ smallestUnit: "hour" }); // 2024-03-13 14:00:00
1040
+ date.round({ smallestUnit: "day" }); // 2024-03-13 00:00:00
1041
+
1042
+ // Rounding modes
1043
+ date.round({
1044
+ smallestUnit: "minute",
1045
+ roundingMode: "halfExpand", // Default: round to nearest
1046
+ });
1047
+
1048
+ date.round({
1049
+ smallestUnit: "minute",
1050
+ roundingMode: "ceil", // Always round up
1051
+ });
1052
+ ```
1053
+
1054
+ ### 🌍 Locale & Timezone
1055
+
1056
+ ```typescript
1057
+ const date = TimeGuard.from("2024-03-13 14:30:00");
1058
+
1059
+ // Get/Set locale
1060
+ date.locale(); // Returns current locale: 'en'
1061
+ date.locale("es"); // Set locale, returns new instance
1062
+
1063
+ // Format in different locales
1064
+ date.format("YYYY-MM-DD"); // 2024-03-13
1065
+ date.locale("es").format("DD MMMM YYYY"); // 13 marzo 2024
1066
+ date.locale("es-mx").format("DD/MM/YYYY"); // 13/03/2024
1067
+ date.locale("fr").format("dddd, DD MMMM YYYY"); // mercredi, 13 mars 2024
1068
+ date.locale("de").format("DD. MMMM YYYY"); // 13. März 2024
1069
+ date.locale("ja").format("YYYY年M月D日"); // 2024年3月13日
1070
+ date.locale("zh-cn").format("YYYY年M月D日"); // 2024年3月13日
1071
+ date.locale("ar").format("DD MMMM YYYY"); // 13 مارس 2024
1072
+
1073
+ // Get/Set timezone
1074
+ date.timezone(); // Returns current timezone: 'UTC'
1075
+ const inNYC = date.timezone("America/New_York");
1076
+ const inTokyo = date.timezone("Asia/Tokyo");
1077
+ const inDubai = date.timezone("Asia/Dubai");
1078
+
1079
+ // Format with timezone info
1080
+ inNYC.format("YYYY-MM-DD HH:mm:ss Z"); // 2024-03-13 10:30:00 -04:00
1081
+ inTokyo.format("YYYY-MM-DD HH:mm:ss Z"); // 2024-03-13 23:30:00 +09:00
1082
+
1083
+ // Get all available locales
1084
+ TimeGuard.getAvailableLocales(); // Array of 40+ locale codes
1085
+ ```
1086
+
1087
+ ### 🎨 Format Patterns
1088
+
1089
+ #### Format Presets
1090
+
1091
+ ```typescript
1092
+ const date = TimeGuard.from("2024-03-13 14:30:45.123");
1093
+
1094
+ // Built-in presets
1095
+ date.format("iso"); // 2024-03-13T14:30:45.123Z
1096
+ date.format("date"); // 2024-03-13
1097
+ date.format("time"); // 14:30:45
1098
+ date.format("datetime"); // 2024-03-13 14:30:45
1099
+ date.format("rfc2822"); // Wed, 13 Mar 2024 14:30:45 +0000
1100
+ date.format("rfc3339"); // 2024-03-13T14:30:45Z
1101
+ date.format("utc"); // 2024-03-13T14:30:45.123Z
1102
+ ```
1103
+
1104
+ #### Format Tokens
1105
+
1106
+ ```typescript
1107
+ // Year
1108
+ 'YYYY' // 2024 (4-digit)
1109
+ 'YY' // 24 (2-digit)
1110
+
1111
+ // Month
1112
+ 'MMMM' // March
1113
+ 'MMM' // Mar
1114
+ 'MM' // 03 (zero-padded)
1115
+ 'M' // 3 (no padding)
1116
+
1117
+ // Day
1118
+ 'DDDD' or 'DDD' // Monday (full day name)
1119
+ 'ddd' // Mon (abbreviated)
1120
+ 'DD' // 13 (zero-padded)
1121
+ 'D' // 13 (no padding)
1122
+
1123
+ // Hours, minutes, seconds
1124
+ 'HH' // 14 (24-hour, zero-padded)
1125
+ 'H' // 14
1126
+ 'hh' // 02 (12-hour, zero-padded)
1127
+ 'h' // 2
1128
+ 'mm' // 30
1129
+ 'm' // 30
1130
+ 'ss' // 45
1131
+ 's' // 45
1132
+ 'A' // AM or PM
1133
+ 'a' // am or pm
1134
+
1135
+ // Milliseconds & Week
1136
+ 'SSS' // 123 (milliseconds)
1137
+ 'SS' // 12
1138
+ 'S' // 1
1139
+ 'ww' // 11 (week with padding)
1140
+ 'w' // 11 (week no padding)
1141
+
1142
+ // Escaped text
1143
+ '[text]' // Protects text: [UTC]
1144
+ '"text"' // Alternative protection: "o'clock"
1145
+ ```
1146
+
1147
+ #### Custom Format Examples
1148
+
1149
+ ```typescript
1150
+ date.format("YYYY-MM-DD"); // 2024-03-13
1151
+ date.format("DD/MM/YYYY"); // 13/03/2024
1152
+ date.format("MMMM D, YYYY"); // March 13, 2024
1153
+ date.format("dddd, MMMM D, YYYY"); // Wednesday, March 13, 2024
1154
+ date.format("DD-MMMM-YY"); // 13-Mar-24
1155
+ date.format("h:mm A"); // 2:30 PM
1156
+ date.format("HH:mm:ss"); // 14:30:45
1157
+ date.format("[Today is] dddd"); // Today is Wednesday
1158
+ date.format("HH:mm [UTC]"); // 14:30 UTC
1159
+ date.format('DD/MM/YYYY "at" HH:mm'); // 13/03/2024 at 14:30
1160
+ ```
1161
+
1162
+ **📖 Complete Format Guide:** See [EXAMPLES.md](EXAMPLES.md) for more patterns and use cases.
1163
+
1164
+ ---
1165
+
1166
+ ## 🧪 Testing
1167
+
1168
+ TimeGuard includes **530+ comprehensive tests** covering:
1169
+
1170
+ - ✅ Core functionality (creation, manipulation, querying)
1171
+ - ✅ Advanced features (timezones, locales, formatting)
1172
+ - ✅ Edge cases (leap years, month boundaries, DST)
1173
+ - ✅ SOLID principle validation
1174
+ - ✅ Type safety verification
1175
+
1176
+ ### Run Tests
1177
+
1178
+ ```bash
1179
+ # Run all tests
1180
+ npm test
1181
+
1182
+ # Run with coverage
1183
+ npm test -- --coverage
1184
+
1185
+ # Run specific test file
1186
+ npm test -- locales.test.ts
1187
+
1188
+ # Watch mode
1189
+ npm test -- --watch
1190
+ ```
1191
+
1192
+ ### Test Coverage
1193
+
1194
+ ```
1195
+ Core functionality: 65+ tests
1196
+ Advanced features: 50+ tests
1197
+ Locale support: 100+ tests
1198
+ Integration scenarios: 250+ tests
1199
+ Edge cases: 65+ tests
1200
+ ```
1201
+
1202
+ ---
1203
+
1204
+ ## 🏛️ Architecture
1205
+
1206
+ TimeGuard is built on **SOLID principles** ensuring clean, maintainable, and extensible code:
1207
+
1208
+ ### Key Principles
1209
+
1210
+ - **Single Responsibility** - Each class has one reason to change
1211
+ - **Open/Closed** - Open for extension, closed for modification
1212
+ - **Liskov Substitution** - Proper interface contracts
1213
+ - **Interface Segregation** - Minimal, focused interfaces
1214
+ - **Dependency Inversion** - Depend on abstractions, not concretions
1215
+
1216
+ ### Design Patterns
1217
+
1218
+ - **Factory Pattern** - Date creation and parsing
1219
+ - **Adapter Pattern** - Temporal API abstraction
1220
+ - **Strategy Pattern** - Multiple formatting strategies
1221
+ - **Singleton Pattern** - Locale manager
1222
+ - **Facade Pattern** - Simple public API
1223
+ - **Immutable Pattern** - Safe data handling
1224
+
1225
+ **📖 Deep Dive:** See [ARCHITECTURE.md](ARCHITECTURE.md) for detailed architecture explanation.
1226
+
1227
+ ---
1228
+
1229
+ ## 🔧 Development
1230
+
1231
+ ### Build
1232
+
1233
+ ```bash
1234
+ # Build for production
1235
+ npm run build
1236
+
1237
+ # Watch mode for development
1238
+ npm run dev
1239
+ ```
1240
+
1241
+ ### Project Structure
1242
+
1243
+ ```
1244
+ time-guard/
1245
+ ├── src/
1246
+ │ ├── index.ts # Public API exports
1247
+ │ ├── types.ts # Type definitions
1248
+ │ ├── time-guard.ts # Main class
1249
+ │ ├── adapters/
1250
+ │ │ └── temporal.adapter.ts # Temporal API wrapper
1251
+ │ ├── formatters/
1252
+ │ │ └── date.formatter.ts # Format strategies
1253
+ │ └── locales/
1254
+ │ ├── index.ts # Locale registry
1255
+ │ ├── locale.manager.ts # Singleton manager
1256
+ │ ├── english.locale.ts # English variants
1257
+ │ ├── spanish.locale.ts # Spanish variants
1258
+ │ └── ... # 6+ more locale files
1259
+ ├── test/
1260
+ │ ├── time-guard.test.ts # Core tests
1261
+ │ ├── advanced.test.ts # Advanced tests
1262
+ │ └── locales.test.ts # Locale tests
1263
+ └── docs/
1264
+ ├── ARCHITECTURE.md # Architecture guide
1265
+ ├── EXAMPLES.md # Usage examples
1266
+ └── LOCALES.md # Locale documentation
1267
+ ```
1268
+
1269
+ ---
1270
+
1271
+ ## 🤝 Contributing
1272
+
1273
+ We welcome contributions! Please:
1274
+
1275
+ 1. Follow SOLID principles and existing code patterns
1276
+ 2. Write tests for new features
1277
+ 3. Update documentation
1278
+ 4. Ensure all tests pass (`npm test`)
1279
+ 5. Check types pass (`npx tsc --noEmit`)
1280
+
1281
+ ---
1282
+
1283
+ ## 📄 License
1284
+
1285
+ MIT License © 2024 Berea-Soft
1286
+
1287
+ See [LICENSE](LICENSE) file for details.
1288
+
1289
+ ---
1290
+
1291
+ ## 🔗 Quick Links
1292
+
1293
+ - 📖 [Full API Reference](EXAMPLES.md)
1294
+ - 🏛️ [Architecture Guide](ARCHITECTURE.md)
1295
+ - 🌍 [Localization Guide](LOCALES.md)
1296
+ - 🐛 [Issue Tracker](https://github.com/bereasoftware/time-guard/issues)
1297
+ - 💬 [Discussions](https://github.com/bereasoftware/time-guard/discussions)
1298
+
1299
+ ---
1300
+
1301
+ ## 📞 Support
1302
+
1303
+ For questions, issues, or feature requests:
1304
+
1305
+ - Open an issue on GitHub
1306
+ - Start a discussion
1307
+ - Check existing documentation
1308
+
1309
+ ---
1310
+
1311
+ ---
1312
+
1313
+ ## Built with ❤️ by Berea-Soft
1314
+
1315
+ A modern date/time library with SOLID principles and TypeScript