UNPKG

14.4 kBJavaScriptView Raw
1import { isBlank, isPresent, isString } from './util';
2export function renderDateTime(template, value, locale) {
3 if (isBlank(value)) {
4 return '';
5 }
6 var tokens = [];
7 var hasText = false;
8 FORMAT_KEYS.forEach(function (format, index) {
9 if (template.indexOf(format.f) > -1) {
10 var token = '{' + index + '}';
11 var text = renderTextFormat(format.f, value[format.k], value, locale);
12 if (!hasText && text && isPresent(value[format.k])) {
13 hasText = true;
14 }
15 tokens.push(token, text);
16 template = template.replace(format.f, token);
17 }
18 });
19 if (!hasText) {
20 return '';
21 }
22 for (var i = 0; i < tokens.length; i += 2) {
23 template = template.replace(tokens[i], tokens[i + 1]);
24 }
25 return template;
26}
27export function renderTextFormat(format, value, date, locale) {
28 if (format === FORMAT_DDDD || format === FORMAT_DDD) {
29 try {
30 value = (new Date(date.year, date.month - 1, date.day)).getDay();
31 if (format === FORMAT_DDDD) {
32 return (isPresent(locale.dayNames) ? locale.dayNames : DAY_NAMES)[value];
33 }
34 return (isPresent(locale.dayShortNames) ? locale.dayShortNames : DAY_SHORT_NAMES)[value];
35 }
36 catch (e) { }
37 return '';
38 }
39 if (format === FORMAT_A) {
40 return date ? date.hour < 12 ? 'AM' : 'PM' : isPresent(value) ? value.toUpperCase() : '';
41 }
42 if (format === FORMAT_a) {
43 return date ? date.hour < 12 ? 'am' : 'pm' : isPresent(value) ? value : '';
44 }
45 if (isBlank(value)) {
46 return '';
47 }
48 if (format === FORMAT_YY || format === FORMAT_MM ||
49 format === FORMAT_DD || format === FORMAT_HH ||
50 format === FORMAT_mm || format === FORMAT_ss) {
51 return twoDigit(value);
52 }
53 if (format === FORMAT_YYYY) {
54 return fourDigit(value);
55 }
56 if (format === FORMAT_MMMM) {
57 return (isPresent(locale.monthNames) ? locale.monthNames : MONTH_NAMES)[value - 1];
58 }
59 if (format === FORMAT_MMM) {
60 return (isPresent(locale.monthShortNames) ? locale.monthShortNames : MONTH_SHORT_NAMES)[value - 1];
61 }
62 if (format === FORMAT_hh || format === FORMAT_h) {
63 if (value === 0) {
64 return '12';
65 }
66 if (value > 12) {
67 value -= 12;
68 }
69 if (format === FORMAT_hh && value < 10) {
70 return ('0' + value);
71 }
72 }
73 return value.toString();
74}
75export function dateValueRange(format, min, max) {
76 var opts = [];
77 var i;
78 if (format === FORMAT_YYYY || format === FORMAT_YY) {
79 // year
80 i = max.year;
81 while (i >= min.year) {
82 opts.push(i--);
83 }
84 }
85 else if (format === FORMAT_MMMM || format === FORMAT_MMM ||
86 format === FORMAT_MM || format === FORMAT_M ||
87 format === FORMAT_hh || format === FORMAT_h) {
88 // month or 12-hour
89 for (i = 1; i < 13; i++) {
90 opts.push(i);
91 }
92 }
93 else if (format === FORMAT_DDDD || format === FORMAT_DDD ||
94 format === FORMAT_DD || format === FORMAT_D) {
95 // day
96 for (i = 1; i < 32; i++) {
97 opts.push(i);
98 }
99 }
100 else if (format === FORMAT_HH || format === FORMAT_H) {
101 // 24-hour
102 for (i = 0; i < 24; i++) {
103 opts.push(i);
104 }
105 }
106 else if (format === FORMAT_mm || format === FORMAT_m) {
107 // minutes
108 for (i = 0; i < 60; i++) {
109 opts.push(i);
110 }
111 }
112 else if (format === FORMAT_ss || format === FORMAT_s) {
113 // seconds
114 for (i = 0; i < 60; i++) {
115 opts.push(i);
116 }
117 }
118 else if (format === FORMAT_A || format === FORMAT_a) {
119 // AM/PM
120 opts.push('am', 'pm');
121 }
122 return opts;
123}
124export function dateSortValue(year, month, day, hour, minute) {
125 if (hour === void 0) { hour = 0; }
126 if (minute === void 0) { minute = 0; }
127 return parseInt("1" + fourDigit(year) + twoDigit(month) + twoDigit(day) + twoDigit(hour) + twoDigit(minute), 10);
128}
129export function dateDataSortValue(data) {
130 if (data) {
131 return dateSortValue(data.year, data.month, data.day, data.hour, data.minute);
132 }
133 return -1;
134}
135export function daysInMonth(month, year) {
136 return (month === 4 || month === 6 || month === 9 || month === 11) ? 30 : (month === 2) ? isLeapYear(year) ? 29 : 28 : 31;
137}
138export function isLeapYear(year) {
139 return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
140}
141var ISO_8601_REGEXP = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
142var TIME_REGEXP = /^((\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
143export function parseDate(val) {
144 // manually parse IS0 cuz Date.parse cannot be trusted
145 // ISO 8601 format: 1994-12-15T13:47:20Z
146 var parse;
147 if (isPresent(val) && val !== '') {
148 // try parsing for just time first, HH:MM
149 parse = TIME_REGEXP.exec(val);
150 if (isPresent(parse)) {
151 // adjust the array so it fits nicely with the datetime parse
152 parse.unshift(undefined, undefined);
153 parse[2] = parse[3] = undefined;
154 }
155 else {
156 // try parsing for full ISO datetime
157 parse = ISO_8601_REGEXP.exec(val);
158 }
159 }
160 if (isBlank(parse)) {
161 // wasn't able to parse the ISO datetime
162 return null;
163 }
164 // ensure all the parse values exist with at least 0
165 for (var i = 1; i < 8; i++) {
166 parse[i] = (parse[i] !== undefined ? parseInt(parse[i], 10) : null);
167 }
168 var tzOffset = 0;
169 if (isPresent(parse[9]) && isPresent(parse[10])) {
170 // hours
171 tzOffset = parseInt(parse[10], 10) * 60;
172 if (isPresent(parse[11])) {
173 // minutes
174 tzOffset += parseInt(parse[11], 10);
175 }
176 if (parse[9] === '-') {
177 // + or -
178 tzOffset *= -1;
179 }
180 }
181 return {
182 year: parse[1],
183 month: parse[2],
184 day: parse[3],
185 hour: parse[4],
186 minute: parse[5],
187 second: parse[6],
188 millisecond: parse[7],
189 tzOffset: tzOffset,
190 };
191}
192export function compareDates(d1, d2) {
193 var date1 = new Date(d1.year, d1.month, d1.day, d1.hour, d1.minute, d1.second);
194 var date2 = new Date(d2.year, d2.month, d2.day, d2.hour, d2.minute, d2.second);
195 return date1.getTime() - date2.getTime();
196}
197export function updateDate(existingData, newData) {
198 if (isPresent(newData) && newData !== '') {
199 if (isString(newData)) {
200 // new date is a string, and hopefully in the ISO format
201 // convert it to our DateTimeData if a valid ISO
202 newData = parseDate(newData);
203 if (newData) {
204 // successfully parsed the ISO string to our DateTimeData
205 Object.assign(existingData, newData);
206 return true;
207 }
208 }
209 else if ((isPresent(newData.year) || isPresent(newData.hour) || isPresent(newData.month) || isPresent(newData.day) || isPresent(newData.minute) || isPresent(newData.second))) {
210 // newData is from of a datetime picker's selected values
211 // update the existing DateTimeData data with the new values
212 // do some magic for 12-hour values
213 if (isPresent(newData.ampm) && isPresent(newData.hour)) {
214 if (newData.ampm.value === 'pm') {
215 newData.hour.value = (newData.hour.value === 12 ? 12 : newData.hour.value + 12);
216 }
217 else {
218 newData.hour.value = (newData.hour.value === 12 ? 0 : newData.hour.value);
219 }
220 }
221 // merge new values from the picker's selection
222 // to the existing DateTimeData values
223 for (var k in newData) {
224 existingData[k] = newData[k].value;
225 }
226 return true;
227 }
228 // eww, invalid data
229 console.warn("Error parsing date: \"" + newData + "\". Please provide a valid ISO 8601 datetime format: https://www.w3.org/TR/NOTE-datetime");
230 }
231 else {
232 // blank data, clear everything out
233 for (var k in existingData) {
234 delete existingData[k];
235 }
236 }
237 return false;
238}
239export function parseTemplate(template) {
240 var formats = [];
241 template = template.replace(/[^\w\s]/gi, ' ');
242 FORMAT_KEYS.forEach(function (format) {
243 if (format.f.length > 1 && template.indexOf(format.f) > -1 && template.indexOf(format.f + format.f.charAt(0)) < 0) {
244 template = template.replace(format.f, ' ' + format.f + ' ');
245 }
246 });
247 var words = template.split(' ').filter(function (w) { return w.length > 0; });
248 words.forEach(function (word, i) {
249 FORMAT_KEYS.forEach(function (format) {
250 if (word === format.f) {
251 if (word === FORMAT_A || word === FORMAT_a) {
252 // this format is an am/pm format, so it's an "a" or "A"
253 if ((formats.indexOf(FORMAT_h) < 0 && formats.indexOf(FORMAT_hh) < 0) ||
254 VALID_AMPM_PREFIX.indexOf(words[i - 1]) === -1) {
255 // template does not already have a 12-hour format
256 // or this am/pm format doesn't have a hour, minute, or second format immediately before it
257 // so do not treat this word "a" or "A" as the am/pm format
258 return;
259 }
260 }
261 formats.push(word);
262 }
263 });
264 });
265 return formats;
266}
267export function getValueFromFormat(date, format) {
268 if (format === FORMAT_A || format === FORMAT_a) {
269 return (date.hour < 12 ? 'am' : 'pm');
270 }
271 if (format === FORMAT_hh || format === FORMAT_h) {
272 return (date.hour > 12 ? date.hour - 12 : date.hour);
273 }
274 return date[convertFormatToKey(format)];
275}
276export function convertFormatToKey(format) {
277 for (var k in FORMAT_KEYS) {
278 if (FORMAT_KEYS[k].f === format) {
279 return FORMAT_KEYS[k].k;
280 }
281 }
282 return null;
283}
284export function convertDataToISO(data) {
285 // https://www.w3.org/TR/NOTE-datetime
286 var rtn = '';
287 if (isPresent(data)) {
288 if (isPresent(data.year)) {
289 // YYYY
290 rtn = fourDigit(data.year);
291 if (isPresent(data.month)) {
292 // YYYY-MM
293 rtn += '-' + twoDigit(data.month);
294 if (isPresent(data.day)) {
295 // YYYY-MM-DD
296 rtn += '-' + twoDigit(data.day);
297 if (isPresent(data.hour)) {
298 // YYYY-MM-DDTHH:mm:SS
299 rtn += "T" + twoDigit(data.hour) + ":" + twoDigit(data.minute) + ":" + twoDigit(data.second);
300 if (data.millisecond > 0) {
301 // YYYY-MM-DDTHH:mm:SS.SSS
302 rtn += '.' + threeDigit(data.millisecond);
303 }
304 if (isBlank(data.tzOffset) || data.tzOffset === 0) {
305 // YYYY-MM-DDTHH:mm:SSZ
306 rtn += 'Z';
307 }
308 else {
309 // YYYY-MM-DDTHH:mm:SS+/-HH:mm
310 rtn += (data.tzOffset > 0 ? '+' : '-') + twoDigit(Math.floor(data.tzOffset / 60)) + ':' + twoDigit(data.tzOffset % 60);
311 }
312 }
313 }
314 }
315 }
316 else if (isPresent(data.hour)) {
317 // HH:mm
318 rtn = twoDigit(data.hour) + ':' + twoDigit(data.minute);
319 if (isPresent(data.second)) {
320 // HH:mm:SS
321 rtn += ':' + twoDigit(data.second);
322 if (isPresent(data.millisecond)) {
323 // HH:mm:SS.SSS
324 rtn += '.' + threeDigit(data.millisecond);
325 }
326 }
327 }
328 }
329 return rtn;
330}
331function twoDigit(val) {
332 return ('0' + (isPresent(val) ? Math.abs(val) : '0')).slice(-2);
333}
334function threeDigit(val) {
335 return ('00' + (isPresent(val) ? Math.abs(val) : '0')).slice(-3);
336}
337function fourDigit(val) {
338 return ('000' + (isPresent(val) ? Math.abs(val) : '0')).slice(-4);
339}
340var FORMAT_YYYY = 'YYYY';
341var FORMAT_YY = 'YY';
342var FORMAT_MMMM = 'MMMM';
343var FORMAT_MMM = 'MMM';
344var FORMAT_MM = 'MM';
345var FORMAT_M = 'M';
346var FORMAT_DDDD = 'DDDD';
347var FORMAT_DDD = 'DDD';
348var FORMAT_DD = 'DD';
349var FORMAT_D = 'D';
350var FORMAT_HH = 'HH';
351var FORMAT_H = 'H';
352var FORMAT_hh = 'hh';
353var FORMAT_h = 'h';
354var FORMAT_mm = 'mm';
355var FORMAT_m = 'm';
356var FORMAT_ss = 'ss';
357var FORMAT_s = 's';
358var FORMAT_A = 'A';
359var FORMAT_a = 'a';
360var FORMAT_KEYS = [
361 { f: FORMAT_YYYY, k: 'year' },
362 { f: FORMAT_MMMM, k: 'month' },
363 { f: FORMAT_DDDD, k: 'day' },
364 { f: FORMAT_MMM, k: 'month' },
365 { f: FORMAT_DDD, k: 'day' },
366 { f: FORMAT_YY, k: 'year' },
367 { f: FORMAT_MM, k: 'month' },
368 { f: FORMAT_DD, k: 'day' },
369 { f: FORMAT_HH, k: 'hour' },
370 { f: FORMAT_hh, k: 'hour' },
371 { f: FORMAT_mm, k: 'minute' },
372 { f: FORMAT_ss, k: 'second' },
373 { f: FORMAT_M, k: 'month' },
374 { f: FORMAT_D, k: 'day' },
375 { f: FORMAT_H, k: 'hour' },
376 { f: FORMAT_h, k: 'hour' },
377 { f: FORMAT_m, k: 'minute' },
378 { f: FORMAT_s, k: 'second' },
379 { f: FORMAT_A, k: 'ampm' },
380 { f: FORMAT_a, k: 'ampm' },
381];
382var DAY_NAMES = [
383 'Sunday',
384 'Monday',
385 'Tuesday',
386 'Wednesday',
387 'Thursday',
388 'Friday',
389 'Saturday',
390];
391var DAY_SHORT_NAMES = [
392 'Sun',
393 'Mon',
394 'Tue',
395 'Wed',
396 'Thu',
397 'Fri',
398 'Sat',
399];
400var MONTH_NAMES = [
401 'January',
402 'February',
403 'March',
404 'April',
405 'May',
406 'June',
407 'July',
408 'August',
409 'September',
410 'October',
411 'November',
412 'December',
413];
414var MONTH_SHORT_NAMES = [
415 'Jan',
416 'Feb',
417 'Mar',
418 'Apr',
419 'May',
420 'Jun',
421 'Jul',
422 'Aug',
423 'Sep',
424 'Oct',
425 'Nov',
426 'Dec',
427];
428var VALID_AMPM_PREFIX = [
429 FORMAT_hh, FORMAT_h, FORMAT_mm, FORMAT_m, FORMAT_ss, FORMAT_s
430];
431//# sourceMappingURL=datetime-util.js.map
\No newline at end of file