@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.
@@ -1,16 +1,225 @@
1
- import { ITimeGuard, ITimeGuardConfig, Unit, FormatPreset, IRoundOptions } from './types';
2
- type DurationParts = {
1
+ import { ITimeGuard, ITimeGuardConfig, Unit, FormatPreset, IRoundOptions, IDurationOptions, IDiffResult, IDiffOptions, DurationParts, IDurationExplanation } from './types';
2
+ /**
3
+ * Diff result object that allows chaining with .as()
4
+ * Example: tg1.diff(tg2).as('month')
5
+ * Also acts as a number value for backward compatibility
6
+ *
7
+ * Supports two modes:
8
+ * - 'exact': Returns precise time differences (e.g., 65 days)
9
+ * - 'calendar': Returns calendar-aware breakdown (e.g., 2 months 5 days)
10
+ */
11
+ declare class DiffResult implements IDiffResult {
12
+ private _value;
13
+ private _tg1;
14
+ private _tg2;
15
+ private _mode;
16
+ private _breakdownData;
17
+ private _locale;
18
+ constructor(value: number, tg1: TimeGuard, tg2: TimeGuard, mode?: 'calendar' | 'exact', breakdownData?: DurationParts, locale?: string);
19
+ /**
20
+ * Convert the diff to a different unit
21
+ * Example: diff.as('month') returns the difference in months
22
+ */
23
+ as(unit: Unit): number;
24
+ /**
25
+ * Get breakdown in calendar mode (months, days, etc.)
26
+ * Returns null for 'exact' mode
27
+ */
28
+ breakdown(): DurationParts | null;
29
+ /**
30
+ * Format as human-readable string
31
+ * Example: "2 months and 5 days"
32
+ */
33
+ format(locale?: string): string;
34
+ /**
35
+ * Get the calculation mode used for this diff
36
+ */
37
+ getMode(): 'calendar' | 'exact';
38
+ /**
39
+ * Allow implicit numeric conversion for backward compatibility
40
+ */
41
+ valueOf(): number;
42
+ /**
43
+ * String representation
44
+ */
45
+ toString(): string;
46
+ /**
47
+ * JSON representation
48
+ */
49
+ toJSON(): number;
50
+ }
51
+ /**
52
+ * DurationResult class - Represents a duration breakdown with humanize support
53
+ * Example: start.until(end).humanize() → "2 months and 5 days"
54
+ *
55
+ * Public class available for type checking and extending
56
+ * Returned by until(), since(), and between() methods
57
+ */
58
+ export declare class DurationResult implements DurationParts {
3
59
  years: number;
4
60
  months: number;
61
+ weeks: number;
5
62
  days: number;
6
63
  hours: number;
7
64
  minutes: number;
8
65
  seconds: number;
9
66
  milliseconds: number;
10
- };
67
+ private _locale;
68
+ private _startDate?;
69
+ private _endDate?;
70
+ private _steps;
71
+ private _mode;
72
+ private _leapYearFlags;
73
+ private _calculationTimeMs;
74
+ constructor(parts: DurationParts, locale?: string, metadata?: {
75
+ startDate?: string;
76
+ endDate?: string;
77
+ steps?: string[];
78
+ mode?: 'exact' | 'estimated';
79
+ leapYearFlags?: Array<{
80
+ year: number;
81
+ isLeap: boolean;
82
+ daysInFebruary: number;
83
+ }>;
84
+ calculationTimeMs?: number;
85
+ });
86
+ /**
87
+ * Convert duration to human-readable string
88
+ * Supports multiple humanization styles using Intl API
89
+ * @example
90
+ * duration.humanize() // "2 months" (Intl.RelativeTimeFormat style)
91
+ * duration.humanize({ fullBreakdown: true, locale: 'es' }) // "2 meses y 5 días"
92
+ */
93
+ humanize(options?: {
94
+ locale?: string;
95
+ fullBreakdown?: boolean;
96
+ numeric?: 'always' | 'auto';
97
+ }): string;
98
+ /**
99
+ * Get total duration in specified unit (date-fns style)
100
+ * Useful for business logic: payments, metrics, analytics
101
+ *
102
+ * Conversion factors:
103
+ * - 1 year = 365.25 days (accounting for leap years)
104
+ * - 1 month = 365.25/12 days = 30.4375 days
105
+ * - 1 week = 7 days
106
+ *
107
+ * @example
108
+ * duration.total('days') // 65
109
+ * duration.total('months') // 2.166... (65 / 30.4375)
110
+ * duration.total('hours') // 1560 (65 * 24)
111
+ * duration.total('seconds') // 5616000 (65 * 24 * 60 * 60)
112
+ */
113
+ total(unit: Unit): number;
114
+ /**
115
+ * String representation
116
+ * Returns humanized format by default, or numeric if in exact mode
117
+ */
118
+ toString(): string;
119
+ /**
120
+ * JSON representation
121
+ * Returns the breakdown as object for serialization
122
+ */
123
+ toJSON(): Record<string, number>;
124
+ /**
125
+ * Explain the calculation - killer feature for debugging and education
126
+ * Returns detailed breakdown of how the duration was calculated
127
+ *
128
+ * Perfect for:
129
+ * - Debugging complex date calculations
130
+ * - Educational purposes (showing date math)
131
+ * - Auditing time-based business logic
132
+ * - Verification of calculation methodology
133
+ *
134
+ * @example
135
+ * start.until(end).explain()
136
+ * // {
137
+ * // input: ['2024-01-15', '2024-03-20'],
138
+ * // steps: [
139
+ * // 'Parsed dates: 2024-01-15 to 2024-03-20',
140
+ * // '2024 is a leap year (366 days)',
141
+ * // 'February 2024 has 29 days',
142
+ * // 'Total calculated: 65 days'
143
+ * // ],
144
+ * // breakdown: { years: 0, months: 2, weeks: 0, days: 5, ... },
145
+ * // mode: 'exact',
146
+ * // explanation: 'Calculated 2024-01-15 to 2024-03-20...'
147
+ * // }
148
+ */
149
+ explain(): IDurationExplanation;
150
+ /**
151
+ * Generate explanation steps for the calculation
152
+ * Used when steps weren't provided during construction
153
+ */
154
+ private generateExplanationSteps;
155
+ /**
156
+ * Get the conjunction for a locale
157
+ */
158
+ private getConjunction;
159
+ /**
160
+ * Pluralize a unit name
161
+ */
162
+ private pluralizeUnit;
163
+ }
11
164
  /**
12
165
  * TimeGuard implementation - Main facade class
13
166
  */
167
+ /**
168
+ * TimeRange - Fluent API for date range operations
169
+ * Semantic naming that eliminates confusion about date order
170
+ *
171
+ * @example
172
+ * TimeGuard.range('2024-01-15', '2024-03-20')
173
+ * .toDuration() // Returns DurationResult
174
+ * .humanize() // "2 months and 5 days"
175
+ *
176
+ * TimeGuard.range('2024-01-15', '2024-03-20')
177
+ * .inMonths() // 2.1355 (precise decimal)
178
+ *
179
+ * These methods work regardless of date order
180
+ */
181
+ export declare class TimeRange {
182
+ private _start;
183
+ private _end;
184
+ constructor(start: TimeGuard, end: TimeGuard);
185
+ /**
186
+ * Get the duration between the two dates
187
+ * @returns DurationResult with all duration properties and methods
188
+ * @example
189
+ * const duration = TimeGuard.range(start, end).toDuration();
190
+ * duration.humanize(); // "2 months and 5 days"
191
+ * duration.total('day'); // 65.875
192
+ */
193
+ toDuration(): DurationResult;
194
+ /**
195
+ * Get the range expressed in months (as decimal)
196
+ * Accounts for leap years and average month lengths
197
+ * @returns Number of months (can be decimal like 2.1355)
198
+ * @example
199
+ * TimeGuard.range('2024-01-15', '2024-03-20').inMonths(); // ~2.1355
200
+ */
201
+ inMonths(): number;
202
+ /**
203
+ * Get human-readable representation of the range
204
+ * Semantic naming that emphasizes what the range represents
205
+ * @returns String like "2 months and 5 days"
206
+ * @example
207
+ * TimeGuard.range(start, end).humanize(); // "2 months and 5 days"
208
+ * TimeGuard.range(start, end).humanize({ locale: 'es' }); // "2 meses y 5 días"
209
+ */
210
+ humanize(options?: {
211
+ locale?: string;
212
+ fullBreakdown?: boolean;
213
+ numeric?: 'always' | 'auto';
214
+ }): string;
215
+ /**
216
+ * Get duration in specific unit
217
+ * Chainable with other TimeRange methods
218
+ * @example
219
+ * TimeGuard.range(start, end).in('day'); // 65.875
220
+ */
221
+ in(unit: Unit): number;
222
+ }
14
223
  export declare class TimeGuard implements ITimeGuard {
15
224
  private temporal;
16
225
  private config;
@@ -26,6 +235,43 @@ export declare class TimeGuard implements ITimeGuard {
26
235
  static from(input: unknown, config?: ITimeGuardConfig): TimeGuard;
27
236
  static fromTemporal(temporal: any, // Temporal.PlainDateTime | Temporal.ZonedDateTime
28
237
  config?: ITimeGuardConfig): TimeGuard;
238
+ /**
239
+ * Calculate duration between two dates - semantic API eliminating until/since confusion
240
+ *
241
+ * Always returns positive duration regardless of date order.
242
+ * Use .humanize() for user-friendly output.
243
+ *
244
+ * @example
245
+ * const start = TimeGuard.from("2024-01-15");
246
+ * const end = TimeGuard.from("2024-03-20");
247
+ *
248
+ * TimeGuard.between(start, end).humanize();
249
+ * // "2 months and 5 days"
250
+ *
251
+ * // Order doesn't matter - semantic clarity!
252
+ * TimeGuard.between(end, start).humanize();
253
+ * // "2 months and 5 days" (still positive)
254
+ *
255
+ * // Has all DurationParts properties
256
+ * TimeGuard.between(start, end).months; // 2
257
+ * TimeGuard.between(start, end).days; // 5
258
+ */
259
+ static between(date1: TimeGuard, date2: TimeGuard): DurationResult;
260
+ /**
261
+ * Create a TimeRange for fluent duration calculations
262
+ * Marketing-friendly naming that emphasizes range semantics
263
+ *
264
+ * @example
265
+ * TimeGuard.range("2024-01-15", "2024-03-20")
266
+ * .humanize() // "2 months and 5 days"
267
+ *
268
+ * TimeGuard.range("2024-01-15", "2024-03-20")
269
+ * .inMonths() // 2.1355
270
+ *
271
+ * TimeGuard.range("2024-01-15", "2024-03-20")
272
+ * .toDuration() // DurationResult object
273
+ */
274
+ static range(start: unknown, end: unknown): TimeRange;
29
275
  toTemporal(): any;
30
276
  toDate(): Date;
31
277
  toISOString(): string;
@@ -41,7 +287,28 @@ export declare class TimeGuard implements ITimeGuard {
41
287
  get(component: Unit): number;
42
288
  add(units: Partial<Record<Unit, number>>): TimeGuard;
43
289
  subtract(units: Partial<Record<Unit, number>>): TimeGuard;
44
- diff(other: TimeGuard, unit?: Unit): number;
290
+ /**
291
+ * Calculate difference between two TimeGuard instances
292
+ *
293
+ * Supports multiple modes:
294
+ * 1. diff(other) - Returns DiffResult with fluent API (default: exact mode)
295
+ * 2. diff(other, unit) - Returns number (backward compatible)
296
+ * 3. diff(other, options) - Returns DiffResult with calendar or exact mode
297
+ *
298
+ * @example
299
+ * // Exact mode (default)
300
+ * tg1.diff(tg2).as('day') // Get as number: 65
301
+ *
302
+ * // Calendar mode - shows normalized breakdown
303
+ * tg1.diff(tg2, { mode: 'calendar' }).format('en')
304
+ * // Output: "2 months and 5 days"
305
+ *
306
+ * // With custom unit
307
+ * tg1.diff(tg2, { unit: 'hour' }).as('hour') // 1560
308
+ */
309
+ diff(other: TimeGuard): DiffResult;
310
+ diff(other: TimeGuard, unit: Unit): number;
311
+ diff(other: TimeGuard, options: IDiffOptions): DiffResult;
45
312
  isBefore(other: TimeGuard): boolean;
46
313
  isAfter(other: TimeGuard): boolean;
47
314
  isSame(other: TimeGuard, unit?: Unit): boolean;
@@ -65,8 +332,16 @@ export declare class TimeGuard implements ITimeGuard {
65
332
  inLeapYear(): boolean;
66
333
  /**
67
334
  * Calculate duration until another TimeGuard
335
+ * @returns Duration object with .humanize() and other methods
336
+ * @example
337
+ * start.until(end).humanize() // "2 months and 5 days"
338
+ * start.until(end).humanize({ fullBreakdown: true, locale: 'es' }) // "2 meses y 5 días"
339
+ */
340
+ until(other: TimeGuard, options?: IDurationOptions): DurationResult;
341
+ /**
342
+ * Generate explanation steps for until() calculation
68
343
  */
69
- until(other: TimeGuard): DurationParts;
344
+ private generateUntilSteps;
70
345
  /**
71
346
  * Round to a specific unit with optional rounding mode
72
347
  */
@@ -120,8 +395,12 @@ export declare class TimeGuard implements ITimeGuard {
120
395
  /**
121
396
  * Calculate duration from another TimeGuard (inverse of until)
122
397
  * Returns negative values if other is before this
398
+ * @returns Duration object with .humanize() and other methods
399
+ * @example
400
+ * end.since(start).humanize() // "2 months and 5 days"
401
+ * end.since(start).humanize({ locale: 'es' }) // "2 meses y 5 días"
123
402
  */
124
- since(other: TimeGuard): DurationParts;
403
+ since(other: TimeGuard, options?: IDurationOptions): DurationResult;
125
404
  /**
126
405
  * Get ISO 8601 duration string
127
406
  * Example: P1Y2M3DT4H5M6S
@@ -35,6 +35,230 @@ export interface IRoundOptions {
35
35
  roundingMode?: 'ceil' | 'floor' | 'expand' | 'trunc' | 'halfExpand' | 'halfFloor' | 'halfCeil' | 'halfTrunc';
36
36
  roundingIncrement?: number;
37
37
  }
38
+ /**
39
+ * Duration options for normalizing time differences
40
+ */
41
+ export interface IDurationOptions {
42
+ largestUnit?: 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond';
43
+ smallestUnit?: 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond';
44
+ }
45
+ /**
46
+ * Diff result object that allows chaining with .as()
47
+ * Example: tg1.diff(tg2).as('month')
48
+ */
49
+ export interface IDiffResult {
50
+ as(unit: Unit): number;
51
+ /**
52
+ * Get breakdown in calendar mode (e.g., "2 months 5 days")
53
+ * Only available when mode is 'calendar'
54
+ */
55
+ breakdown(): DurationParts | null;
56
+ /**
57
+ * Format the difference as a human-readable string
58
+ * @param locale Locale code (e.g., 'en', 'es', 'fr')
59
+ * @example
60
+ * diff.format('en') // "2 months and 5 days"
61
+ * diff.format('es') // "2 meses y 5 días"
62
+ */
63
+ format(locale?: string): string;
64
+ /**
65
+ * Get the mode used for this diff calculation
66
+ */
67
+ getMode(): 'calendar' | 'exact';
68
+ }
69
+ /**
70
+ * Options for diff() method
71
+ */
72
+ export interface IDiffOptions {
73
+ /**
74
+ * Calculation mode:
75
+ * - 'calendar': Returns months/days breakdown (e.g., 65 days → 2 months 5 days)
76
+ * - 'exact': Returns exact time units (e.g., 65 days)
77
+ * @default 'exact'
78
+ */
79
+ mode?: 'calendar' | 'exact';
80
+ /**
81
+ * Unit for diff when using 'exact' mode
82
+ * @default 'millisecond'
83
+ */
84
+ unit?: Unit;
85
+ /**
86
+ * Locale for formatting output text
87
+ * @default from TimeGuard instance config
88
+ */
89
+ locale?: string;
90
+ }
91
+ /**
92
+ * Duration parts breakdown
93
+ */
94
+ export interface DurationParts {
95
+ years: number;
96
+ months: number;
97
+ weeks: number;
98
+ days: number;
99
+ hours: number;
100
+ minutes: number;
101
+ seconds: number;
102
+ milliseconds: number;
103
+ }
104
+ /**
105
+ * Options for humanize() method
106
+ */
107
+ export interface IHumanizeOptions {
108
+ /**
109
+ * Locale code (e.g., 'en', 'es', 'fr')
110
+ * @default from TimeGuard instance config
111
+ */
112
+ locale?: string;
113
+ /**
114
+ * Show full breakdown (e.g., "2 months and 5 days")
115
+ * or just largest unit (e.g., "2 months")
116
+ * @default false (largest unit only with Intl.RelativeTimeFormat style)
117
+ */
118
+ fullBreakdown?: boolean;
119
+ /**
120
+ * Numeric format: 'always', 'auto'
121
+ * @default 'always'
122
+ */
123
+ numeric?: 'always' | 'auto';
124
+ }
125
+ /**
126
+ * Duration result with humanize and total methods
127
+ * Returned by until(), since(), and between()
128
+ * Rich object for business logic: payments, metrics, analytics
129
+ */
130
+ export interface IDurationResult extends DurationParts {
131
+ /**
132
+ * Convert duration to human-readable string
133
+ * @example
134
+ * duration.humanize() // "2 months"
135
+ * duration.humanize({ fullBreakdown: true, locale: 'es' }) // "2 meses y 5 días"
136
+ */
137
+ humanize(options?: IHumanizeOptions): string;
138
+ /**
139
+ * Get total duration in specified unit (date-fns style)
140
+ * Perfect for business metrics: payments, analytics, calculations
141
+ *
142
+ * Conversion factors account for:
143
+ * - Leap years (1 year = 365.25 days)
144
+ * - Average month length (1 month = 30.4375 days)
145
+ *
146
+ * @example
147
+ * duration.total('days') // 65
148
+ * duration.total('months') // 2.166... (65 / 30.4375)
149
+ * duration.total('hours') // 1560
150
+ * duration.total('seconds') // 5616000
151
+ *
152
+ * Use cases:
153
+ * - Billing calculations: `duration.total('days') * dailyRate`
154
+ * - Performance metrics: `duration.total('milliseconds')`
155
+ * - Report generation: `duration.total('months')`
156
+ */
157
+ total(unit: Unit): number;
158
+ /**
159
+ * String representation
160
+ * Returns humanized format for display
161
+ */
162
+ toString(): string;
163
+ /**
164
+ * JSON representation
165
+ * Returns breakdown as object for API responses
166
+ */
167
+ toJSON(): Record<string, number>;
168
+ /**
169
+ * Explain the calculation - killer feature for debugging and education
170
+ * Returns detailed breakdown of how the duration was calculated
171
+ *
172
+ * Perfect for:
173
+ * - Debugging complex date calculations
174
+ * - Educational purposes (showing date math)
175
+ * - Auditing time-based business logic
176
+ *
177
+ * @example
178
+ * duration.explain()
179
+ * // {
180
+ * // input: ['2024-01-15', '2024-03-20'],
181
+ * // steps: ['...step 1...', '...step 2...'],
182
+ * // breakdown: { years: 0, months: 2, days: 5, ... },
183
+ * // mode: 'exact',
184
+ * // explanation: '...'
185
+ * // }
186
+ */
187
+ explain(): IDurationExplanation;
188
+ }
189
+ /**
190
+ * Duration explanation object for debugging and education
191
+ * Provides transparent insight into calculation methodology
192
+ * Perfect for: debugging, auditing, educational purposes
193
+ *
194
+ * @example
195
+ * duration.explain()
196
+ * // {
197
+ * // input: ['2024-01-15', '2024-03-20'],
198
+ * // steps: [
199
+ * // 'Parsed dates: 2024-01-15 (day 15 of 365) to 2024-03-20 (day 80 of 365)',
200
+ * // '2024 is a leap year (366 days)',
201
+ * // 'February 2024 has 29 days',
202
+ * // 'Month 1: 31 - 15 = 16 days remaining',
203
+ * // 'Month 2: 29 days (full leap month)',
204
+ * // 'Month 3: 1 - 20 = 20 days',
205
+ * // 'Total: 16 + 29 + 20 = 65 days'
206
+ * // ],
207
+ * // breakdown: { years: 0, months: 2, weeks: 0, days: 5, ... },
208
+ * // mode: 'exact',
209
+ * // explanation: 'Calculated 2024-01-15 to 2024-03-20 including leap year adjustment'
210
+ * // }
211
+ */
212
+ export interface IDurationExplanation {
213
+ /**
214
+ * Input dates as array of strings or formatted representations
215
+ */
216
+ input: string[];
217
+ /**
218
+ * Step-by-step calculation explanation
219
+ * Each step is human-readable and educational
220
+ * Useful for debugging complex date calculations
221
+ */
222
+ steps: string[];
223
+ /**
224
+ * Duration breakdown by component
225
+ * Same as the DurationResult properties
226
+ */
227
+ breakdown: DurationParts;
228
+ /**
229
+ * Calculation mode
230
+ * - 'exact': Uses Temporal API precise calculations
231
+ * - 'estimated': Fallback for edge cases
232
+ */
233
+ mode: 'exact' | 'estimated';
234
+ /**
235
+ * Human-readable explanation of the entire calculation
236
+ * Summarizes the approach and any special handling
237
+ */
238
+ explanation: string;
239
+ /**
240
+ * Locale used for explanation text
241
+ * Supports internationalization of step descriptions
242
+ */
243
+ locale: string;
244
+ /**
245
+ * Leap year flags if applicable
246
+ * Documents which years were leap years in the calculation
247
+ */
248
+ leapYearFlags?: {
249
+ year: number;
250
+ isLeap: boolean;
251
+ daysInFebruary: number;
252
+ }[];
253
+ /**
254
+ * Performance metadata
255
+ * For monitoring calculation complexity
256
+ */
257
+ metadata?: {
258
+ calculationTimeMs: number;
259
+ precision: 'nanosecond' | 'microsecond' | 'millisecond' | 'second' | 'day';
260
+ };
261
+ }
38
262
  /**
39
263
  * Calendar system interface
40
264
  */
@@ -110,8 +334,10 @@ export interface ILocaleManager {
110
334
  export interface IDateArithmetic {
111
335
  add(units: Partial<Record<Unit, number>> | IDuration): TimeGuard;
112
336
  subtract(units: Partial<Record<Unit, number>> | IDuration): TimeGuard;
113
- diff(other: TimeGuard, unit?: Unit): number;
114
- until(other: TimeGuard, options?: IRoundOptions): IDuration;
337
+ diff(other: TimeGuard): IDiffResult;
338
+ diff(other: TimeGuard, unit: Unit): number;
339
+ until(other: TimeGuard, options?: IDurationOptions): IDurationResult;
340
+ since(other: TimeGuard, options?: IDurationOptions): IDurationResult;
115
341
  round(options: IRoundOptions): TimeGuard;
116
342
  }
117
343
  /**
@@ -250,7 +476,7 @@ export interface ITimeGuard extends IDateArithmetic, IDateQuery, IDateManipulati
250
476
  /**
251
477
  * Duration from another date (inverse of until)
252
478
  */
253
- since(other: TimeGuard): IDuration;
479
+ since(other: TimeGuard, options?: IDurationOptions): IDurationResult;
254
480
  /**
255
481
  * ISO 8601 duration string (P1Y2M3DT4H5M6S)
256
482
  */
@@ -299,3 +525,54 @@ export interface ITimeGuardFactory {
299
525
  export declare class TimeGuard {
300
526
  constructor(input?: unknown, config?: ITimeGuardConfig);
301
527
  }
528
+ /**
529
+ * Forward declaration for DurationResult class
530
+ * Implementation is in ./time-guard.ts, exported via ./index.ts
531
+ */
532
+ export declare class DurationResult implements IDurationResult {
533
+ constructor(parts: DurationParts, locale?: string, metadata?: {
534
+ startDate?: string;
535
+ endDate?: string;
536
+ steps?: string[];
537
+ mode?: 'exact' | 'estimated';
538
+ leapYearFlags?: Array<{
539
+ year: number;
540
+ isLeap: boolean;
541
+ daysInFebruary: number;
542
+ }>;
543
+ calculationTimeMs?: number;
544
+ });
545
+ years: number;
546
+ months: number;
547
+ weeks: number;
548
+ days: number;
549
+ hours: number;
550
+ minutes: number;
551
+ seconds: number;
552
+ milliseconds: number;
553
+ humanize(options?: {
554
+ locale?: string;
555
+ fullBreakdown?: boolean;
556
+ numeric?: 'always' | 'auto';
557
+ }): string;
558
+ total(unit: Unit): number;
559
+ toString(): string;
560
+ toJSON(): Record<string, number>;
561
+ explain(): IDurationExplanation;
562
+ }
563
+ /**
564
+ * Forward declaration for TimeRange class
565
+ * Fluent API for date range operations with semantic naming
566
+ * Implementation is in ./time-guard.ts, exported via ./index.ts
567
+ */
568
+ export declare class TimeRange {
569
+ constructor(start: TimeGuard, end: TimeGuard);
570
+ toDuration(): DurationResult;
571
+ inMonths(): number;
572
+ humanize(options?: {
573
+ locale?: string;
574
+ fullBreakdown?: boolean;
575
+ numeric?: 'always' | 'auto';
576
+ }): string;
577
+ in(unit: Unit): number;
578
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bereasoftware/time-guard",
3
3
  "private": false,
4
- "version": "2.1.0",
4
+ "version": "2.2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "main": "./dist/time-guard.cjs",