@contentful/field-editor-date 2.0.8 → 2.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.
- package/dist/cjs/utils/data.spec.js +333 -0
- package/dist/esm/utils/data.spec.js +334 -1
- package/package.json +4 -4
|
@@ -52,5 +52,338 @@ describe('date utils', ()=>{
|
|
|
52
52
|
valid: '2015-01-14T17:00-05:00'
|
|
53
53
|
});
|
|
54
54
|
});
|
|
55
|
+
it('returns date-only format when usesTime and usesTimezone are false', ()=>{
|
|
56
|
+
expect((0, _date.buildFieldValue)({
|
|
57
|
+
data: {
|
|
58
|
+
date: (0, _moment.default)('2020-06-15'),
|
|
59
|
+
time: '10:30',
|
|
60
|
+
ampm: 'AM',
|
|
61
|
+
utcOffset: '+00:00'
|
|
62
|
+
},
|
|
63
|
+
usesTimezone: false,
|
|
64
|
+
usesTime: false
|
|
65
|
+
})).toEqual({
|
|
66
|
+
invalid: false,
|
|
67
|
+
valid: '2020-06-15'
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
it('returns datetime without timezone when usesTime=true, usesTimezone=false', ()=>{
|
|
71
|
+
expect((0, _date.buildFieldValue)({
|
|
72
|
+
data: {
|
|
73
|
+
date: (0, _moment.default)('2020-06-15'),
|
|
74
|
+
time: '14:30',
|
|
75
|
+
ampm: 'PM',
|
|
76
|
+
utcOffset: '+00:00'
|
|
77
|
+
},
|
|
78
|
+
usesTimezone: false,
|
|
79
|
+
usesTime: true
|
|
80
|
+
})).toEqual({
|
|
81
|
+
invalid: false,
|
|
82
|
+
valid: '2020-06-15T14:30'
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
it('returns valid: null when no date is provided', ()=>{
|
|
86
|
+
expect((0, _date.buildFieldValue)({
|
|
87
|
+
data: {
|
|
88
|
+
time: '10:00',
|
|
89
|
+
ampm: 'AM',
|
|
90
|
+
utcOffset: '+00:00'
|
|
91
|
+
},
|
|
92
|
+
usesTimezone: true,
|
|
93
|
+
usesTime: true
|
|
94
|
+
})).toEqual({
|
|
95
|
+
invalid: false,
|
|
96
|
+
valid: null
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
it('handles midnight (12:00 AM) correctly', ()=>{
|
|
100
|
+
expect((0, _date.buildFieldValue)({
|
|
101
|
+
data: {
|
|
102
|
+
date: (0, _moment.default)('2021-03-01'),
|
|
103
|
+
time: '12:00',
|
|
104
|
+
ampm: 'AM',
|
|
105
|
+
utcOffset: '+00:00'
|
|
106
|
+
},
|
|
107
|
+
usesTimezone: true,
|
|
108
|
+
usesTime: true
|
|
109
|
+
})).toEqual({
|
|
110
|
+
invalid: false,
|
|
111
|
+
valid: '2021-03-01T00:00+00:00'
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
it('handles noon (12:00 PM) correctly', ()=>{
|
|
115
|
+
expect((0, _date.buildFieldValue)({
|
|
116
|
+
data: {
|
|
117
|
+
date: (0, _moment.default)('2021-03-01'),
|
|
118
|
+
time: '12:00',
|
|
119
|
+
ampm: 'PM',
|
|
120
|
+
utcOffset: '+00:00'
|
|
121
|
+
},
|
|
122
|
+
usesTimezone: true,
|
|
123
|
+
usesTime: true
|
|
124
|
+
})).toEqual({
|
|
125
|
+
invalid: false,
|
|
126
|
+
valid: '2021-03-01T12:00+00:00'
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
it('preserves half-hour offset +05:30 (India)', ()=>{
|
|
130
|
+
expect((0, _date.buildFieldValue)({
|
|
131
|
+
data: {
|
|
132
|
+
date: (0, _moment.default)('2023-08-15'),
|
|
133
|
+
time: '10:00',
|
|
134
|
+
ampm: 'AM',
|
|
135
|
+
utcOffset: '+05:30'
|
|
136
|
+
},
|
|
137
|
+
usesTimezone: true,
|
|
138
|
+
usesTime: true
|
|
139
|
+
})).toEqual({
|
|
140
|
+
invalid: false,
|
|
141
|
+
valid: '2023-08-15T10:00+05:30'
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
it('preserves negative half-hour offset -09:30', ()=>{
|
|
145
|
+
expect((0, _date.buildFieldValue)({
|
|
146
|
+
data: {
|
|
147
|
+
date: (0, _moment.default)('2023-08-15'),
|
|
148
|
+
time: '03:30',
|
|
149
|
+
ampm: 'AM',
|
|
150
|
+
utcOffset: '-09:30'
|
|
151
|
+
},
|
|
152
|
+
usesTimezone: true,
|
|
153
|
+
usesTime: true
|
|
154
|
+
})).toEqual({
|
|
155
|
+
invalid: false,
|
|
156
|
+
valid: '2023-08-15T03:30-09:30'
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
it('preserves quarter-hour offset +05:45 (Nepal)', ()=>{
|
|
160
|
+
expect((0, _date.buildFieldValue)({
|
|
161
|
+
data: {
|
|
162
|
+
date: (0, _moment.default)('2023-08-15'),
|
|
163
|
+
time: '05:45',
|
|
164
|
+
ampm: 'AM',
|
|
165
|
+
utcOffset: '+05:45'
|
|
166
|
+
},
|
|
167
|
+
usesTimezone: true,
|
|
168
|
+
usesTime: true
|
|
169
|
+
})).toEqual({
|
|
170
|
+
invalid: false,
|
|
171
|
+
valid: '2023-08-15T05:45+05:45'
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
it('preserves UTC +00:00 offset', ()=>{
|
|
175
|
+
expect((0, _date.buildFieldValue)({
|
|
176
|
+
data: {
|
|
177
|
+
date: (0, _moment.default)('2023-01-01'),
|
|
178
|
+
time: '00:00',
|
|
179
|
+
ampm: 'AM',
|
|
180
|
+
utcOffset: '+00:00'
|
|
181
|
+
},
|
|
182
|
+
usesTimezone: true,
|
|
183
|
+
usesTime: true
|
|
184
|
+
})).toEqual({
|
|
185
|
+
invalid: false,
|
|
186
|
+
valid: '2023-01-01T00:00+00:00'
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
it('preserves far-west offset -12:00', ()=>{
|
|
190
|
+
expect((0, _date.buildFieldValue)({
|
|
191
|
+
data: {
|
|
192
|
+
date: (0, _moment.default)('2023-01-01'),
|
|
193
|
+
time: '23:59',
|
|
194
|
+
ampm: 'PM',
|
|
195
|
+
utcOffset: '-12:00'
|
|
196
|
+
},
|
|
197
|
+
usesTimezone: true,
|
|
198
|
+
usesTime: true
|
|
199
|
+
})).toEqual({
|
|
200
|
+
invalid: false,
|
|
201
|
+
valid: '2023-01-01T23:59-12:00'
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
it('preserves far-east offset +14:00', ()=>{
|
|
205
|
+
expect((0, _date.buildFieldValue)({
|
|
206
|
+
data: {
|
|
207
|
+
date: (0, _moment.default)('2023-01-01'),
|
|
208
|
+
time: '01:00',
|
|
209
|
+
ampm: 'AM',
|
|
210
|
+
utcOffset: '+14:00'
|
|
211
|
+
},
|
|
212
|
+
usesTimezone: true,
|
|
213
|
+
usesTime: true
|
|
214
|
+
})).toEqual({
|
|
215
|
+
invalid: false,
|
|
216
|
+
valid: '2023-01-01T01:00+14:00'
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
it('11:59 PM → 23:59', ()=>{
|
|
220
|
+
expect((0, _date.buildFieldValue)({
|
|
221
|
+
data: {
|
|
222
|
+
date: (0, _moment.default)('2023-06-01'),
|
|
223
|
+
time: '11:59',
|
|
224
|
+
ampm: 'PM',
|
|
225
|
+
utcOffset: '+00:00'
|
|
226
|
+
},
|
|
227
|
+
usesTimezone: true,
|
|
228
|
+
usesTime: true
|
|
229
|
+
})).toEqual({
|
|
230
|
+
invalid: false,
|
|
231
|
+
valid: '2023-06-01T23:59+00:00'
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
it('01:00 AM → 01:00 (no shift)', ()=>{
|
|
235
|
+
expect((0, _date.buildFieldValue)({
|
|
236
|
+
data: {
|
|
237
|
+
date: (0, _moment.default)('2023-06-01'),
|
|
238
|
+
time: '01:00',
|
|
239
|
+
ampm: 'AM',
|
|
240
|
+
utcOffset: '+00:00'
|
|
241
|
+
},
|
|
242
|
+
usesTimezone: true,
|
|
243
|
+
usesTime: true
|
|
244
|
+
})).toEqual({
|
|
245
|
+
invalid: false,
|
|
246
|
+
valid: '2023-06-01T01:00+00:00'
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
describe('userInputFromDatetime', ()=>{
|
|
251
|
+
it('parses a full ISO datetime string with timezone', ()=>{
|
|
252
|
+
const result = (0, _date.userInputFromDatetime)({
|
|
253
|
+
value: '2018-02-02T17:00+03:00',
|
|
254
|
+
uses12hClock: false
|
|
255
|
+
});
|
|
256
|
+
expect(result.time).toBe('17:00');
|
|
257
|
+
expect(result.ampm).toBe('PM');
|
|
258
|
+
expect(result.utcOffset).toBe('+03:00');
|
|
259
|
+
});
|
|
260
|
+
it('parses a full ISO datetime string with 12h clock', ()=>{
|
|
261
|
+
const result = (0, _date.userInputFromDatetime)({
|
|
262
|
+
value: '2018-02-02T05:00+03:00',
|
|
263
|
+
uses12hClock: true
|
|
264
|
+
});
|
|
265
|
+
expect(result.time).toBe('05:00');
|
|
266
|
+
expect(result.ampm).toBe('AM');
|
|
267
|
+
expect(result.utcOffset).toBe('+03:00');
|
|
268
|
+
});
|
|
269
|
+
it('returns defaults when value is null', ()=>{
|
|
270
|
+
const result = (0, _date.userInputFromDatetime)({
|
|
271
|
+
value: null,
|
|
272
|
+
uses12hClock: false
|
|
273
|
+
});
|
|
274
|
+
expect(result.date).toBeUndefined();
|
|
275
|
+
expect(result.ampm).toBe((0, _date.getDefaultAMPM)());
|
|
276
|
+
expect(result.utcOffset).toBe((0, _date.getDefaultUtcOffset)());
|
|
277
|
+
});
|
|
278
|
+
it('returns defaults when value is undefined', ()=>{
|
|
279
|
+
const result = (0, _date.userInputFromDatetime)({
|
|
280
|
+
value: undefined,
|
|
281
|
+
uses12hClock: false
|
|
282
|
+
});
|
|
283
|
+
expect(result.date).toBeUndefined();
|
|
284
|
+
expect(result.ampm).toBe((0, _date.getDefaultAMPM)());
|
|
285
|
+
});
|
|
286
|
+
it('returns defaults when value is empty string', ()=>{
|
|
287
|
+
const result = (0, _date.userInputFromDatetime)({
|
|
288
|
+
value: '',
|
|
289
|
+
uses12hClock: false
|
|
290
|
+
});
|
|
291
|
+
expect(result.date).toBeUndefined();
|
|
292
|
+
});
|
|
293
|
+
it('parses a date-only string — utcOffset is the local system offset', ()=>{
|
|
294
|
+
const result = (0, _date.userInputFromDatetime)({
|
|
295
|
+
value: '2022-09-16',
|
|
296
|
+
uses12hClock: false
|
|
297
|
+
});
|
|
298
|
+
expect(result.utcOffset).toMatch(/^[+-]\d{2}:\d{2}$/);
|
|
299
|
+
});
|
|
300
|
+
it('preserves raw time and does not shift by system timezone (positive offset)', ()=>{
|
|
301
|
+
const result = (0, _date.userInputFromDatetime)({
|
|
302
|
+
value: '2020-03-15T14:00+05:30',
|
|
303
|
+
uses12hClock: false
|
|
304
|
+
});
|
|
305
|
+
expect(result.time).toBe('14:00');
|
|
306
|
+
expect(result.ampm).toBe('PM');
|
|
307
|
+
expect(result.utcOffset).toBe('+05:30');
|
|
308
|
+
});
|
|
309
|
+
it('preserves raw time and does not shift by system timezone (negative offset)', ()=>{
|
|
310
|
+
const result = (0, _date.userInputFromDatetime)({
|
|
311
|
+
value: '2020-03-15T08:30-05:30',
|
|
312
|
+
uses12hClock: false
|
|
313
|
+
});
|
|
314
|
+
expect(result.time).toBe('08:30');
|
|
315
|
+
expect(result.ampm).toBe('AM');
|
|
316
|
+
expect(result.utcOffset).toBe('-05:30');
|
|
317
|
+
});
|
|
318
|
+
it('handles UTC "Z" suffix — moment normalizes offset to +00:00', ()=>{
|
|
319
|
+
const result = (0, _date.userInputFromDatetime)({
|
|
320
|
+
value: '2021-06-01T12:00Z',
|
|
321
|
+
uses12hClock: false
|
|
322
|
+
});
|
|
323
|
+
expect(result.time).toBe('12:00');
|
|
324
|
+
expect(result.ampm).toBe('PM');
|
|
325
|
+
expect(result.utcOffset).toBe('+00:00');
|
|
326
|
+
});
|
|
327
|
+
it('handles midnight UTC correctly', ()=>{
|
|
328
|
+
const result = (0, _date.userInputFromDatetime)({
|
|
329
|
+
value: '2021-06-01T00:00Z',
|
|
330
|
+
uses12hClock: false
|
|
331
|
+
});
|
|
332
|
+
expect(result.time).toBe('00:00');
|
|
333
|
+
expect(result.ampm).toBe('AM');
|
|
334
|
+
});
|
|
335
|
+
it('converts PM hour to 12h display (17:00 → 05:00 PM)', ()=>{
|
|
336
|
+
const result = (0, _date.userInputFromDatetime)({
|
|
337
|
+
value: '2018-02-02T17:00+03:00',
|
|
338
|
+
uses12hClock: true
|
|
339
|
+
});
|
|
340
|
+
expect(result.time).toBe('05:00');
|
|
341
|
+
expect(result.ampm).toBe('PM');
|
|
342
|
+
});
|
|
343
|
+
it('converts noon to 12h display (12:00 → 12:00 PM)', ()=>{
|
|
344
|
+
const result = (0, _date.userInputFromDatetime)({
|
|
345
|
+
value: '2021-03-01T12:00+00:00',
|
|
346
|
+
uses12hClock: true
|
|
347
|
+
});
|
|
348
|
+
expect(result.time).toBe('12:00');
|
|
349
|
+
expect(result.ampm).toBe('PM');
|
|
350
|
+
});
|
|
351
|
+
it('converts midnight to 12h display (00:00 → 12:00 AM)', ()=>{
|
|
352
|
+
const result = (0, _date.userInputFromDatetime)({
|
|
353
|
+
value: '2021-03-01T00:00+00:00',
|
|
354
|
+
uses12hClock: true
|
|
355
|
+
});
|
|
356
|
+
expect(result.time).toBe('12:00');
|
|
357
|
+
expect(result.ampm).toBe('AM');
|
|
358
|
+
});
|
|
359
|
+
it('handles quarter-hour offset +05:45 (Nepal)', ()=>{
|
|
360
|
+
const result = (0, _date.userInputFromDatetime)({
|
|
361
|
+
value: '2023-07-20T09:45+05:45',
|
|
362
|
+
uses12hClock: false
|
|
363
|
+
});
|
|
364
|
+
expect(result.time).toBe('09:45');
|
|
365
|
+
expect(result.utcOffset).toBe('+05:45');
|
|
366
|
+
});
|
|
367
|
+
it('handles -12:00 (far-west) offset without date shift', ()=>{
|
|
368
|
+
const result = (0, _date.userInputFromDatetime)({
|
|
369
|
+
value: '2023-01-01T23:59-12:00',
|
|
370
|
+
uses12hClock: false
|
|
371
|
+
});
|
|
372
|
+
expect(result.time).toBe('23:59');
|
|
373
|
+
expect(result.utcOffset).toBe('-12:00');
|
|
374
|
+
});
|
|
375
|
+
it('handles +14:00 (far-east) offset without date shift', ()=>{
|
|
376
|
+
const result = (0, _date.userInputFromDatetime)({
|
|
377
|
+
value: '2023-01-01T01:00+14:00',
|
|
378
|
+
uses12hClock: false
|
|
379
|
+
});
|
|
380
|
+
expect(result.time).toBe('01:00');
|
|
381
|
+
expect(result.utcOffset).toBe('+14:00');
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
describe('getDefaultAMPM', ()=>{
|
|
385
|
+
it('returns AM', ()=>{
|
|
386
|
+
expect((0, _date.getDefaultAMPM)()).toBe('AM');
|
|
387
|
+
});
|
|
55
388
|
});
|
|
56
389
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import moment from 'moment';
|
|
2
|
-
import { buildFieldValue } from './date';
|
|
2
|
+
import { buildFieldValue, userInputFromDatetime, getDefaultAMPM, getDefaultUtcOffset } from './date';
|
|
3
3
|
describe('date utils', ()=>{
|
|
4
4
|
describe('buildFieldValue', ()=>{
|
|
5
5
|
it('should work properly', ()=>{
|
|
@@ -43,5 +43,338 @@ describe('date utils', ()=>{
|
|
|
43
43
|
valid: '2015-01-14T17:00-05:00'
|
|
44
44
|
});
|
|
45
45
|
});
|
|
46
|
+
it('returns date-only format when usesTime and usesTimezone are false', ()=>{
|
|
47
|
+
expect(buildFieldValue({
|
|
48
|
+
data: {
|
|
49
|
+
date: moment('2020-06-15'),
|
|
50
|
+
time: '10:30',
|
|
51
|
+
ampm: 'AM',
|
|
52
|
+
utcOffset: '+00:00'
|
|
53
|
+
},
|
|
54
|
+
usesTimezone: false,
|
|
55
|
+
usesTime: false
|
|
56
|
+
})).toEqual({
|
|
57
|
+
invalid: false,
|
|
58
|
+
valid: '2020-06-15'
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
it('returns datetime without timezone when usesTime=true, usesTimezone=false', ()=>{
|
|
62
|
+
expect(buildFieldValue({
|
|
63
|
+
data: {
|
|
64
|
+
date: moment('2020-06-15'),
|
|
65
|
+
time: '14:30',
|
|
66
|
+
ampm: 'PM',
|
|
67
|
+
utcOffset: '+00:00'
|
|
68
|
+
},
|
|
69
|
+
usesTimezone: false,
|
|
70
|
+
usesTime: true
|
|
71
|
+
})).toEqual({
|
|
72
|
+
invalid: false,
|
|
73
|
+
valid: '2020-06-15T14:30'
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
it('returns valid: null when no date is provided', ()=>{
|
|
77
|
+
expect(buildFieldValue({
|
|
78
|
+
data: {
|
|
79
|
+
time: '10:00',
|
|
80
|
+
ampm: 'AM',
|
|
81
|
+
utcOffset: '+00:00'
|
|
82
|
+
},
|
|
83
|
+
usesTimezone: true,
|
|
84
|
+
usesTime: true
|
|
85
|
+
})).toEqual({
|
|
86
|
+
invalid: false,
|
|
87
|
+
valid: null
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
it('handles midnight (12:00 AM) correctly', ()=>{
|
|
91
|
+
expect(buildFieldValue({
|
|
92
|
+
data: {
|
|
93
|
+
date: moment('2021-03-01'),
|
|
94
|
+
time: '12:00',
|
|
95
|
+
ampm: 'AM',
|
|
96
|
+
utcOffset: '+00:00'
|
|
97
|
+
},
|
|
98
|
+
usesTimezone: true,
|
|
99
|
+
usesTime: true
|
|
100
|
+
})).toEqual({
|
|
101
|
+
invalid: false,
|
|
102
|
+
valid: '2021-03-01T00:00+00:00'
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
it('handles noon (12:00 PM) correctly', ()=>{
|
|
106
|
+
expect(buildFieldValue({
|
|
107
|
+
data: {
|
|
108
|
+
date: moment('2021-03-01'),
|
|
109
|
+
time: '12:00',
|
|
110
|
+
ampm: 'PM',
|
|
111
|
+
utcOffset: '+00:00'
|
|
112
|
+
},
|
|
113
|
+
usesTimezone: true,
|
|
114
|
+
usesTime: true
|
|
115
|
+
})).toEqual({
|
|
116
|
+
invalid: false,
|
|
117
|
+
valid: '2021-03-01T12:00+00:00'
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
it('preserves half-hour offset +05:30 (India)', ()=>{
|
|
121
|
+
expect(buildFieldValue({
|
|
122
|
+
data: {
|
|
123
|
+
date: moment('2023-08-15'),
|
|
124
|
+
time: '10:00',
|
|
125
|
+
ampm: 'AM',
|
|
126
|
+
utcOffset: '+05:30'
|
|
127
|
+
},
|
|
128
|
+
usesTimezone: true,
|
|
129
|
+
usesTime: true
|
|
130
|
+
})).toEqual({
|
|
131
|
+
invalid: false,
|
|
132
|
+
valid: '2023-08-15T10:00+05:30'
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
it('preserves negative half-hour offset -09:30', ()=>{
|
|
136
|
+
expect(buildFieldValue({
|
|
137
|
+
data: {
|
|
138
|
+
date: moment('2023-08-15'),
|
|
139
|
+
time: '03:30',
|
|
140
|
+
ampm: 'AM',
|
|
141
|
+
utcOffset: '-09:30'
|
|
142
|
+
},
|
|
143
|
+
usesTimezone: true,
|
|
144
|
+
usesTime: true
|
|
145
|
+
})).toEqual({
|
|
146
|
+
invalid: false,
|
|
147
|
+
valid: '2023-08-15T03:30-09:30'
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
it('preserves quarter-hour offset +05:45 (Nepal)', ()=>{
|
|
151
|
+
expect(buildFieldValue({
|
|
152
|
+
data: {
|
|
153
|
+
date: moment('2023-08-15'),
|
|
154
|
+
time: '05:45',
|
|
155
|
+
ampm: 'AM',
|
|
156
|
+
utcOffset: '+05:45'
|
|
157
|
+
},
|
|
158
|
+
usesTimezone: true,
|
|
159
|
+
usesTime: true
|
|
160
|
+
})).toEqual({
|
|
161
|
+
invalid: false,
|
|
162
|
+
valid: '2023-08-15T05:45+05:45'
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
it('preserves UTC +00:00 offset', ()=>{
|
|
166
|
+
expect(buildFieldValue({
|
|
167
|
+
data: {
|
|
168
|
+
date: moment('2023-01-01'),
|
|
169
|
+
time: '00:00',
|
|
170
|
+
ampm: 'AM',
|
|
171
|
+
utcOffset: '+00:00'
|
|
172
|
+
},
|
|
173
|
+
usesTimezone: true,
|
|
174
|
+
usesTime: true
|
|
175
|
+
})).toEqual({
|
|
176
|
+
invalid: false,
|
|
177
|
+
valid: '2023-01-01T00:00+00:00'
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
it('preserves far-west offset -12:00', ()=>{
|
|
181
|
+
expect(buildFieldValue({
|
|
182
|
+
data: {
|
|
183
|
+
date: moment('2023-01-01'),
|
|
184
|
+
time: '23:59',
|
|
185
|
+
ampm: 'PM',
|
|
186
|
+
utcOffset: '-12:00'
|
|
187
|
+
},
|
|
188
|
+
usesTimezone: true,
|
|
189
|
+
usesTime: true
|
|
190
|
+
})).toEqual({
|
|
191
|
+
invalid: false,
|
|
192
|
+
valid: '2023-01-01T23:59-12:00'
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
it('preserves far-east offset +14:00', ()=>{
|
|
196
|
+
expect(buildFieldValue({
|
|
197
|
+
data: {
|
|
198
|
+
date: moment('2023-01-01'),
|
|
199
|
+
time: '01:00',
|
|
200
|
+
ampm: 'AM',
|
|
201
|
+
utcOffset: '+14:00'
|
|
202
|
+
},
|
|
203
|
+
usesTimezone: true,
|
|
204
|
+
usesTime: true
|
|
205
|
+
})).toEqual({
|
|
206
|
+
invalid: false,
|
|
207
|
+
valid: '2023-01-01T01:00+14:00'
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
it('11:59 PM → 23:59', ()=>{
|
|
211
|
+
expect(buildFieldValue({
|
|
212
|
+
data: {
|
|
213
|
+
date: moment('2023-06-01'),
|
|
214
|
+
time: '11:59',
|
|
215
|
+
ampm: 'PM',
|
|
216
|
+
utcOffset: '+00:00'
|
|
217
|
+
},
|
|
218
|
+
usesTimezone: true,
|
|
219
|
+
usesTime: true
|
|
220
|
+
})).toEqual({
|
|
221
|
+
invalid: false,
|
|
222
|
+
valid: '2023-06-01T23:59+00:00'
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
it('01:00 AM → 01:00 (no shift)', ()=>{
|
|
226
|
+
expect(buildFieldValue({
|
|
227
|
+
data: {
|
|
228
|
+
date: moment('2023-06-01'),
|
|
229
|
+
time: '01:00',
|
|
230
|
+
ampm: 'AM',
|
|
231
|
+
utcOffset: '+00:00'
|
|
232
|
+
},
|
|
233
|
+
usesTimezone: true,
|
|
234
|
+
usesTime: true
|
|
235
|
+
})).toEqual({
|
|
236
|
+
invalid: false,
|
|
237
|
+
valid: '2023-06-01T01:00+00:00'
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
describe('userInputFromDatetime', ()=>{
|
|
242
|
+
it('parses a full ISO datetime string with timezone', ()=>{
|
|
243
|
+
const result = userInputFromDatetime({
|
|
244
|
+
value: '2018-02-02T17:00+03:00',
|
|
245
|
+
uses12hClock: false
|
|
246
|
+
});
|
|
247
|
+
expect(result.time).toBe('17:00');
|
|
248
|
+
expect(result.ampm).toBe('PM');
|
|
249
|
+
expect(result.utcOffset).toBe('+03:00');
|
|
250
|
+
});
|
|
251
|
+
it('parses a full ISO datetime string with 12h clock', ()=>{
|
|
252
|
+
const result = userInputFromDatetime({
|
|
253
|
+
value: '2018-02-02T05:00+03:00',
|
|
254
|
+
uses12hClock: true
|
|
255
|
+
});
|
|
256
|
+
expect(result.time).toBe('05:00');
|
|
257
|
+
expect(result.ampm).toBe('AM');
|
|
258
|
+
expect(result.utcOffset).toBe('+03:00');
|
|
259
|
+
});
|
|
260
|
+
it('returns defaults when value is null', ()=>{
|
|
261
|
+
const result = userInputFromDatetime({
|
|
262
|
+
value: null,
|
|
263
|
+
uses12hClock: false
|
|
264
|
+
});
|
|
265
|
+
expect(result.date).toBeUndefined();
|
|
266
|
+
expect(result.ampm).toBe(getDefaultAMPM());
|
|
267
|
+
expect(result.utcOffset).toBe(getDefaultUtcOffset());
|
|
268
|
+
});
|
|
269
|
+
it('returns defaults when value is undefined', ()=>{
|
|
270
|
+
const result = userInputFromDatetime({
|
|
271
|
+
value: undefined,
|
|
272
|
+
uses12hClock: false
|
|
273
|
+
});
|
|
274
|
+
expect(result.date).toBeUndefined();
|
|
275
|
+
expect(result.ampm).toBe(getDefaultAMPM());
|
|
276
|
+
});
|
|
277
|
+
it('returns defaults when value is empty string', ()=>{
|
|
278
|
+
const result = userInputFromDatetime({
|
|
279
|
+
value: '',
|
|
280
|
+
uses12hClock: false
|
|
281
|
+
});
|
|
282
|
+
expect(result.date).toBeUndefined();
|
|
283
|
+
});
|
|
284
|
+
it('parses a date-only string — utcOffset is the local system offset', ()=>{
|
|
285
|
+
const result = userInputFromDatetime({
|
|
286
|
+
value: '2022-09-16',
|
|
287
|
+
uses12hClock: false
|
|
288
|
+
});
|
|
289
|
+
expect(result.utcOffset).toMatch(/^[+-]\d{2}:\d{2}$/);
|
|
290
|
+
});
|
|
291
|
+
it('preserves raw time and does not shift by system timezone (positive offset)', ()=>{
|
|
292
|
+
const result = userInputFromDatetime({
|
|
293
|
+
value: '2020-03-15T14:00+05:30',
|
|
294
|
+
uses12hClock: false
|
|
295
|
+
});
|
|
296
|
+
expect(result.time).toBe('14:00');
|
|
297
|
+
expect(result.ampm).toBe('PM');
|
|
298
|
+
expect(result.utcOffset).toBe('+05:30');
|
|
299
|
+
});
|
|
300
|
+
it('preserves raw time and does not shift by system timezone (negative offset)', ()=>{
|
|
301
|
+
const result = userInputFromDatetime({
|
|
302
|
+
value: '2020-03-15T08:30-05:30',
|
|
303
|
+
uses12hClock: false
|
|
304
|
+
});
|
|
305
|
+
expect(result.time).toBe('08:30');
|
|
306
|
+
expect(result.ampm).toBe('AM');
|
|
307
|
+
expect(result.utcOffset).toBe('-05:30');
|
|
308
|
+
});
|
|
309
|
+
it('handles UTC "Z" suffix — moment normalizes offset to +00:00', ()=>{
|
|
310
|
+
const result = userInputFromDatetime({
|
|
311
|
+
value: '2021-06-01T12:00Z',
|
|
312
|
+
uses12hClock: false
|
|
313
|
+
});
|
|
314
|
+
expect(result.time).toBe('12:00');
|
|
315
|
+
expect(result.ampm).toBe('PM');
|
|
316
|
+
expect(result.utcOffset).toBe('+00:00');
|
|
317
|
+
});
|
|
318
|
+
it('handles midnight UTC correctly', ()=>{
|
|
319
|
+
const result = userInputFromDatetime({
|
|
320
|
+
value: '2021-06-01T00:00Z',
|
|
321
|
+
uses12hClock: false
|
|
322
|
+
});
|
|
323
|
+
expect(result.time).toBe('00:00');
|
|
324
|
+
expect(result.ampm).toBe('AM');
|
|
325
|
+
});
|
|
326
|
+
it('converts PM hour to 12h display (17:00 → 05:00 PM)', ()=>{
|
|
327
|
+
const result = userInputFromDatetime({
|
|
328
|
+
value: '2018-02-02T17:00+03:00',
|
|
329
|
+
uses12hClock: true
|
|
330
|
+
});
|
|
331
|
+
expect(result.time).toBe('05:00');
|
|
332
|
+
expect(result.ampm).toBe('PM');
|
|
333
|
+
});
|
|
334
|
+
it('converts noon to 12h display (12:00 → 12:00 PM)', ()=>{
|
|
335
|
+
const result = userInputFromDatetime({
|
|
336
|
+
value: '2021-03-01T12:00+00:00',
|
|
337
|
+
uses12hClock: true
|
|
338
|
+
});
|
|
339
|
+
expect(result.time).toBe('12:00');
|
|
340
|
+
expect(result.ampm).toBe('PM');
|
|
341
|
+
});
|
|
342
|
+
it('converts midnight to 12h display (00:00 → 12:00 AM)', ()=>{
|
|
343
|
+
const result = userInputFromDatetime({
|
|
344
|
+
value: '2021-03-01T00:00+00:00',
|
|
345
|
+
uses12hClock: true
|
|
346
|
+
});
|
|
347
|
+
expect(result.time).toBe('12:00');
|
|
348
|
+
expect(result.ampm).toBe('AM');
|
|
349
|
+
});
|
|
350
|
+
it('handles quarter-hour offset +05:45 (Nepal)', ()=>{
|
|
351
|
+
const result = userInputFromDatetime({
|
|
352
|
+
value: '2023-07-20T09:45+05:45',
|
|
353
|
+
uses12hClock: false
|
|
354
|
+
});
|
|
355
|
+
expect(result.time).toBe('09:45');
|
|
356
|
+
expect(result.utcOffset).toBe('+05:45');
|
|
357
|
+
});
|
|
358
|
+
it('handles -12:00 (far-west) offset without date shift', ()=>{
|
|
359
|
+
const result = userInputFromDatetime({
|
|
360
|
+
value: '2023-01-01T23:59-12:00',
|
|
361
|
+
uses12hClock: false
|
|
362
|
+
});
|
|
363
|
+
expect(result.time).toBe('23:59');
|
|
364
|
+
expect(result.utcOffset).toBe('-12:00');
|
|
365
|
+
});
|
|
366
|
+
it('handles +14:00 (far-east) offset without date shift', ()=>{
|
|
367
|
+
const result = userInputFromDatetime({
|
|
368
|
+
value: '2023-01-01T01:00+14:00',
|
|
369
|
+
uses12hClock: false
|
|
370
|
+
});
|
|
371
|
+
expect(result.time).toBe('01:00');
|
|
372
|
+
expect(result.utcOffset).toBe('+14:00');
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
describe('getDefaultAMPM', ()=>{
|
|
376
|
+
it('returns AM', ()=>{
|
|
377
|
+
expect(getDefaultAMPM()).toBe('AM');
|
|
378
|
+
});
|
|
46
379
|
});
|
|
47
380
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/field-editor-date",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.9",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/esm/index.js",
|
|
6
6
|
"types": "dist/types/index.d.ts",
|
|
@@ -39,13 +39,13 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@contentful/f36-components": "^6.7.1",
|
|
41
41
|
"@contentful/f36-tokens": "^6.1.2",
|
|
42
|
-
"@contentful/field-editor-shared": "^
|
|
42
|
+
"@contentful/field-editor-shared": "^4.0.0",
|
|
43
43
|
"@emotion/css": "^11.13.5",
|
|
44
44
|
"moment": "^2.20.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@babel/core": "^7.7.4",
|
|
48
|
-
"@contentful/field-editor-test-utils": "^
|
|
48
|
+
"@contentful/field-editor-test-utils": "^3.0.0",
|
|
49
49
|
"@lingui/core": "5.3.0",
|
|
50
50
|
"@types/timezoned-date": "^3.0.0",
|
|
51
51
|
"timezoned-date": "^3.0.2"
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"publishConfig": {
|
|
58
58
|
"registry": "https://npm.pkg.github.com/"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "267c2c3194103479b3fa0ba2c61001ef993f4cfd"
|
|
61
61
|
}
|