@bereasoftware/time-guard 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +294 -0
- package/README.md +415 -2
- package/dist/calendars/index.es.js +1 -1
- package/dist/locales/index.es.js +1 -1
- package/dist/plugins/advanced-format.es.js +1 -1
- package/dist/plugins/duration.es.js +1 -1
- package/dist/plugins/relative-time.es.js +1 -1
- package/dist/time-guard.cjs +1 -1
- package/dist/time-guard.es.js +477 -67
- package/dist/time-guard.iife.js +1 -1
- package/dist/time-guard.umd.js +1 -1
- package/dist/types/index.d.ts +3 -2
- package/dist/types/time-guard.d.ts +285 -6
- package/dist/types/types/index.d.ts +280 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -232,6 +232,120 @@ console.log(date.inLeapYear()); // true
|
|
|
232
232
|
|
|
233
233
|
## ⏱️ Cálculos Avanzados
|
|
234
234
|
|
|
235
|
+
### 🎯 API Semántica: `between()` - Sin Carga Mental
|
|
236
|
+
|
|
237
|
+
La forma **más semántica y clara** para calcular diferencias de tiempo. ¡No necesitas pensar en `until()` vs `since()`!
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
const start = TimeGuard.from("2024-01-15");
|
|
241
|
+
const end = TimeGuard.from("2024-03-20");
|
|
242
|
+
|
|
243
|
+
// Lectura simple y directa
|
|
244
|
+
TimeGuard.between(start, end).humanize();
|
|
245
|
+
// "2 months and 5 days"
|
|
246
|
+
|
|
247
|
+
// El orden NO importa - siempre positivo
|
|
248
|
+
TimeGuard.between(end, start).humanize();
|
|
249
|
+
// "2 months and 5 days" (¡idéntico!)
|
|
250
|
+
|
|
251
|
+
// Acceso a propiedades DurationParts
|
|
252
|
+
TimeGuard.between(start, end).months; // 2
|
|
253
|
+
TimeGuard.between(start, end).days; // 5
|
|
254
|
+
|
|
255
|
+
// Todas las opciones de humanize() disponibles
|
|
256
|
+
TimeGuard.between(start, end).humanize({ locale: "es", fullBreakdown: true });
|
|
257
|
+
// "2 meses y 5 días"
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**Comparación semántica:**
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
// ❌ Confuso: ¿cuál es cuál?
|
|
264
|
+
start.until(end); // ¿es positivo?
|
|
265
|
+
end.since(start); // ¿es diferente?
|
|
266
|
+
|
|
267
|
+
// ✅ Claro: no necesitas pensar
|
|
268
|
+
TimeGuard.between(start, end); // siempre positivo, sin confusión
|
|
269
|
+
TimeGuard.between(end, start); // mismo resultado, order no importa
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### 🔗 API Fluente: `range()` - Naming Killer
|
|
273
|
+
|
|
274
|
+
**Marketing técnico puro:** La API más intuitiva para rangos de fechas con **method chaining fluent**:
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
// Sintaxis limpia y directa
|
|
278
|
+
TimeGuard.range("2024-01-15", "2024-03-20").humanize();
|
|
279
|
+
// "2 months and 5 days"
|
|
280
|
+
|
|
281
|
+
TimeGuard.range("2024-01-15", "2024-03-20").inMonths();
|
|
282
|
+
// 2.1355 (valor decimal preciso)
|
|
283
|
+
|
|
284
|
+
TimeGuard.range("2024-01-15", "2024-03-20").toDuration();
|
|
285
|
+
// DurationResult: acceso completo a propiedades
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**Casos de uso empresariales:**
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
// 📅 Período de alquiler
|
|
292
|
+
const checkIn = new TimeGuard("2024-06-15");
|
|
293
|
+
const checkOut = new TimeGuard("2024-06-22");
|
|
294
|
+
|
|
295
|
+
const rentalDays = TimeGuard.range(checkIn, checkOut).in("day");
|
|
296
|
+
const rentalCost = rentalDays * 100; // $100 por día
|
|
297
|
+
console.log(rentalCost); // $700
|
|
298
|
+
|
|
299
|
+
// 💳 Cálculo de mora
|
|
300
|
+
const invoiceDate = new TimeGuard("2024-01-01");
|
|
301
|
+
const paymentDate = new TimeGuard("2024-02-15");
|
|
302
|
+
|
|
303
|
+
const lateFeePerDay = 10;
|
|
304
|
+
const lateFee =
|
|
305
|
+
TimeGuard.range(invoiceDate, paymentDate).in("day") * lateFeePerDay;
|
|
306
|
+
console.log(lateFee); // Cálculo exacto con promediado de meses
|
|
307
|
+
|
|
308
|
+
// 📊 Analítica de sesiones
|
|
309
|
+
const sessionStart = new TimeGuard("2024-03-15T10:00:00");
|
|
310
|
+
const sessionEnd = new TimeGuard("2024-03-15T10:35:42");
|
|
311
|
+
|
|
312
|
+
const engagementMinutes = TimeGuard.range(sessionStart, sessionEnd).in(
|
|
313
|
+
"minute",
|
|
314
|
+
);
|
|
315
|
+
console.log(engagementMinutes); // Para métricas de usuarios
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**Soporte de Locales:**
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
// El orden de fechas NO importa
|
|
322
|
+
TimeGuard.range("2024-03-20", "2024-01-15").humanize({ locale: "es" });
|
|
323
|
+
// "2 meses y 5 días" (resultado idéntico)
|
|
324
|
+
|
|
325
|
+
// Diferentes idiomas
|
|
326
|
+
TimeGuard.range("2024-01-15", "2024-03-20").humanize({ locale: "fr" });
|
|
327
|
+
// "2 mois et 5 jours"
|
|
328
|
+
|
|
329
|
+
TimeGuard.range("2024-01-15", "2024-03-20").humanize({ locale: "de" });
|
|
330
|
+
// "2 Monate und 5 Tage"
|
|
331
|
+
|
|
332
|
+
// Desglose completo
|
|
333
|
+
TimeGuard.range("2024-01-15", "2024-03-20").humanize({
|
|
334
|
+
locale: "es",
|
|
335
|
+
fullBreakdown: true,
|
|
336
|
+
});
|
|
337
|
+
// "2 meses y 5 días"
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**Métodos disponibles en `TimeRange`:**
|
|
341
|
+
|
|
342
|
+
| Método | Retorna | Descripción |
|
|
343
|
+
| --------------------- | ---------------- | --------------------------------------------------- |
|
|
344
|
+
| `.toDuration()` | `DurationResult` | Objeto de duración completo con todos los métodos |
|
|
345
|
+
| `.inMonths()` | `number` | Rango en meses (decimal: 2.1355) |
|
|
346
|
+
| `.humanize(options?)` | `string` | Texto legible: "2 meses y 5 días" |
|
|
347
|
+
| `.in(unit)` | `number` | Rango en cualquier unidad (day, hour, minute, etc.) |
|
|
348
|
+
|
|
235
349
|
### Duración: Calcular tiempo entre fechas
|
|
236
350
|
|
|
237
351
|
```typescript
|
|
@@ -252,7 +366,185 @@ console.log(duration);
|
|
|
252
366
|
// }
|
|
253
367
|
```
|
|
254
368
|
|
|
255
|
-
###
|
|
369
|
+
### Humanize: Duración Legible para Usuarios 📝
|
|
370
|
+
|
|
371
|
+
Convierte duraciones a texto natural y legible con soporte multiidioma:
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
const start = TimeGuard.from("2024-01-15");
|
|
375
|
+
const end = TimeGuard.from("2024-03-20");
|
|
376
|
+
|
|
377
|
+
// Estilo simple (Intl.RelativeTimeFormat)
|
|
378
|
+
const duration = start.until(end);
|
|
379
|
+
console.log(duration.humanize());
|
|
380
|
+
// "2 months"
|
|
381
|
+
|
|
382
|
+
// Desglose completo con múltiples unidades
|
|
383
|
+
console.log(duration.humanize({ fullBreakdown: true }));
|
|
384
|
+
// "2 months and 5 days"
|
|
385
|
+
|
|
386
|
+
// Con locale específico
|
|
387
|
+
console.log(duration.humanize({ locale: "es" }));
|
|
388
|
+
// "2 meses"
|
|
389
|
+
|
|
390
|
+
console.log(duration.humanize({ locale: "es", fullBreakdown: true }));
|
|
391
|
+
// "2 meses y 5 días"
|
|
392
|
+
|
|
393
|
+
// Con locale francés
|
|
394
|
+
console.log(duration.humanize({ locale: "fr" }));
|
|
395
|
+
// "2 mois"
|
|
396
|
+
|
|
397
|
+
console.log(duration.humanize({ locale: "fr", fullBreakdown: true }));
|
|
398
|
+
// "2 mois et 5 jours"
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
#### Uso de Locales Heredadas
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
// TimeGuard hereda configuración de locale
|
|
405
|
+
const start = TimeGuard.from("2024-01-15", { locale: "es" });
|
|
406
|
+
const end = TimeGuard.from("2024-03-20");
|
|
407
|
+
|
|
408
|
+
const duration = start.until(end);
|
|
409
|
+
|
|
410
|
+
// Usa automáticamente el locale de la instancia
|
|
411
|
+
console.log(duration.humanize());
|
|
412
|
+
// "2 meses"
|
|
413
|
+
|
|
414
|
+
console.log(duration.humanize({ fullBreakdown: true }));
|
|
415
|
+
// "2 meses y 5 días"
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
#### Opciones de Humanize
|
|
419
|
+
|
|
420
|
+
| Opción | Tipo | Default | Descripción |
|
|
421
|
+
| --------------- | ------------------ | ------------- | ----------------------------------------------- |
|
|
422
|
+
| `locale` | string | del TimeGuard | Código de locale ('en', 'es', 'fr', etc.) |
|
|
423
|
+
| `fullBreakdown` | boolean | false | Mostrar desglose completo vs. unidad más grande |
|
|
424
|
+
| `numeric` | 'always' \| 'auto' | 'always' | Formato numérico para Intl API |
|
|
425
|
+
|
|
426
|
+
#### Locales Soportados
|
|
427
|
+
|
|
428
|
+
Humanize automáticamente soporta:
|
|
429
|
+
|
|
430
|
+
- 🇬🇧 **en** - English
|
|
431
|
+
- 🇪🇸 **es** - Español
|
|
432
|
+
- 🇫🇷 **fr** - Français (French)
|
|
433
|
+
- 🇩🇪 **de** - Deutsch (German)
|
|
434
|
+
- 🇮🇹 **it** - Italiano (Italian)
|
|
435
|
+
- 🇵🇹 **pt** - Português (Portuguese)
|
|
436
|
+
|
|
437
|
+
Y muchos más a través de `Intl.RelativeTimeFormat`.
|
|
438
|
+
|
|
439
|
+
### 💥 Explain Mode: Debugging Brutal y Educación
|
|
440
|
+
|
|
441
|
+
**Feature killer para debugging y enseñanza** - Obtén una explicación detallada de cómo se calculó cada duración.
|
|
442
|
+
|
|
443
|
+
Perfecto para:
|
|
444
|
+
|
|
445
|
+
- 🐛 **Debugging** - Entender exactamente cómo se calculó la duración
|
|
446
|
+
- 📚 **Educación** - Enseñar matemáticas de fechas
|
|
447
|
+
- 📋 **Auditoría** - Verificar lógica de negocio basada en fechas
|
|
448
|
+
- ✅ **Validación** - Confirmar que los cálculos son correctos
|
|
449
|
+
|
|
450
|
+
```typescript
|
|
451
|
+
const start = TimeGuard.from("2024-01-15");
|
|
452
|
+
const end = TimeGuard.from("2024-03-20");
|
|
453
|
+
const duration = start.until(end);
|
|
454
|
+
|
|
455
|
+
// Explicación detallada del cálculo
|
|
456
|
+
const explanation = duration.explain();
|
|
457
|
+
|
|
458
|
+
console.log(explanation);
|
|
459
|
+
// {
|
|
460
|
+
// input: [
|
|
461
|
+
// '2024-01-15T00:00:00',
|
|
462
|
+
// '2024-03-20T00:00:00'
|
|
463
|
+
// ],
|
|
464
|
+
// steps: [
|
|
465
|
+
// 'Parsed dates: 2024-01-15 (day 15 of 365) to 2024-03-20 (day 80 of 365)',
|
|
466
|
+
// '2024 is a leap year (February has 29 days)',
|
|
467
|
+
// 'Years: 0',
|
|
468
|
+
// 'Months: 2',
|
|
469
|
+
// 'Days: 5',
|
|
470
|
+
// 'Total: 2m 5d'
|
|
471
|
+
// ],
|
|
472
|
+
// breakdown: {
|
|
473
|
+
// years: 0,
|
|
474
|
+
// months: 2,
|
|
475
|
+
// weeks: 0,
|
|
476
|
+
// days: 5,
|
|
477
|
+
// hours: 0,
|
|
478
|
+
// minutes: 0,
|
|
479
|
+
// seconds: 0,
|
|
480
|
+
// milliseconds: 0
|
|
481
|
+
// },
|
|
482
|
+
// mode: 'exact',
|
|
483
|
+
// explanation: 'Calculated 2024-01-15 to 2024-03-20. 2024 is a leap year. Breakdown: 0 year(s), 2 month(s), 5 day(s). Mode: exact calculation',
|
|
484
|
+
// locale: 'en',
|
|
485
|
+
// leapYearFlags: [
|
|
486
|
+
// { year: 2024, isLeap: true, daysInFebruary: 29 }
|
|
487
|
+
// ],
|
|
488
|
+
// metadata: {
|
|
489
|
+
// calculationTimeMs: 0.5,
|
|
490
|
+
// precision: 'day'
|
|
491
|
+
// }
|
|
492
|
+
// }
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
#### Casos de Uso
|
|
496
|
+
|
|
497
|
+
Debugging de lógica de fechas:
|
|
498
|
+
|
|
499
|
+
```typescript
|
|
500
|
+
// ¿Por qué el cálculo de mora es diferente?
|
|
501
|
+
const invoiceDate = TimeGuard.from("2024-01-05");
|
|
502
|
+
const paymentDate = TimeGuard.from("2024-02-15");
|
|
503
|
+
const lateFee = invoiceDate.until(paymentDate);
|
|
504
|
+
|
|
505
|
+
// Obtén la explicación completa
|
|
506
|
+
const debug = lateFee.explain();
|
|
507
|
+
|
|
508
|
+
console.log("Pasos del cálculo:", debug.steps);
|
|
509
|
+
console.log("Febrero es bisiesto:", debug.leapYearFlags);
|
|
510
|
+
console.log("Desglose:", debug.breakdown);
|
|
511
|
+
// Ahora sabes exactamente qué sucedió!
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
Educación - Enseñar cálculos de fechas:
|
|
515
|
+
|
|
516
|
+
```typescript
|
|
517
|
+
// Mostrar a estudiantes cómo funciona
|
|
518
|
+
const start = TimeGuard.from("2024-02-15"); // Enero
|
|
519
|
+
const end = TimeGuard.from("2024-04-15"); // Abril
|
|
520
|
+
const duration = start.until(end);
|
|
521
|
+
|
|
522
|
+
const explanation = duration.explain();
|
|
523
|
+
|
|
524
|
+
// Mostrar todos los pasos
|
|
525
|
+
explanation.steps.forEach((step, i) => {
|
|
526
|
+
console.log(`${i + 1}. ${step}`);
|
|
527
|
+
});
|
|
528
|
+
// 1. Parsed dates: ...
|
|
529
|
+
// 2. 2024 is a leap year...
|
|
530
|
+
// 3. Years: 0
|
|
531
|
+
// 4. Months: 2
|
|
532
|
+
// 5. Days: 0
|
|
533
|
+
// 6. Total: 2m
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
#### Propiedades de Explanation
|
|
537
|
+
|
|
538
|
+
| Propiedad | Tipo | Descripción |
|
|
539
|
+
| ---------------- | ------------------------ | ----------------------------- |
|
|
540
|
+
| `input` | `string[]` | Fechas de entrada parseadas |
|
|
541
|
+
| `steps` | `string[]` | Pasos del cálculo legibles |
|
|
542
|
+
| `breakdown` | `DurationParts` | Desglose por componentes |
|
|
543
|
+
| `mode` | `'exact' \| 'estimated'` | Tipo de cálculo realizado |
|
|
544
|
+
| `explanation` | `string` | Resumen en texto natural |
|
|
545
|
+
| `locale` | `string` | Idioma de la explicación |
|
|
546
|
+
| `leapYearFlags?` | `Array` | Información de años bisiestos |
|
|
547
|
+
| `metadata?` | `Object` | Rendimiento y precisión |
|
|
256
548
|
|
|
257
549
|
```typescript
|
|
258
550
|
const date = TimeGuard.from("2024-03-13 14:35:47.654");
|
|
@@ -1042,10 +1334,30 @@ date1.isBetween(date1, date2, undefined, "[]"); // inclusive both ends
|
|
|
1042
1334
|
date1.isBetween(date1, date2, undefined, "()"); // exclusive both ends
|
|
1043
1335
|
date1.isBetween(date1, date2, "month", "[]"); // granular range
|
|
1044
1336
|
|
|
1045
|
-
// Calculate difference
|
|
1337
|
+
// Calculate difference - Traditional API (backward compatible)
|
|
1046
1338
|
date1.diff(date2, "days"); // -7
|
|
1047
1339
|
date1.diff(date2, "millisecond"); // difference in ms
|
|
1048
1340
|
date1.diff(date2, "months"); // -0
|
|
1341
|
+
|
|
1342
|
+
// Calculate difference - Modern Calendar-Aware API
|
|
1343
|
+
const start = TimeGuard.from("2024-01-15");
|
|
1344
|
+
const end = TimeGuard.from("2024-03-20");
|
|
1345
|
+
|
|
1346
|
+
// Exact mode (default) - precise time difference
|
|
1347
|
+
const exactDiff = start.diff(end, { mode: "exact" });
|
|
1348
|
+
console.log(exactDiff.as("day")); // 65 days
|
|
1349
|
+
|
|
1350
|
+
// Calendar mode - human-readable breakdown
|
|
1351
|
+
const calendarDiff = start.diff(end, { mode: "calendar" });
|
|
1352
|
+
console.log(calendarDiff.format("en")); // "2 months and 5 days"
|
|
1353
|
+
console.log(calendarDiff.format("es")); // "2 meses y 5 días"
|
|
1354
|
+
console.log(calendarDiff.breakdown()); // { years: 0, months: 2, weeks: 0, days: 5, ... }
|
|
1355
|
+
|
|
1356
|
+
// Fluent API for unit conversion
|
|
1357
|
+
const diff = start.diff(end);
|
|
1358
|
+
console.log(diff.as("day")); // 65
|
|
1359
|
+
console.log(diff.as("hour")); // 1560
|
|
1360
|
+
console.log(diff.valueOf()); // milliseconds
|
|
1049
1361
|
```
|
|
1050
1362
|
|
|
1051
1363
|
### 📊 Advanced Calculations
|
|
@@ -1187,6 +1499,107 @@ date.format('DD/MM/YYYY "at" HH:mm'); // 13/03/2024 at 14:30
|
|
|
1187
1499
|
|
|
1188
1500
|
**📖 Complete Format Guide:** See [EXAMPLES.md](EXAMPLES.md) for more patterns and use cases.
|
|
1189
1501
|
|
|
1502
|
+
### ⏱️ Calendar-Aware Difference Calculations
|
|
1503
|
+
|
|
1504
|
+
One of TimeGuard's most powerful features is its **calendar-aware diff mode**, which solves a fundamental problem with date libraries: months and years have variable lengths.
|
|
1505
|
+
|
|
1506
|
+
#### Understanding Two Approaches
|
|
1507
|
+
|
|
1508
|
+
```typescript
|
|
1509
|
+
// Problem: How much time between Jan 15 and Mar 20?
|
|
1510
|
+
const start = TimeGuard.from("2024-01-15");
|
|
1511
|
+
const end = TimeGuard.from("2024-03-20");
|
|
1512
|
+
|
|
1513
|
+
// ❌ Naive approach: Just count days
|
|
1514
|
+
// Result: "65 days" (technically correct but not user-friendly)
|
|
1515
|
+
|
|
1516
|
+
// ✅ Calendar-aware approach: Break into meaningful units
|
|
1517
|
+
// Result: "2 months and 5 days" (how humans think about time)
|
|
1518
|
+
```
|
|
1519
|
+
|
|
1520
|
+
#### API Modes
|
|
1521
|
+
|
|
1522
|
+
```typescript
|
|
1523
|
+
const start = TimeGuard.from("2024-01-15");
|
|
1524
|
+
const end = TimeGuard.from("2024-03-20");
|
|
1525
|
+
|
|
1526
|
+
// ==== EXACT MODE (default) ====
|
|
1527
|
+
// Precise time difference in specified unit
|
|
1528
|
+
const exactDiff = start.diff(end, { mode: "exact" });
|
|
1529
|
+
|
|
1530
|
+
// Returns normalized difference
|
|
1531
|
+
exactDiff.as("day"); // 65 days
|
|
1532
|
+
exactDiff.as("hour"); // 1560 hours
|
|
1533
|
+
exactDiff.as("week"); // 9 weeks
|
|
1534
|
+
exactDiff.valueOf(); // milliseconds
|
|
1535
|
+
|
|
1536
|
+
// ==== CALENDAR MODE ====
|
|
1537
|
+
// Human-readable breakdown with automatic localization
|
|
1538
|
+
const calendarDiff = start.diff(end, { mode: "calendar" });
|
|
1539
|
+
|
|
1540
|
+
// Get structured breakdown
|
|
1541
|
+
calendarDiff.breakdown();
|
|
1542
|
+
// {
|
|
1543
|
+
// years: 0,
|
|
1544
|
+
// months: 2,
|
|
1545
|
+
// weeks: 0,
|
|
1546
|
+
// days: 5,
|
|
1547
|
+
// hours: 0,
|
|
1548
|
+
// minutes: 0,
|
|
1549
|
+
// seconds: 0,
|
|
1550
|
+
// milliseconds: 0
|
|
1551
|
+
// }
|
|
1552
|
+
|
|
1553
|
+
// Format in any locale
|
|
1554
|
+
calendarDiff.format("en"); // "2 months and 5 days"
|
|
1555
|
+
calendarDiff.format("es"); // "2 meses y 5 días"
|
|
1556
|
+
calendarDiff.format("fr"); // "2 mois et 5 jours"
|
|
1557
|
+
calendarDiff.format("de"); // "2 Monate und 5 Tage"
|
|
1558
|
+
```
|
|
1559
|
+
|
|
1560
|
+
#### Backward Compatibility
|
|
1561
|
+
|
|
1562
|
+
```typescript
|
|
1563
|
+
// Traditional API still works perfectly
|
|
1564
|
+
const tg1 = TimeGuard.from("2024-01-15");
|
|
1565
|
+
const tg2 = TimeGuard.from("2024-03-20");
|
|
1566
|
+
|
|
1567
|
+
tg1.diff(tg2, "day"); // 65 (returns number)
|
|
1568
|
+
tg1.diff(tg2, "month"); // 2
|
|
1569
|
+
tg1.diff(tg2, "millisecond"); // raw milliseconds
|
|
1570
|
+
```
|
|
1571
|
+
|
|
1572
|
+
#### Advanced Usage
|
|
1573
|
+
|
|
1574
|
+
```typescript
|
|
1575
|
+
const start = TimeGuard.from("2024-01-15 10:30:00");
|
|
1576
|
+
const end = TimeGuard.from("2024-03-20 15:45:00");
|
|
1577
|
+
|
|
1578
|
+
// Fluent API for unit conversion
|
|
1579
|
+
const diff = start.diff(end);
|
|
1580
|
+
diff.as("day"); // Get as days
|
|
1581
|
+
diff.as("hour"); // Get as hours
|
|
1582
|
+
diff.as("minute"); // Get as minutes
|
|
1583
|
+
diff.valueOf(); // Implicit number conversion (milliseconds)
|
|
1584
|
+
|
|
1585
|
+
// Locale-specific formatting
|
|
1586
|
+
const spanishDiff = start.diff(end, {
|
|
1587
|
+
mode: "calendar",
|
|
1588
|
+
locale: "es",
|
|
1589
|
+
});
|
|
1590
|
+
console.log(spanishDiff.format()); // Uses Spanish locale
|
|
1591
|
+
|
|
1592
|
+
// Query the mode used
|
|
1593
|
+
diff.getMode(); // "exact"
|
|
1594
|
+
calendarDiff.getMode(); // "calendar"
|
|
1595
|
+
|
|
1596
|
+
// String representation
|
|
1597
|
+
spanishDiff.toString(); // "2 meses y 5 días" (nice for display)
|
|
1598
|
+
exactDiff.toString(); // "432000000" (milliseconds)
|
|
1599
|
+
```
|
|
1600
|
+
|
|
1601
|
+
**💡 Key Insight:** Calendar mode handles month/year variations automatically using Temporal API's built-in month normalization, ensuring accurate results across different month lengths and leap years.
|
|
1602
|
+
|
|
1190
1603
|
---
|
|
1191
1604
|
|
|
1192
1605
|
## 🧪 Testing
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! time-guard v2.
|
|
1
|
+
/*! time-guard v2.2.0 | (c) 2026 Berea-Soft | MIT License | https://github.com/Berea-Soft/time-guard */
|
|
2
2
|
//#region src/calendars/index.ts
|
|
3
3
|
var e = class {
|
|
4
4
|
id = "islamic";
|
package/dist/locales/index.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! time-guard v2.
|
|
1
|
+
/*! time-guard v2.2.0 | (c) 2026 Berea-Soft | MIT License | https://github.com/Berea-Soft/time-guard */
|
|
2
2
|
//#region src/locales/english.locale.ts
|
|
3
3
|
var e = {
|
|
4
4
|
name: "en",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! time-guard v2.
|
|
1
|
+
/*! time-guard v2.2.0 | (c) 2026 Berea-Soft | MIT License | https://github.com/Berea-Soft/time-guard */
|
|
2
2
|
//#region src/plugins/advanced-format/index.ts
|
|
3
3
|
var e = class {
|
|
4
4
|
name = "advanced-format";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! time-guard v2.
|
|
1
|
+
/*! time-guard v2.2.0 | (c) 2026 Berea-Soft | MIT License | https://github.com/Berea-Soft/time-guard */
|
|
2
2
|
//#region src/plugins/duration/index.ts
|
|
3
3
|
var e = class e {
|
|
4
4
|
years = 0;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! time-guard v2.
|
|
1
|
+
/*! time-guard v2.2.0 | (c) 2026 Berea-Soft | MIT License | https://github.com/Berea-Soft/time-guard */
|
|
2
2
|
//#region src/plugins/relative-time/index.ts
|
|
3
3
|
var e = [
|
|
4
4
|
{
|