@f-o-t/datetime 0.1.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.md ADDED
@@ -0,0 +1,726 @@
1
+ # @f-o-t/datetime
2
+
3
+ Lightweight, Day.js-inspired datetime library with modern fluent API, Zod-first validation, and plugin architecture.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@f-o-t/datetime.svg)](https://www.npmjs.com/package/@f-o-t/datetime)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Features
9
+
10
+ - **Immutable**: All operations return new instances, preventing accidental mutations
11
+ - **Type Safety**: Full TypeScript support with Zod schema validation
12
+ - **Plugin Architecture**: Extend functionality with timezone, formatting, business days, and relative time plugins
13
+ - **Lightweight**: Minimal dependencies, built on native JavaScript Date
14
+ - **Fluent API**: Chainable methods for elegant datetime operations
15
+ - **Framework Agnostic**: Works with any JavaScript/TypeScript project
16
+ - **UTC-First**: All core operations use UTC to avoid timezone confusion
17
+ - **Rich API**: Comprehensive operations for creation, arithmetic, comparison, and manipulation
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ # bun
23
+ bun add @f-o-t/datetime
24
+
25
+ # npm
26
+ npm install @f-o-t/datetime
27
+
28
+ # yarn
29
+ yarn add @f-o-t/datetime
30
+
31
+ # pnpm
32
+ pnpm add @f-o-t/datetime
33
+ ```
34
+
35
+ ## Quick Start
36
+
37
+ ```typescript
38
+ import { datetime } from "@f-o-t/datetime";
39
+
40
+ // Create datetime instances
41
+ const now = datetime();
42
+ const birthday = datetime("2024-01-15T10:30:00Z");
43
+
44
+ // Perform arithmetic
45
+ const nextWeek = now.addWeeks(1);
46
+ const yesterday = now.subtractDays(1);
47
+
48
+ // Compare dates
49
+ if (birthday.isBefore(now)) {
50
+ console.log("Birthday has passed");
51
+ }
52
+
53
+ // Calculate differences
54
+ const daysUntil = birthday.diff(now, "day");
55
+ console.log(`Days until birthday: ${daysUntil}`);
56
+
57
+ // Format output
58
+ console.log(now.toISO()); // "2024-01-15T10:30:00.000Z"
59
+ ```
60
+
61
+ ## Core Concepts
62
+
63
+ ### DateTime Object
64
+
65
+ The `DateTime` class is the core type representing a moment in time:
66
+
67
+ ```typescript
68
+ import { datetime } from "@f-o-t/datetime";
69
+
70
+ const dt = datetime("2024-01-15T10:30:00Z");
71
+ ```
72
+
73
+ **Important**: DateTime objects are immutable. All operations return new instances.
74
+
75
+ ### UTC-First Design
76
+
77
+ All core DateTime methods operate in UTC to avoid timezone-related bugs:
78
+
79
+ ```typescript
80
+ const dt = datetime("2024-01-15T10:30:00Z");
81
+ dt.year(); // Returns UTC year
82
+ dt.hour(); // Returns UTC hour
83
+ dt.addDays(1); // Adds days in UTC
84
+ ```
85
+
86
+ Use the timezone plugin for timezone-aware operations.
87
+
88
+ ### Validation
89
+
90
+ All inputs are validated using Zod schemas:
91
+
92
+ ```typescript
93
+ import { datetime } from "@f-o-t/datetime";
94
+
95
+ // Valid inputs
96
+ datetime(); // Current time
97
+ datetime(new Date()); // Date object
98
+ datetime("2024-01-15T10:30:00Z"); // ISO string
99
+ datetime(1705315800000); // Unix timestamp
100
+ datetime(dt); // Another DateTime
101
+
102
+ // Invalid inputs throw InvalidDateError
103
+ datetime("invalid"); // Throws
104
+ datetime({}); // Throws
105
+ ```
106
+
107
+ ## API Reference
108
+
109
+ ### Factory Functions
110
+
111
+ Create DateTime instances:
112
+
113
+ ```typescript
114
+ import { datetime, DateTime } from "@f-o-t/datetime";
115
+
116
+ // Factory function (recommended)
117
+ const dt1 = datetime(); // Current time
118
+ const dt2 = datetime("2024-01-15"); // ISO string
119
+ const dt3 = datetime(new Date()); // Date object
120
+ const dt4 = datetime(1705315800000); // Timestamp
121
+ const dt5 = datetime(dt1); // Clone
122
+
123
+ // Constructor (alternative)
124
+ const dt6 = new DateTime("2024-01-15");
125
+ ```
126
+
127
+ ### Validation and Conversion
128
+
129
+ ```typescript
130
+ const dt = datetime("2024-01-15T10:30:00Z");
131
+
132
+ // Check validity
133
+ dt.isValid(); // true
134
+
135
+ // Convert to native types
136
+ dt.toDate(); // Returns native Date object
137
+ dt.toISO(); // "2024-01-15T10:30:00.000Z"
138
+ dt.valueOf(); // 1705315800000 (Unix timestamp)
139
+ ```
140
+
141
+ ### Arithmetic Operations
142
+
143
+ All arithmetic methods return new DateTime instances:
144
+
145
+ ```typescript
146
+ const dt = datetime("2024-01-15T10:30:00Z");
147
+
148
+ // Add time
149
+ dt.addMilliseconds(500); // Add 500ms
150
+ dt.addSeconds(30); // Add 30 seconds
151
+ dt.addMinutes(15); // Add 15 minutes
152
+ dt.addHours(2); // Add 2 hours
153
+ dt.addDays(7); // Add 7 days
154
+ dt.addWeeks(2); // Add 2 weeks
155
+ dt.addMonths(3); // Add 3 months
156
+ dt.addYears(1); // Add 1 year
157
+
158
+ // Subtract time
159
+ dt.subtractMilliseconds(500);
160
+ dt.subtractSeconds(30);
161
+ dt.subtractMinutes(15);
162
+ dt.subtractHours(2);
163
+ dt.subtractDays(7);
164
+ dt.subtractWeeks(2);
165
+ dt.subtractMonths(3);
166
+ dt.subtractYears(1);
167
+
168
+ // Negative amounts work in reverse
169
+ dt.addDays(-7); // Same as subtractDays(7)
170
+ dt.subtractDays(-7); // Same as addDays(7)
171
+ ```
172
+
173
+ ### Comparison Operations
174
+
175
+ ```typescript
176
+ const dt1 = datetime("2024-01-15T10:00:00Z");
177
+ const dt2 = datetime("2024-01-20T10:00:00Z");
178
+
179
+ // Basic comparisons
180
+ dt1.isBefore(dt2); // true
181
+ dt1.isAfter(dt2); // false
182
+ dt1.isSame(dt2); // false
183
+ dt1.isSameOrBefore(dt2); // true
184
+ dt1.isSameOrAfter(dt2); // false
185
+
186
+ // Range checking
187
+ const mid = datetime("2024-01-17T10:00:00Z");
188
+ mid.isBetween(dt1, dt2); // false (exclusive)
189
+ mid.isBetween(dt1, dt2, true); // true (inclusive)
190
+ ```
191
+
192
+ ### Getter Methods
193
+
194
+ All getters return UTC values:
195
+
196
+ ```typescript
197
+ const dt = datetime("2024-01-15T10:30:45.123Z");
198
+
199
+ dt.year(); // 2024
200
+ dt.month(); // 0 (0-indexed, 0=January)
201
+ dt.date(); // 15 (day of month)
202
+ dt.day(); // 1 (day of week, 0=Sunday)
203
+ dt.hour(); // 10
204
+ dt.minute(); // 30
205
+ dt.second(); // 45
206
+ dt.millisecond(); // 123
207
+ ```
208
+
209
+ ### Setter Methods
210
+
211
+ All setters return new DateTime instances:
212
+
213
+ ```typescript
214
+ const dt = datetime("2024-01-15T10:30:00Z");
215
+
216
+ dt.setYear(2025); // Changes year to 2025
217
+ dt.setMonth(5); // Changes month to June (0-indexed)
218
+ dt.setDate(20); // Changes day to 20th
219
+ dt.setHour(14); // Changes hour to 14:00
220
+ dt.setMinute(45); // Changes minute to XX:45
221
+ dt.setSecond(30); // Changes second to XX:XX:30
222
+ dt.setMillisecond(500); // Changes millisecond to XX:XX:XX.500
223
+ ```
224
+
225
+ ### Start/End of Unit
226
+
227
+ Get the start or end of a time unit:
228
+
229
+ ```typescript
230
+ const dt = datetime("2024-01-15T10:30:45.123Z");
231
+
232
+ // Start of unit (sets to 00:00:00.000)
233
+ dt.startOfDay(); // 2024-01-15T00:00:00.000Z
234
+ dt.startOfHour(); // 2024-01-15T10:00:00.000Z
235
+ dt.startOfWeek(); // 2024-01-14T00:00:00.000Z (Sunday)
236
+ dt.startOfMonth(); // 2024-01-01T00:00:00.000Z
237
+ dt.startOfYear(); // 2024-01-01T00:00:00.000Z
238
+
239
+ // End of unit (sets to 23:59:59.999 or max value)
240
+ dt.endOfDay(); // 2024-01-15T23:59:59.999Z
241
+ dt.endOfHour(); // 2024-01-15T10:59:59.999Z
242
+ dt.endOfWeek(); // 2024-01-20T23:59:59.999Z (Saturday)
243
+ dt.endOfMonth(); // 2024-01-31T23:59:59.999Z
244
+ dt.endOfYear(); // 2024-12-31T23:59:59.999Z
245
+ ```
246
+
247
+ ### Difference Calculation
248
+
249
+ Calculate the difference between two dates:
250
+
251
+ ```typescript
252
+ const dt1 = datetime("2024-01-15T10:00:00Z");
253
+ const dt2 = datetime("2024-01-20T14:30:00Z");
254
+
255
+ dt2.diff(dt1, "millisecond"); // 456600000
256
+ dt2.diff(dt1, "second"); // 456600
257
+ dt2.diff(dt1, "minute"); // 7610
258
+ dt2.diff(dt1, "hour"); // 126.83...
259
+ dt2.diff(dt1, "day"); // 5.19...
260
+ dt2.diff(dt1, "week"); // 0.74...
261
+ dt2.diff(dt1, "month"); // 0 (calendar months)
262
+ dt2.diff(dt1, "year"); // 0.01...
263
+
264
+ // Difference can be negative
265
+ dt1.diff(dt2, "day"); // -5.19...
266
+ ```
267
+
268
+ ## Plugins
269
+
270
+ Extend DateTime functionality with plugins. Each plugin adds new methods to DateTime instances.
271
+
272
+ ### Timezone Plugin
273
+
274
+ Handle timezone conversions and operations:
275
+
276
+ ```typescript
277
+ import { DateTime } from "@f-o-t/datetime";
278
+ import timezonePlugin from "@f-o-t/datetime/plugins/timezone";
279
+
280
+ // Install plugin
281
+ DateTime.extend(timezonePlugin);
282
+
283
+ const dt = datetime("2024-01-15T10:00:00Z");
284
+
285
+ // Convert to timezone
286
+ const nyTime = dt.tz("America/New_York");
287
+
288
+ // Get timezone offset
289
+ const offset = dt.utcOffset("America/New_York"); // -300 (minutes)
290
+
291
+ // Format in timezone
292
+ const formatted = dt.tzFormat("America/New_York", "YYYY-MM-DD HH:mm");
293
+
294
+ // Get local timezone
295
+ const localTz = DateTime.localTimezone(); // e.g., "America/Los_Angeles"
296
+
297
+ // Validate timezone
298
+ DateTime.isValidTimezone("America/New_York"); // true
299
+ DateTime.isValidTimezone("Invalid/Zone"); // false
300
+ ```
301
+
302
+ **Available Methods:**
303
+ - `tz(timezone)` - Convert to timezone
304
+ - `toTimezone(timezone)` - Alias for tz()
305
+ - `utcOffset(timezone)` - Get UTC offset in minutes
306
+ - `tzFormat(timezone, format)` - Format in timezone
307
+
308
+ **Static Methods:**
309
+ - `DateTime.localTimezone()` - Get system timezone
310
+ - `DateTime.isValidTimezone(tz)` - Validate timezone string
311
+
312
+ ### Business Days Plugin
313
+
314
+ Work with business days (Monday-Friday):
315
+
316
+ ```typescript
317
+ import { DateTime } from "@f-o-t/datetime";
318
+ import businessDaysPlugin from "@f-o-t/datetime/plugins/business-days";
319
+
320
+ DateTime.extend(businessDaysPlugin);
321
+
322
+ const dt = datetime("2024-01-15T10:00:00Z"); // Monday
323
+
324
+ // Check if weekday/weekend
325
+ dt.isWeekday(); // true
326
+ dt.isWeekend(); // false
327
+
328
+ // Add/subtract business days (skips weekends)
329
+ const nextBizDay = dt.addBusinessDays(1); // Tuesday
330
+ const prevBizDay = dt.subtractBusinessDays(1); // Friday (prev week)
331
+
332
+ // Calculate business days between dates
333
+ const start = datetime("2024-01-15"); // Monday
334
+ const end = datetime("2024-01-22"); // Next Monday
335
+ start.diffBusinessDays(end); // 5 business days
336
+ ```
337
+
338
+ **Note**: Business days plugin only considers weekends. It does not account for holidays.
339
+
340
+ ### Format Plugin
341
+
342
+ Format dates with customizable tokens:
343
+
344
+ ```typescript
345
+ import { DateTime } from "@f-o-t/datetime";
346
+ import formatPlugin from "@f-o-t/datetime/plugins/format";
347
+
348
+ DateTime.extend(formatPlugin);
349
+
350
+ const dt = datetime("2024-01-15T14:30:45.123Z");
351
+
352
+ // Common formats
353
+ dt.format("YYYY-MM-DD"); // "2024-01-15"
354
+ dt.format("MM/DD/YYYY"); // "01/15/2024"
355
+ dt.format("MMMM D, YYYY"); // "January 15, 2024"
356
+ dt.format("dddd, MMMM D, YYYY"); // "Monday, January 15, 2024"
357
+ dt.format("h:mm A"); // "2:30 PM"
358
+ dt.format("HH:mm:ss"); // "14:30:45"
359
+ dt.format("YYYY-MM-DDTHH:mm:ss.SSSZ"); // ISO format (default)
360
+
361
+ // Escape characters with brackets
362
+ dt.format("[Year:] YYYY"); // "Year: 2024"
363
+ dt.format("[Today is] dddd"); // "Today is Monday"
364
+ ```
365
+
366
+ **Available Tokens:**
367
+ - `YYYY` - 4-digit year (2024)
368
+ - `YY` - 2-digit year (24)
369
+ - `MMMM` - Full month name (January)
370
+ - `MMM` - Abbreviated month (Jan)
371
+ - `MM` - 2-digit month (01)
372
+ - `M` - Month number (1)
373
+ - `DD` - 2-digit day (15)
374
+ - `D` - Day of month (15)
375
+ - `dddd` - Full day name (Monday)
376
+ - `ddd` - Abbreviated day (Mon)
377
+ - `dd` - Min day name (Mo)
378
+ - `d` - Day of week (1)
379
+ - `HH` - 2-digit hour 24h (14)
380
+ - `H` - Hour 24h (14)
381
+ - `hh` - 2-digit hour 12h (02)
382
+ - `h` - Hour 12h (2)
383
+ - `mm` - 2-digit minute (30)
384
+ - `m` - Minute (30)
385
+ - `ss` - 2-digit second (45)
386
+ - `s` - Second (45)
387
+ - `SSS` - Milliseconds (123)
388
+ - `A` - AM/PM (PM)
389
+ - `a` - am/pm (pm)
390
+ - `Z` - Timezone offset (+00:00)
391
+ - `ZZ` - Compact offset (+0000)
392
+
393
+ ### Relative Time Plugin
394
+
395
+ Display human-readable relative time:
396
+
397
+ ```typescript
398
+ import { DateTime } from "@f-o-t/datetime";
399
+ import relativeTimePlugin from "@f-o-t/datetime/plugins/relative-time";
400
+
401
+ DateTime.extend(relativeTimePlugin);
402
+
403
+ const now = datetime();
404
+
405
+ // Get relative time from now
406
+ datetime(now.valueOf() - 30000).fromNow(); // "a few seconds ago"
407
+ datetime(now.valueOf() - 120000).fromNow(); // "2 minutes ago"
408
+ datetime(now.valueOf() - 7200000).fromNow(); // "2 hours ago"
409
+ datetime(now.valueOf() + 86400000).fromNow(); // "in a day"
410
+
411
+ // Get relative time to now
412
+ datetime(now.valueOf() - 30000).toNow(); // "in a few seconds"
413
+ datetime(now.valueOf() + 120000).toNow(); // "in 2 minutes"
414
+
415
+ // Relative time between two dates
416
+ const dt1 = datetime("2024-01-15");
417
+ const dt2 = datetime("2024-01-20");
418
+ dt1.from(dt2); // "5 days ago"
419
+ dt1.to(dt2); // "in 5 days"
420
+ ```
421
+
422
+ **Time Ranges:**
423
+ - 0-45 seconds: "a few seconds ago"
424
+ - 45-90 seconds: "a minute ago"
425
+ - 2-45 minutes: "X minutes ago"
426
+ - 45 minutes - 21 hours: "X hours ago"
427
+ - 21 hours - 30 days: "X days ago"
428
+ - 30 days - 1 year: "X months ago"
429
+ - 1+ years: "X years ago"
430
+
431
+ ## Zod Schemas
432
+
433
+ Validate datetime inputs with Zod:
434
+
435
+ ```typescript
436
+ import { DateInputSchema } from "@f-o-t/datetime";
437
+
438
+ // Validate user input
439
+ const result = DateInputSchema.safeParse("2024-01-15");
440
+
441
+ if (result.success) {
442
+ const dt = datetime(result.data);
443
+ }
444
+
445
+ // Use in API schemas
446
+ import { z } from "zod";
447
+
448
+ const EventSchema = z.object({
449
+ name: z.string(),
450
+ startDate: DateInputSchema,
451
+ endDate: DateInputSchema,
452
+ });
453
+
454
+ type Event = z.infer<typeof EventSchema>;
455
+ ```
456
+
457
+ **Accepted Inputs:**
458
+ - `Date` objects
459
+ - ISO date strings
460
+ - Unix timestamps (numbers)
461
+ - DateTime instances
462
+
463
+ ## Error Handling
464
+
465
+ The library provides specific error types:
466
+
467
+ ```typescript
468
+ import { InvalidDateError, PluginError } from "@f-o-t/datetime";
469
+
470
+ // InvalidDateError - thrown on invalid input
471
+ try {
472
+ datetime("invalid-date");
473
+ } catch (error) {
474
+ if (error instanceof InvalidDateError) {
475
+ console.log("Invalid date input:", error.input);
476
+ }
477
+ }
478
+
479
+ // PluginError - thrown on plugin issues
480
+ try {
481
+ DateTime.extend(samePluginAgain);
482
+ } catch (error) {
483
+ if (error instanceof PluginError) {
484
+ console.log("Plugin error:", error.pluginName);
485
+ }
486
+ }
487
+
488
+ // Check for invalid dates
489
+ const dt = datetime(new Date("invalid"));
490
+ if (!dt.isValid()) {
491
+ console.log("Date is invalid");
492
+ }
493
+ ```
494
+
495
+ ## Advanced Usage
496
+
497
+ ### Creating Custom Plugins
498
+
499
+ Extend DateTime with your own functionality:
500
+
501
+ ```typescript
502
+ import { createPlugin } from "@f-o-t/datetime";
503
+ import type { DateTimeClass } from "@f-o-t/datetime";
504
+
505
+ // Extend DateTime interface
506
+ declare module "@f-o-t/datetime" {
507
+ interface DateTime {
508
+ isLeapYear(): boolean;
509
+ }
510
+ }
511
+
512
+ // Create plugin
513
+ const leapYearPlugin = createPlugin(
514
+ "leapYear",
515
+ (DateTimeClass: DateTimeClass) => {
516
+ DateTimeClass.prototype.isLeapYear = function(): boolean {
517
+ const year = this.year();
518
+ return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
519
+ };
520
+ }
521
+ );
522
+
523
+ // Install plugin
524
+ DateTime.extend(leapYearPlugin);
525
+
526
+ // Use custom method
527
+ const dt = datetime("2024-01-15");
528
+ dt.isLeapYear(); // true
529
+ ```
530
+
531
+ ### Plugin Validation
532
+
533
+ Check if plugins are installed:
534
+
535
+ ```typescript
536
+ import timezonePlugin from "@f-o-t/datetime/plugins/timezone";
537
+
538
+ // Check if plugin installed
539
+ DateTime.hasPlugin("timezone"); // false
540
+
541
+ // Install plugin
542
+ DateTime.extend(timezonePlugin);
543
+
544
+ // Check again
545
+ DateTime.hasPlugin("timezone"); // true
546
+
547
+ // Get plugin instance
548
+ const plugin = DateTime.getPlugin("timezone");
549
+ ```
550
+
551
+ ### Method Chaining
552
+
553
+ All operations return DateTime instances, enabling fluent chaining:
554
+
555
+ ```typescript
556
+ const result = datetime("2024-01-15T10:00:00Z")
557
+ .addDays(7)
558
+ .startOfDay()
559
+ .addHours(9)
560
+ .setMinute(30);
561
+
562
+ // Result: 2024-01-22T09:30:00.000Z
563
+ ```
564
+
565
+ ### Working with Native Date
566
+
567
+ Convert between DateTime and native Date:
568
+
569
+ ```typescript
570
+ // DateTime to Date
571
+ const dt = datetime("2024-01-15");
572
+ const nativeDate = dt.toDate();
573
+
574
+ // Date to DateTime
575
+ const dt2 = datetime(nativeDate);
576
+
577
+ // Modify native date (won't affect DateTime due to cloning)
578
+ nativeDate.setFullYear(2025);
579
+ console.log(dt.year()); // Still 2024
580
+ ```
581
+
582
+ ## Best Practices
583
+
584
+ ### 1. Use UTC for Storage and Business Logic
585
+
586
+ ```typescript
587
+ // Good - UTC operations
588
+ const dt = datetime("2024-01-15T10:00:00Z");
589
+ const tomorrow = dt.addDays(1);
590
+
591
+ // Store as ISO string
592
+ const stored = dt.toISO(); // "2024-01-15T10:00:00.000Z"
593
+
594
+ // Use timezone plugin for display only
595
+ const displayed = dt.tz("America/New_York");
596
+ ```
597
+
598
+ ### 2. Validate User Input
599
+
600
+ ```typescript
601
+ import { DateInputSchema } from "@f-o-t/datetime";
602
+
603
+ function parseUserDate(input: unknown): DateTime | null {
604
+ const result = DateInputSchema.safeParse(input);
605
+ if (!result.success) {
606
+ return null;
607
+ }
608
+
609
+ const dt = datetime(result.data);
610
+ return dt.isValid() ? dt : null;
611
+ }
612
+ ```
613
+
614
+ ### 3. Use Immutability to Your Advantage
615
+
616
+ ```typescript
617
+ // Safe to pass around without worrying about mutations
618
+ function processDate(dt: DateTime) {
619
+ // This doesn't affect the original
620
+ const modified = dt.addDays(1);
621
+ return modified;
622
+ }
623
+
624
+ const original = datetime("2024-01-15");
625
+ const result = processDate(original);
626
+ // original is unchanged
627
+ ```
628
+
629
+ ### 4. Leverage TypeScript for Safety
630
+
631
+ ```typescript
632
+ import type { DateTime, TimeUnit } from "@f-o-t/datetime";
633
+
634
+ function calculateAge(birthDate: DateTime): number {
635
+ const now = datetime();
636
+ return Math.floor(now.diff(birthDate, "year"));
637
+ }
638
+
639
+ // Type-safe unit parameter
640
+ function addTime(dt: DateTime, amount: number, unit: TimeUnit): DateTime {
641
+ switch (unit) {
642
+ case "day": return dt.addDays(amount);
643
+ case "hour": return dt.addHours(amount);
644
+ // TypeScript ensures all units are handled
645
+ }
646
+ }
647
+ ```
648
+
649
+ ### 5. Install Plugins Once at Startup
650
+
651
+ ```typescript
652
+ // app.ts or main.ts
653
+ import { DateTime } from "@f-o-t/datetime";
654
+ import timezonePlugin from "@f-o-t/datetime/plugins/timezone";
655
+ import formatPlugin from "@f-o-t/datetime/plugins/format";
656
+
657
+ // Install plugins once
658
+ DateTime.extend(timezonePlugin);
659
+ DateTime.extend(formatPlugin);
660
+
661
+ // Now available everywhere
662
+ ```
663
+
664
+ ## TypeScript
665
+
666
+ Full TypeScript support with strict types:
667
+
668
+ ```typescript
669
+ import type {
670
+ DateTime,
671
+ DateInput,
672
+ DateTimeClass,
673
+ DateTimeConfig,
674
+ DateTimePlugin,
675
+ TimeUnit,
676
+ } from "@f-o-t/datetime";
677
+
678
+ // DateTime is the core instance type
679
+ const dt: DateTime = datetime();
680
+
681
+ // DateInput accepts multiple input types
682
+ const input: DateInput = "2024-01-15";
683
+ const dt2: DateTime = datetime(input);
684
+
685
+ // TimeUnit for diff operations
686
+ const unit: TimeUnit = "day";
687
+ const difference: number = dt.diff(dt2, unit);
688
+
689
+ // DateTimePlugin for custom plugins
690
+ const plugin: DateTimePlugin = {
691
+ name: "custom",
692
+ install: (DateTimeClass: DateTimeClass) => {
693
+ // Add methods
694
+ }
695
+ };
696
+ ```
697
+
698
+ ## Performance
699
+
700
+ The library is optimized for common datetime operations:
701
+
702
+ - **10,000 creations**: < 100ms
703
+ - **10,000 arithmetic operations**: < 50ms
704
+ - **10,000 comparisons**: < 30ms
705
+ - **10,000 format operations**: < 200ms
706
+ - **10,000 timezone conversions**: < 300ms
707
+
708
+ All benchmarks run with Bun runtime on modern hardware.
709
+
710
+ ## Contributing
711
+
712
+ Contributions are welcome! Please check the repository for guidelines.
713
+
714
+ ## License
715
+
716
+ MIT License - see [LICENSE](./LICENSE) file for details.
717
+
718
+ ## Credits
719
+
720
+ Inspired by Day.js and built by the Finance Tracker team as part of the F-O-T libraries collection.
721
+
722
+ ## Links
723
+
724
+ - [GitHub Repository](https://github.com/F-O-T/libraries)
725
+ - [Issue Tracker](https://github.com/F-O-T/libraries/issues)
726
+ - [NPM Package](https://www.npmjs.com/package/@f-o-t/datetime)