Skip to content

Commit 30fb820

Browse files
committed
feat(locale): add internationalization support 🌐
- Add locale alias configuration - Add locale directory with multiple locale files - Add locale support to Daytime class - Add locale types and interfaces - Add locale utility functions to Main - Update format utility to use locale data - Update relative time utility to use locale data
1 parent 9637235 commit 30fb820

112 files changed

Lines changed: 7752 additions & 125 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export default defineBuildConfig({
1515
/** Aliases for the build */
1616
alias: {
1717
'@app': resolve(__dirname, 'src'),
18+
'@locale': resolve(__dirname, 'src/locale'),
1819
'@helpers': resolve(__dirname, 'src/helpers'),
1920
'@utils': resolve(__dirname, 'src/utils')
2021
},

deno.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
"@std/expect": "jsr:@std/expect@^1.0.17",
9797
"@app/": "./src/",
9898
"@helpers/": "./src/helpers/",
99+
"@locale/": "./src/locale/",
99100
"@utils/": "./src/utils/",
100101
"@tests/": "./tests/"
101102
},

src/Daytime.ts

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type * as Types from '@app/Types.ts'
22
import * as Helpers from '@helpers/index.ts'
3+
import * as Locale from '@locale/index.ts'
34
import * as Utils from '@utils/index.ts'
45

56
/**
@@ -9,13 +10,22 @@ import * as Utils from '@utils/index.ts'
910
export class Daytime implements Types.IDaytime {
1011
/** The date object */
1112
private readonly date: Date
13+
/** The locale code for this instance */
14+
private readonly localeCode: string
1215

1316
/**
1417
* Creates a new Daytime instance.
1518
* @param input - Optional date input (Date, number, string, or object with toDate method)
19+
* @param localeCode - Optional locale code (defaults to default locale)
1620
*/
17-
constructor(input?: Types.DateInput) {
21+
constructor(input?: Types.DateInput, localeCode?: string) {
1822
this.date = Utils.parseDateInput(input)
23+
if (localeCode) {
24+
const normalized = Locale.normalizeLocaleCode(localeCode)
25+
this.localeCode = normalized
26+
} else {
27+
this.localeCode = Locale.getDefaultLocale()
28+
}
1929
}
2030

2131
/**
@@ -26,7 +36,7 @@ export class Daytime implements Types.IDaytime {
2636
*/
2737
add(value: number, unit: Types.TimeUnit): Types.IDaytime {
2838
const newDate = Utils.addTime(this.date, value, unit)
29-
return new Daytime(newDate)
39+
return new Daytime(newDate, this.localeCode)
3040
}
3141

3242
/**
@@ -50,7 +60,7 @@ export class Daytime implements Types.IDaytime {
5060
* @returns A new Daytime instance with the same date
5161
*/
5262
clone(): Types.IDaytime {
53-
return new Daytime(Helpers.cloneDate(this.date))
63+
return new Daytime(Helpers.cloneDate(this.date), this.localeCode)
5464
}
5565

5666
/**
@@ -114,7 +124,7 @@ export class Daytime implements Types.IDaytime {
114124
*/
115125
endOf(unit: Types.TimeUnit): Types.IDaytime {
116126
const newDate = Utils.endOf(this.date, unit)
117-
return new Daytime(newDate)
127+
return new Daytime(newDate, this.localeCode)
118128
}
119129

120130
/**
@@ -123,15 +133,34 @@ export class Daytime implements Types.IDaytime {
123133
* @returns The formatted date string
124134
*/
125135
format(pattern: string): string {
126-
return Utils.formatDate(this.date, pattern)
136+
return Utils.formatDate(this.date, pattern, this.localeCode)
127137
}
128138

129139
/**
130140
* Gets a human-readable relative time string from now.
131141
* @returns A relative time string (e.g., "2 hours ago", "in 3 days")
132142
*/
133143
fromNow(): string {
134-
return Utils.getRelativeTime(this.date)
144+
return Utils.getRelativeTime(this.date, this.localeCode)
145+
}
146+
147+
/**
148+
* Gets the current locale code.
149+
* @returns The locale code
150+
*/
151+
locale(): string
152+
/**
153+
* Sets the locale and returns a new Daytime instance.
154+
* @param code - The locale code to set
155+
* @returns A new Daytime instance with the locale set
156+
*/
157+
locale(code: Types.LocaleCode): Types.IDaytime
158+
locale(code?: Types.LocaleCode): string | Types.IDaytime {
159+
if (code === undefined) {
160+
return this.localeCode
161+
}
162+
const normalized = Locale.normalizeLocaleCode(code)
163+
return new Daytime(this.date, normalized)
135164
}
136165

137166
/**
@@ -150,7 +179,7 @@ export class Daytime implements Types.IDaytime {
150179
*/
151180
getDaysInMonth(): Types.IDaytime[] {
152181
const days = Helpers.getDaysInMonth(this.date)
153-
return days.map((day) => new Daytime(day))
182+
return days.map((day) => new Daytime(day, this.localeCode))
154183
}
155184

156185
/**
@@ -159,7 +188,7 @@ export class Daytime implements Types.IDaytime {
159188
*/
160189
getMonthsInYear(): Types.IDaytime[] {
161190
const months = Helpers.getMonthsInYear(this.date)
162-
return months.map((month) => new Daytime(month))
191+
return months.map((month) => new Daytime(month, this.localeCode))
163192
}
164193

165194
/**
@@ -169,7 +198,7 @@ export class Daytime implements Types.IDaytime {
169198
*/
170199
getWeeksInMonth(): Types.IDaytime[][] {
171200
const weeks = Helpers.getWeeksInMonth(this.date)
172-
return weeks.map((week) => week.map((day) => new Daytime(day)))
201+
return weeks.map((week) => week.map((day) => new Daytime(day, this.localeCode)))
173202
}
174203

175204
/**
@@ -470,7 +499,7 @@ export class Daytime implements Types.IDaytime {
470499
*/
471500
local(): Types.IDaytime {
472501
const localDate = Helpers.cloneDate(this.date)
473-
return new Daytime(localDate)
502+
return new Daytime(localDate, this.localeCode)
474503
}
475504

476505
/**
@@ -504,7 +533,7 @@ export class Daytime implements Types.IDaytime {
504533
*/
505534
lastWeekday(weekday: number): Types.IDaytime {
506535
const newDate = Helpers.lastWeekday(this.date, weekday)
507-
return new Daytime(newDate)
536+
return new Daytime(newDate, this.localeCode)
508537
}
509538

510539
/**
@@ -513,7 +542,7 @@ export class Daytime implements Types.IDaytime {
513542
*/
514543
nearestWeekday(): Types.IDaytime {
515544
const newDate = Helpers.nearestWeekday(this.date)
516-
return new Daytime(newDate)
545+
return new Daytime(newDate, this.localeCode)
517546
}
518547

519548
/**
@@ -522,7 +551,7 @@ export class Daytime implements Types.IDaytime {
522551
*/
523552
nextBusinessDay(): Types.IDaytime {
524553
const newDate = Helpers.nextBusinessDay(this.date)
525-
return new Daytime(newDate)
554+
return new Daytime(newDate, this.localeCode)
526555
}
527556

528557
/**
@@ -532,7 +561,7 @@ export class Daytime implements Types.IDaytime {
532561
*/
533562
nextWeekday(weekday: number): Types.IDaytime {
534563
const newDate = Helpers.nextWeekday(this.date, weekday)
535-
return new Daytime(newDate)
564+
return new Daytime(newDate, this.localeCode)
536565
}
537566

538567
/**
@@ -543,7 +572,7 @@ export class Daytime implements Types.IDaytime {
543572
*/
544573
nthWeekday(n: number, weekday: number): Types.IDaytime {
545574
const newDate = Helpers.nthWeekday(this.date, n, weekday)
546-
return new Daytime(newDate)
575+
return new Daytime(newDate, this.localeCode)
547576
}
548577

549578
/**
@@ -552,7 +581,7 @@ export class Daytime implements Types.IDaytime {
552581
*/
553582
prevBusinessDay(): Types.IDaytime {
554583
const newDate = Helpers.prevBusinessDay(this.date)
555-
return new Daytime(newDate)
584+
return new Daytime(newDate, this.localeCode)
556585
}
557586

558587
/**
@@ -562,7 +591,7 @@ export class Daytime implements Types.IDaytime {
562591
*/
563592
prevWeekday(weekday: number): Types.IDaytime {
564593
const newDate = Helpers.prevWeekday(this.date, weekday)
565-
return new Daytime(newDate)
594+
return new Daytime(newDate, this.localeCode)
566595
}
567596

568597
/**
@@ -610,10 +639,10 @@ export class Daytime implements Types.IDaytime {
610639
throw new Error('Value is required when setting a single component')
611640
}
612641
const newDate = Utils.setSingleComponent(this.date, optionsOrUnit, value)
613-
return new Daytime(newDate)
642+
return new Daytime(newDate, this.localeCode)
614643
}
615644
const newDate = Utils.setDateComponent(this.date, optionsOrUnit)
616-
return new Daytime(newDate)
645+
return new Daytime(newDate, this.localeCode)
617646
}
618647

619648
/**
@@ -624,7 +653,7 @@ export class Daytime implements Types.IDaytime {
624653
*/
625654
startOf(unit: Types.TimeUnit): Types.IDaytime {
626655
const newDate = Utils.startOf(this.date, unit)
627-
return new Daytime(newDate)
656+
return new Daytime(newDate, this.localeCode)
628657
}
629658

630659
/**
@@ -635,7 +664,7 @@ export class Daytime implements Types.IDaytime {
635664
*/
636665
subtract(value: number, unit: Types.TimeUnit): Types.IDaytime {
637666
const newDate = Utils.subtractTime(this.date, value, unit)
638-
return new Daytime(newDate)
667+
return new Daytime(newDate, this.localeCode)
639668
}
640669

641670
/**
@@ -726,7 +755,7 @@ export class Daytime implements Types.IDaytime {
726755
*/
727756
toTimezone(tz: string): Types.IDaytime {
728757
const newDate = Helpers.convertToTimezone(this.date, tz)
729-
return new Daytime(newDate)
758+
return new Daytime(newDate, this.localeCode)
730759
}
731760

732761
/**
@@ -752,7 +781,7 @@ export class Daytime implements Types.IDaytime {
752781
components.second,
753782
components.millisecond
754783
)
755-
return new Daytime(utcDate)
784+
return new Daytime(utcDate, this.localeCode)
756785
}
757786

758787
/**

src/Main.ts

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,49 @@
11
import type * as Types from '@app/Types.ts'
2+
import * as Locale from '@locale/index.ts'
23
import { Daytime } from '@app/Daytime.ts'
34

45
/**
56
* Factory function to create a Daytime instance.
67
* @description Creates a new Daytime instance from the given date input.
78
* @param date - Optional date input (Date, number, string, or object with toDate method)
9+
* @param localeCode - Optional locale code (defaults to default locale)
810
* @returns A new Daytime instance
911
*/
10-
export default function daytime(date?: Types.DateInput): Daytime {
11-
return new Daytime(date)
12+
export default function daytime(date?: Types.DateInput, localeCode?: Types.LocaleCode): Daytime {
13+
return new Daytime(date, localeCode)
14+
}
15+
16+
/**
17+
* Sets the default locale for all new Daytime instances.
18+
* @param code - The locale code to set as default
19+
*/
20+
daytime.setDefaultLocale = (code: Types.LocaleCode): void => {
21+
Locale.setDefaultLocale(code)
22+
}
23+
24+
/**
25+
* Gets the default locale code.
26+
* @returns The default locale code
27+
*/
28+
daytime.getDefaultLocale = (): string => {
29+
return Locale.getDefaultLocale()
30+
}
31+
32+
/**
33+
* Registers a custom locale.
34+
* @param code - The locale code
35+
* @param data - The locale data
36+
*/
37+
daytime.registerLocale = (code: string, data: Types.LocaleData): void => {
38+
Locale.registerLocale(code, data)
39+
}
40+
41+
/**
42+
* Gets all available locale codes.
43+
* @returns Array of available locale codes
44+
*/
45+
daytime.getAvailableLocales = (): string[] => {
46+
return Locale.getAvailableLocales()
1247
}
1348

1449
/**

0 commit comments

Comments
 (0)