-
Notifications
You must be signed in to change notification settings - Fork 279
Expand file tree
/
Copy pathDateFormat.ts
More file actions
162 lines (139 loc) · 6.56 KB
/
DateFormat.ts
File metadata and controls
162 lines (139 loc) · 6.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import type DateFormatT from "sap/ui/core/format/DateFormat";
// @ts-ignore
import DateFormatNative from "./sap/ui/core/format/DateFormat.js";
import getLocale from "@ui5/webcomponents-base/dist/locale/getLocale.js";
import LocaleWrapped from "./Locale.js";
import type CalendarWeekNumbering from "sap/base/i18n/date/CalendarWeekNumbering";
import type CalendarType from "sap/base/i18n/date/CalendarType";
type DateFormatOptions = {
calendarWeekNumbering?: CalendarWeekNumbering | keyof typeof CalendarWeekNumbering;
firstDayOfWeek?: int;
minimalDaysInFirstWeek?: int;
format?: string;
pattern?: string;
style?: string;
strictParsing?: boolean;
relative?: boolean;
relativeRange?: int[];
relativeScale?: string;
relativeStyle?: string;
interval?: boolean;
intervalDelimiter?: string;
singleIntervalValue?: boolean;
UTC?: boolean;
calendarType?: CalendarType | keyof typeof CalendarType;
};
const DateFormatWrapped = DateFormatNative as typeof DateFormatT;
class DateFormat extends DateFormatWrapped {
/**
* Central cache for all DateFormat instances across the entire library.
* Shared by Calendar, DatePicker, TimePicker, and all other date components.
* Key format: "type:JSON.stringify(options):locale"
* @private
*/
private static _cache = new Map<string, DateFormat>();
private static _stats = {
totalCalls: 0,
cacheHits: 0,
cacheMisses: 0,
uniqueInstances: 0,
};
static logCacheStats() {
console.log("===== DateFormat Cache Statistics =====");
console.log(`Total calls: ${DateFormat._stats.totalCalls}`);
console.log(`Cache hits: ${DateFormat._stats.cacheHits} (${DateFormat._stats.totalCalls > 0 ? ((DateFormat._stats.cacheHits / DateFormat._stats.totalCalls) * 100).toFixed(1) : 0}%)`);
console.log(`Cache misses: ${DateFormat._stats.cacheMisses} (${DateFormat._stats.totalCalls > 0 ? ((DateFormat._stats.cacheMisses / DateFormat._stats.totalCalls) * 100).toFixed(1) : 0}%)`);
console.log(`Unique instances: ${DateFormat._cache.size}`);
console.log(`Total instances: ${(window as any).dateformatinstances?.size || 0}`);
console.log("Cache keys:");
Array.from(DateFormat._cache.keys()).forEach((key, index) => {
console.log(` ${index + 1}. ${key}`);
});
console.log("=========================================\n");
return {
totalCalls: DateFormat._stats.totalCalls,
cacheHits: DateFormat._stats.cacheHits,
cacheMisses: DateFormat._stats.cacheMisses,
uniqueInstances: DateFormat._cache.size,
totalInstances: (window as any).dateformatinstances?.size || 0,
};
}
static getDateInstance(oFormatOptions?: DateFormatOptions, oLocale?: LocaleWrapped): DateFormat;
static getDateInstance(oLocale?: LocaleWrapped): DateFormat;
static getDateInstance(oFormatOptionsOrLocale?: DateFormatOptions | LocaleWrapped, oLocale?: LocaleWrapped): DateFormat {
DateFormat._stats.totalCalls++;
if (oFormatOptionsOrLocale instanceof LocaleWrapped) {
return DateFormatWrapped.getDateInstance(undefined, oFormatOptionsOrLocale);
}
const nativeLocale = oLocale ?? new LocaleWrapped(getLocale().toString());
const cacheKey = `date:${JSON.stringify(oFormatOptionsOrLocale || {})}:${nativeLocale.toString()}`;
if (!DateFormat._cache.has(cacheKey)) {
DateFormat._stats.cacheMisses++;
console.log(`[DateFormat CACHE MISS #${DateFormat._stats.cacheMisses}] Creating NEW date instance | Total instances: ${DateFormat._cache.size + 1}`);
console.log(` Key: ${cacheKey}`);
const date = DateFormatWrapped.getDateInstance(oFormatOptionsOrLocale, nativeLocale);
DateFormat._cache.set(cacheKey, date);
} else {
DateFormat._stats.cacheHits++;
console.log(`[DateFormat CACHE HIT #${DateFormat._stats.cacheHits}] Reusing CACHED date instance`);
}
return DateFormat._cache.get(cacheKey)!;
}
static getTimeInstance(oFormatOptions?: DateFormatOptions, oLocale?: LocaleWrapped): DateFormat;
static getTimeInstance(oLocale?: LocaleWrapped): DateFormat;
static getTimeInstance(oFormatOptionsOrLocale?: DateFormatOptions | LocaleWrapped, oLocale?: LocaleWrapped): DateFormat {
DateFormat._stats.totalCalls++;
if (oFormatOptionsOrLocale instanceof LocaleWrapped) {
return DateFormatWrapped.getTimeInstance(undefined, oFormatOptionsOrLocale);
}
const nativeLocale = oLocale ?? new LocaleWrapped(getLocale().toString());
const cacheKey = `time:${JSON.stringify(oFormatOptionsOrLocale || {})}:${nativeLocale.toString()}`;
if (!DateFormat._cache.has(cacheKey)) {
DateFormat._stats.cacheMisses++;
console.log(`[DateFormat CACHE MISS #${DateFormat._stats.cacheMisses}] Creating NEW time instance | Total instances: ${DateFormat._cache.size + 1}`);
console.log(` Key: ${cacheKey}`);
const time = DateFormatWrapped.getTimeInstance(oFormatOptionsOrLocale, nativeLocale);
DateFormat._cache.set(cacheKey, time);
} else {
DateFormat._stats.cacheHits++;
console.log(`[DateFormat CACHE HIT #${DateFormat._stats.cacheHits}] Reusing CACHED time instance`);
}
return DateFormat._cache.get(cacheKey)!;
}
static getDateTimeInstance(oFormatOptions?: DateFormatOptions, oLocale?: LocaleWrapped): DateFormat;
static getDateTimeInstance(oLocale?: LocaleWrapped): DateFormat;
static getDateTimeInstance(oFormatOptionsOrLocale?: DateFormatOptions | LocaleWrapped, oLocale?: LocaleWrapped): DateFormat {
DateFormat._stats.totalCalls++;
if (oFormatOptionsOrLocale instanceof LocaleWrapped) {
return DateFormatWrapped.getDateTimeInstance(undefined, oFormatOptionsOrLocale);
}
const nativeLocale = oLocale ?? new LocaleWrapped(getLocale().toString());
const cacheKey = `datetime:${JSON.stringify(oFormatOptionsOrLocale || {})}:${nativeLocale.toString()}`;
if (!DateFormat._cache.has(cacheKey)) {
DateFormat._stats.cacheMisses++;
console.log(`[DateFormat CACHE MISS #${DateFormat._stats.cacheMisses}] Creating NEW datetime instance | Total instances: ${DateFormat._cache.size + 1}`);
console.log(` Key: ${cacheKey}`);
const datetime = DateFormatWrapped.getDateTimeInstance(oFormatOptionsOrLocale, nativeLocale);
DateFormat._cache.set(cacheKey, datetime);
} else {
DateFormat._stats.cacheHits++;
console.log(`[DateFormat CACHE HIT #${DateFormat._stats.cacheHits}] Reusing CACHED datetime instance`);
}
return DateFormat._cache.get(cacheKey)!;
}
}
// @ts-ignore
window.DateFormatStats = {
log: () => DateFormat.logCacheStats(),
get: () => ({
// @ts-ignore
totalCalls: DateFormat._stats.totalCalls,
// @ts-ignore
cacheHits: DateFormat._stats.cacheHits,
// @ts-ignore
cacheMisses: DateFormat._stats.cacheMisses,
// @ts-ignore
uniqueInstances: DateFormat._cache.size,
}),
};
export default DateFormat;