@dative-gpi/foundation-shared-services 1.0.7 → 1.0.9

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,256 +1,145 @@
1
- import { format, subDays, addDays, addMilliseconds, parse } from "date-fns";
2
- import type { Locale } from "date-fns/locale";
3
- import { enUS, enGB, fr, it, es, de } from "date-fns/locale";
1
+ import { addMilliseconds, format, parse, subDays } from "date-fns";
4
2
  import { computed, ref } from "vue";
5
3
 
6
4
  import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
7
- import type { TimeZoneInfos } from "@dative-gpi/foundation-shared-domain/models";
8
- import { isoTimeFormat } from "@dative-gpi/foundation-shared-domain/tools";
5
+ import { ISO_FORMAT, OPTIONS } from "@dative-gpi/foundation-shared-domain/tools";
9
6
 
10
7
  import { useAppLanguageCode } from "./useAppLanguageCode";
11
8
 
12
- const timeZone = ref<TimeZoneInfos | null>(null);
9
+ const timeZone = ref<string | undefined>(undefined);
13
10
 
14
11
  export const useAppTimeZone = () => {
15
- const setAppTimeZone = (payload: TimeZoneInfos) => {
12
+ const { $tr } = useTranslationsProvider();
13
+
14
+ const setAppTimeZone = (payload: string) => {
16
15
  timeZone.value = payload;
17
16
  };
18
17
 
19
- const getOffsetNumber = (offsetString: string, hours: boolean = false): number => {
20
- let offset = 0;
21
- switch (offsetString.toLowerCase().replaceAll(" ", "")) {
22
- case "utc-11:00:00": offset = -11; break;
23
- case "utc-10:00:00": offset = -10; break;
24
- case "utc-09:00:00": offset = -9; break;
25
- case "utc-08:00:00": offset = -8; break;
26
- case "utc-07:00:00": offset = -7; break;
27
- case "utc-06:00:00": offset = -6; break;
28
- case "utc-05:00:00": offset = -5; break;
29
- case "utc-04:00:00": offset = -4; break;
30
- case "utc-03:00:00": offset = -3; break;
31
- case "utc-02:00:00": offset = -2; break;
32
- case "utc-01:00:00": offset = -1; break;
33
- case "utc+01:00:00": offset = +1; break;
34
- case "utc+02:00:00": offset = +2; break;
35
- case "utc+03:00:00": offset = +3; break;
36
- case "utc+04:00:00": offset = +4; break;
37
- case "utc+05:00:00": offset = +5; break;
38
- case "utc+06:00:00": offset = +6; break;
39
- case "utc+07:00:00": offset = +7; break;
40
- case "utc+08:00:00": offset = +8; break;
41
- case "utc+09:00:00": offset = +9; break;
42
- case "utc+10:00:00": offset = +10; break;
43
- case "utc+11:00:00": offset = +11; break;
44
- case "utc+12:00:00": offset = +12; break;
45
- case "utc+13:00:00": offset = +13; break;
46
- case "utc+14:00:00": offset = +14; break;
18
+ const epochToShortDateFormat = (value: number | null | undefined): string => {
19
+ if (value == null || !isFinite(value)) {
20
+ return "";
47
21
  }
48
- return hours ? offset : offset * 60 * 60 * 1000;
22
+ const date = new Date(value);
23
+ return date.toLocaleString(useAppLanguageCode().languageCode.value, { ...OPTIONS.shortDate, timeZone: timeZone.value });
49
24
  };
50
25
 
51
- const userOffset = (): number => {
52
- return getOffsetNumber(getUserOffset());
26
+ const epochToLongDateFormat = (value: number | null | undefined): string => {
27
+ if (value == null || !isFinite(value)) {
28
+ return "";
29
+ }
30
+ const date = new Date(value);
31
+ const now = new Date();
32
+ if (date.toLocaleString(useAppLanguageCode().languageCode.value, { ...OPTIONS.shortDate, timeZone: timeZone.value }) === now.toLocaleString(useAppLanguageCode().languageCode.value, { ...OPTIONS.shortDate, timeZone: timeZone.value })) {
33
+ return $tr("ui.time-zone.today", "Today");
34
+ }
35
+ if (date.toLocaleString(useAppLanguageCode().languageCode.value, { ...OPTIONS.shortDate, timeZone: timeZone.value }) === subDays(now, 1).toLocaleString(useAppLanguageCode().languageCode.value, { ...OPTIONS.shortDate, timeZone: timeZone.value })) {
36
+ return $tr("ui.time-zone.yesterday", "Yesterday");
37
+ }
38
+ const dateString = date.toLocaleString(useAppLanguageCode().languageCode.value, { ...OPTIONS.longDate, timeZone: timeZone.value });
39
+ return dateString[0].toLocaleUpperCase() + dateString.slice(1);
53
40
  };
54
41
 
55
- const machineOffset = (): number => {
56
- return getOffsetNumber(getMachineOffset());
42
+ const epochToShortTimeFormat = (value: number | null | undefined): string => {
43
+ if (value == null || !isFinite(value)) {
44
+ return "";
45
+ }
46
+ const date = new Date(value);
47
+ return date.toLocaleString(useAppLanguageCode().languageCode.value, { ...OPTIONS.shortTime, timeZone: timeZone.value });
57
48
  };
58
49
 
59
- const getUserOffset = (): string => {
60
- return timeZone?.value?.offset ?? "UTC +00:00:00";
50
+ const epochToLongTimeFormat = (value: number | null | undefined): string => {
51
+ if (value == null || !isFinite(value)) {
52
+ return "";
53
+ }
54
+ const date = new Date(value);
55
+ const now = new Date();
56
+ if (date.toLocaleString(useAppLanguageCode().languageCode.value, { ...OPTIONS.shortDate, timeZone: timeZone.value }) === now.toLocaleString(useAppLanguageCode().languageCode.value, { ...OPTIONS.shortDate, timeZone: timeZone.value })) {
57
+ return `${$tr("ui.time-zone.today-at", "Today at")} ${date.toLocaleString(useAppLanguageCode().languageCode.value, { ...OPTIONS.time, timeZone: timeZone.value })}`;
58
+ }
59
+ if (date.toLocaleString(useAppLanguageCode().languageCode.value, { ...OPTIONS.shortDate, timeZone: timeZone.value }) === subDays(now, 1).toLocaleString(useAppLanguageCode().languageCode.value, { ...OPTIONS.shortDate, timeZone: timeZone.value })) {
60
+ return `${$tr("ui.time-zone.yesterday-at", "Yesterday at")} ${date.toLocaleString(useAppLanguageCode().languageCode.value, { ...OPTIONS.time, timeZone: timeZone.value })}`;
61
+ }
62
+ const dateString = date.toLocaleString(useAppLanguageCode().languageCode.value, { ...OPTIONS.longTime, timeZone: timeZone.value });
63
+ return dateString[0].toLocaleUpperCase() + dateString.slice(1);
61
64
  };
62
65
 
63
- const getUserOffsetMillis = (): number => {
64
- const offset = timeZone?.value?.offset.slice(3) ?? "";
65
- const matchData = offset.match(/([+-])(\d+)(?::(\d+))?/);
66
- if (matchData) {
67
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
68
- const [_, sign, hour, minute] = matchData;
69
- return parseInt(sign + "1") * ((hour ? parseInt(hour) : 0) * 60 + (minute ? parseInt(minute) : 0)) * 60 * 1000;
66
+ const epochToTimeOnlyFormat = (value: number | null | undefined): string => {
67
+ if (value == null || !isFinite(value)) {
68
+ return "";
70
69
  }
71
- return 0;
70
+ const date = new Date(value);
71
+ return date.toLocaleString(useAppLanguageCode().languageCode.value, { ...OPTIONS.time, timeZone: timeZone.value });
72
72
  };
73
73
 
74
- const getMachineOffset = (): string => {
75
- const timeZoneName = Intl.DateTimeFormat("ia", {
76
- timeZoneName: "short",
77
- timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone
78
- }).formatToParts().find((i) => i.type === "timeZoneName")?.value ?? "";
79
-
80
- const offset = timeZoneName.slice(3);
81
- if (!offset) {
82
- return "UTC +00:00:00";
83
- }
84
- const matchData = offset.match(/([+-])(\d+)(?::(\d+))?/);
85
- if (matchData) {
86
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
87
- const [_, sign, hour, minute] = matchData;
88
- return `UTC ${sign}${hour.padStart(2, "0")}:${(minute ?? "").padStart(2, "0")}:00`;
89
- }
90
- return "UTC +00:00:00";
74
+ const getOffsetUser = (): number => {
75
+ const offsetParts = (Intl.DateTimeFormat(undefined, {
76
+ timeZone: timeZone.value,
77
+ timeZoneName: "longOffset"
78
+ }).formatToParts(new Date).pop()?.value.slice(3) || "+00:00").split(':');
79
+ return (parseInt(offsetParts[0]) * 60 + parseInt(offsetParts[1])) * 60 * 1000;
91
80
  };
92
81
 
93
- const getMachineOffsetMillis = (): number => {
94
- const timeZoneName = Intl.DateTimeFormat("ia", {
95
- timeZoneName: "short",
96
- timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone
97
- }).formatToParts().find((i) => i.type === "timeZoneName")?.value ?? "";
82
+ const getOffsetMachine = (): number => {
83
+ const offsetParts = (Intl.DateTimeFormat(undefined, {
84
+ timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
85
+ timeZoneName: "longOffset"
86
+ }).formatToParts(new Date).pop()?.value.slice(3) || "+00:00").split(':');
87
+ return (parseInt(offsetParts[0]) * 60 + parseInt(offsetParts[1])) * 60 * 1000;
88
+ };
98
89
 
99
- const offset = timeZoneName.slice(3);
100
- if (!offset) {
90
+ const getOffsetDifference = (): number => {
91
+ if (timeZone.value == null) {
101
92
  return 0;
102
93
  }
103
- const matchData = offset.match(/([+-])(\d+)(?::(\d+))?/);
104
- if (matchData) {
105
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
106
- const [_, sign, hour, minute] = matchData;
107
- return parseInt(sign + "1") * ((hour ? parseInt(hour) : 0) * 60 + (minute ? parseInt(minute) : 0)) * 60 * 1000;
108
- }
109
- return 0;
94
+ return getOffsetUser() - getOffsetMachine();
110
95
  };
111
96
 
112
- const todayToEpoch = (resetHours: boolean): number => {
113
- const today = new Date();
114
- if (resetHours) {
115
- today.setHours(0, 0, 0, 0);
116
- }
117
- return today.getTime() + getMachineOffsetMillis() - getUserOffsetMillis();
97
+ const todayToEpoch = (): number => {
98
+ return (new Date().getTime() + getOffsetDifference());
118
99
  };
119
100
 
120
101
  const pickerToEpoch = (value: Date | null | undefined): number => {
121
102
  if (value != null) {
122
- // FSCalendar is always in machine time zone, so we need to convert it to user time zone
123
- return value.getTime() + getMachineOffsetMillis() - getUserOffsetMillis();
103
+ return value.getTime() - getOffsetDifference();
124
104
  }
125
105
  return 0;
126
106
  };
127
107
 
128
108
  const epochToPicker = (value: number | null | undefined): Date => {
129
- const date = new Date(0);
130
109
  if (value != null) {
131
- // Epoch is always without time zone, so we need to convert it to user time zone
132
- date.setUTCMilliseconds(value - getMachineOffsetMillis() + getUserOffsetMillis());
110
+ return new Date(value + getOffsetDifference());
133
111
  }
134
- return date;
112
+ return new Date(0);
135
113
  };
136
114
 
137
115
  const epochToPickerHeader = (value: number): { d: number, m: number, y: number } => {
138
- const date = new Date(0);
139
- if (value != null) {
140
- date.setUTCMilliseconds(value - getMachineOffsetMillis() + getUserOffsetMillis());
141
- }
116
+ const date = epochToPicker(value);
142
117
  return { d: date.getDate(), m: date.getMonth(), y: date.getFullYear() };
143
118
  };
144
119
 
145
- const epochToLongDateFormat = (value: number | null | undefined): string => {
146
- if (value == null || !isFinite(value)) {
147
- return "";
148
- }
149
- const date = new Date(0);
150
- date.setUTCMilliseconds(value - getMachineOffsetMillis() + getUserOffsetMillis());
151
- return format(date, "EEEE dd LLLL yyyy", { locale: getLocale() });
152
- };
153
-
154
- const epochToLongTimeFormat = (value: number | null | undefined): string => {
155
- if (value == null || !isFinite(value)) {
156
- return "";
157
- }
158
- const date = new Date(0);
159
- date.setUTCMilliseconds(value - getMachineOffsetMillis() + getUserOffsetMillis());
160
- return format(date, overrideFormat(date, "EEEE dd LLLL yyyy HH:mm"), { locale: getLocale() })
161
- };
162
-
163
- const epochToShortDateFormat = (value: number | null | undefined): string => {
164
- if (value == null || !isFinite(value)) {
165
- return "";
166
- }
167
- const date = new Date(0);
168
- date.setUTCMilliseconds(value - getMachineOffsetMillis() + getUserOffsetMillis());
169
- switch (getLocale()) {
170
- case enUS: {
171
- return format(date, "MM/dd/yyyy", { locale: getLocale() });
172
- }
173
- default: {
174
- return format(date, "dd/MM/yyyy", { locale: getLocale() });
175
- }
176
- }
177
- };
178
-
179
- const epochToTimeOnlyFormat = (value: number | null | undefined): string => {
180
- if (value == null || !isFinite(value)) {
181
- return "";
182
- }
183
- const date = new Date(0);
184
- date.setUTCMilliseconds(value - getMachineOffsetMillis() + getUserOffsetMillis());
185
- return format(date, "HH:mm:ss", { locale: getLocale() });
186
- };
187
-
188
- const epochToShortTimeFormat = (value: number | null | undefined): string => {
189
- if (value == null || !isFinite(value)) {
190
- return "";
191
- }
192
- const date = new Date(0);
193
- date.setUTCMilliseconds(value - getMachineOffsetMillis() + getUserOffsetMillis());
194
- switch (getLocale()) {
195
- case enUS: {
196
- return format(date, "MM/dd/yyyy HH:mm", { locale: getLocale() });
197
- }
198
- default: {
199
- return format(date, "dd/MM/yyyy HH:mm", { locale: getLocale() });
200
- }
201
- }
202
- };
203
-
204
- const todayTimeFormat = (): string => {
205
- return `'${useTranslationsProvider().$tr("ui.time-zone.today-at", "Today at").replace(/'/g, "''")}' HH:mm:ss`;
206
- };
207
-
208
- const yesterdayTimeFormat = (): string => {
209
- return `'${useTranslationsProvider().$tr("ui.time-zone.yesterday-at", "Yesterday at").replace(/'/g, "''")}' HH:mm:ss`;
210
- };
211
-
212
- const overrideFormat = (date: Date, askedFormat: string): string => {
213
- const now = new Date();
214
- if (date.toDateString() === now.toDateString()) {
215
- return todayTimeFormat();
216
- }
217
- if (date.toDateString() === subDays(now, 1).toDateString()) {
218
- return yesterdayTimeFormat();
219
- }
220
- return askedFormat;
120
+ const todayToPicker = (): string => {
121
+ const date = addMilliseconds(new Date(), -getOffsetMachine());
122
+ date.setSeconds(0, 0);
123
+ return format(date, ISO_FORMAT);
221
124
  };
222
125
 
223
- const getLocale = (): Locale => {
224
- switch (useAppLanguageCode().languageCode.value) {
225
- case "fr-FR": return fr;
226
- case "es-ES": return es;
227
- case "it-IT": return it;
228
- case "en-GB": return enGB;
229
- case "de-DE": return de;
230
- default: return enUS;
231
- }
126
+ const yesterdayToPicker = (): string => {
127
+ const date = addMilliseconds(subDays(new Date(), 1), -getOffsetMachine());
128
+ date.setSeconds(0, 0);
129
+ return format(date, ISO_FORMAT);
232
130
  };
233
131
 
234
- const parseForPicker = (value: string, dateFormat: string = isoTimeFormat()): number | null => {
235
- let date = parse(value!, dateFormat, new Date());
236
- date = addMilliseconds(date, userOffset());
132
+ const parseForPicker = (value: string, dateFormat: string = ISO_FORMAT): number | null => {
133
+ const date = addMilliseconds(parse(value, dateFormat, new Date()), getOffsetUser());
237
134
  if (!isFinite(date.getTime())) {
238
135
  return null;
239
136
  }
240
137
  return date.getTime();
241
138
  };
242
139
 
243
- const formatCurrentForPicker = (daysOffset: number = -1): string => {
244
- let date = new Date();
245
- date.setSeconds(0, 0);
246
- date = addMilliseconds(addDays(date, daysOffset), -machineOffset());
247
- return format(date, isoTimeFormat());
248
- };
249
-
250
140
  const formatFromPicker = (date: number | null): string => {
251
141
  if (date != null) {
252
- const epoch = date - machineOffset() + (machineOffset() - userOffset());
253
- return format(epoch, isoTimeFormat());
142
+ return format(date - getOffsetMachine(), ISO_FORMAT);
254
143
  }
255
144
  return "";
256
145
  };
@@ -259,7 +148,7 @@ export const useAppTimeZone = () => {
259
148
  if (epoch == null || !isFinite(epoch)) {
260
149
  return "";
261
150
  }
262
- return format(epoch - machineOffset(), isoTimeFormat());
151
+ return format(epoch, ISO_FORMAT);
263
152
  };
264
153
 
265
154
  const ready = computed(() => timeZone.value !== null);
@@ -268,10 +157,6 @@ export const useAppTimeZone = () => {
268
157
  ready,
269
158
  timeZone,
270
159
  setAppTimeZone,
271
- getUserOffset,
272
- getMachineOffset,
273
- getUserOffsetMillis,
274
- getMachineOffsetMillis,
275
160
  todayToEpoch,
276
161
  pickerToEpoch,
277
162
  epochToPicker,
@@ -282,8 +167,12 @@ export const useAppTimeZone = () => {
282
167
  epochToShortTimeFormat,
283
168
  epochToTimeOnlyFormat,
284
169
  parseForPicker,
285
- formatCurrentForPicker,
170
+ todayToPicker,
171
+ yesterdayToPicker,
286
172
  formatFromPicker,
287
- formatEpochToVariable
173
+ formatEpochToVariable,
174
+ getOffsetUser,
175
+ getOffsetMachine,
176
+ getOffsetDifference
288
177
  };
289
178
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dative-gpi/foundation-shared-services",
3
3
  "sideEffects": false,
4
- "version": "1.0.7",
4
+ "version": "1.0.9",
5
5
  "description": "",
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -10,7 +10,7 @@
10
10
  "author": "",
11
11
  "license": "ISC",
12
12
  "dependencies": {
13
- "@dative-gpi/foundation-shared-domain": "1.0.7"
13
+ "@dative-gpi/foundation-shared-domain": "1.0.9"
14
14
  },
15
15
  "peerDependencies": {
16
16
  "@dative-gpi/bones-ui": "^0.0.75",
@@ -18,5 +18,5 @@
18
18
  "vue": "^3.4.29",
19
19
  "vue-router": "^4.3.0"
20
20
  },
21
- "gitHead": "d0380d86664f9d28f757a4f2c0d06bf5cd9ca5e9"
21
+ "gitHead": "018a67489fc022344c90d45b02bfabdcd0dcefec"
22
22
  }