UNPKG

11.1 kBJavaScriptView Raw
1'use strict';
2
3/* Modified from https://github.com/taylorhakes/fecha
4 *
5 * The MIT License (MIT)
6 *
7 * Copyright (c) 2015 Taylor Hakes
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in all
17 * copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 */
27
28/*eslint-disable*/
29// 把 YYYY-MM-DD 改成了 yyyy-MM-dd
30(function (main) {
31 'use strict';
32
33 /**
34 * Parse or format dates
35 * @class fecha
36 */
37
38 var fecha = {};
39 var token = /d{1,4}|M{1,4}|yy(?:yy)?|S{1,3}|Do|ZZ|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g;
40 var twoDigits = '\\d\\d?';
41 var threeDigits = '\\d{3}';
42 var fourDigits = '\\d{4}';
43 var word = '[^\\s]+';
44 var literal = /\[([^]*?)\]/gm;
45 var noop = function noop() {};
46
47 function regexEscape(str) {
48 return str.replace(/[|\\{()[^$+*?.-]/g, '\\$&');
49 }
50
51 function shorten(arr, sLen) {
52 var newArr = [];
53 for (var i = 0, len = arr.length; i < len; i++) {
54 newArr.push(arr[i].substr(0, sLen));
55 }
56 return newArr;
57 }
58
59 function monthUpdate(arrName) {
60 return function (d, v, i18n) {
61 var index = i18n[arrName].indexOf(v.charAt(0).toUpperCase() + v.substr(1).toLowerCase());
62 if (~index) {
63 d.month = index;
64 }
65 };
66 }
67
68 function pad(val, len) {
69 val = String(val);
70 len = len || 2;
71 while (val.length < len) {
72 val = '0' + val;
73 }
74 return val;
75 }
76
77 var dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
78 var monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
79 var monthNamesShort = shorten(monthNames, 3);
80 var dayNamesShort = shorten(dayNames, 3);
81 fecha.i18n = {
82 dayNamesShort: dayNamesShort,
83 dayNames: dayNames,
84 monthNamesShort: monthNamesShort,
85 monthNames: monthNames,
86 amPm: ['am', 'pm'],
87 DoFn: function DoFn(D) {
88 return D + ['th', 'st', 'nd', 'rd'][D % 10 > 3 ? 0 : (D - D % 10 !== 10) * D % 10];
89 }
90 };
91
92 var formatFlags = {
93 D: function D(dateObj) {
94 return dateObj.getDay();
95 },
96 DD: function DD(dateObj) {
97 return pad(dateObj.getDay());
98 },
99 Do: function Do(dateObj, i18n) {
100 return i18n.DoFn(dateObj.getDate());
101 },
102 d: function d(dateObj) {
103 return dateObj.getDate();
104 },
105 dd: function dd(dateObj) {
106 return pad(dateObj.getDate());
107 },
108 ddd: function ddd(dateObj, i18n) {
109 return i18n.dayNamesShort[dateObj.getDay()];
110 },
111 dddd: function dddd(dateObj, i18n) {
112 return i18n.dayNames[dateObj.getDay()];
113 },
114 M: function M(dateObj) {
115 return dateObj.getMonth() + 1;
116 },
117 MM: function MM(dateObj) {
118 return pad(dateObj.getMonth() + 1);
119 },
120 MMM: function MMM(dateObj, i18n) {
121 return i18n.monthNamesShort[dateObj.getMonth()];
122 },
123 MMMM: function MMMM(dateObj, i18n) {
124 return i18n.monthNames[dateObj.getMonth()];
125 },
126 yy: function yy(dateObj) {
127 return pad(String(dateObj.getFullYear()), 4).substr(2);
128 },
129 yyyy: function yyyy(dateObj) {
130 return pad(dateObj.getFullYear(), 4);
131 },
132 h: function h(dateObj) {
133 return dateObj.getHours() % 12 || 12;
134 },
135 hh: function hh(dateObj) {
136 return pad(dateObj.getHours() % 12 || 12);
137 },
138 H: function H(dateObj) {
139 return dateObj.getHours();
140 },
141 HH: function HH(dateObj) {
142 return pad(dateObj.getHours());
143 },
144 m: function m(dateObj) {
145 return dateObj.getMinutes();
146 },
147 mm: function mm(dateObj) {
148 return pad(dateObj.getMinutes());
149 },
150 s: function s(dateObj) {
151 return dateObj.getSeconds();
152 },
153 ss: function ss(dateObj) {
154 return pad(dateObj.getSeconds());
155 },
156 S: function S(dateObj) {
157 return Math.round(dateObj.getMilliseconds() / 100);
158 },
159 SS: function SS(dateObj) {
160 return pad(Math.round(dateObj.getMilliseconds() / 10), 2);
161 },
162 SSS: function SSS(dateObj) {
163 return pad(dateObj.getMilliseconds(), 3);
164 },
165 a: function a(dateObj, i18n) {
166 return dateObj.getHours() < 12 ? i18n.amPm[0] : i18n.amPm[1];
167 },
168 A: function A(dateObj, i18n) {
169 return dateObj.getHours() < 12 ? i18n.amPm[0].toUpperCase() : i18n.amPm[1].toUpperCase();
170 },
171 ZZ: function ZZ(dateObj) {
172 var o = dateObj.getTimezoneOffset();
173 return (o > 0 ? '-' : '+') + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4);
174 }
175 };
176
177 var parseFlags = {
178 d: [twoDigits, function (d, v) {
179 d.day = v;
180 }],
181 Do: [twoDigits + word, function (d, v) {
182 d.day = parseInt(v, 10);
183 }],
184 M: [twoDigits, function (d, v) {
185 d.month = v - 1;
186 }],
187 yy: [twoDigits, function (d, v) {
188 var da = new Date(),
189 cent = +('' + da.getFullYear()).substr(0, 2);
190 d.year = '' + (v > 68 ? cent - 1 : cent) + v;
191 }],
192 h: [twoDigits, function (d, v) {
193 d.hour = v;
194 }],
195 m: [twoDigits, function (d, v) {
196 d.minute = v;
197 }],
198 s: [twoDigits, function (d, v) {
199 d.second = v;
200 }],
201 yyyy: [fourDigits, function (d, v) {
202 d.year = v;
203 }],
204 S: ['\\d', function (d, v) {
205 d.millisecond = v * 100;
206 }],
207 SS: ['\\d{2}', function (d, v) {
208 d.millisecond = v * 10;
209 }],
210 SSS: [threeDigits, function (d, v) {
211 d.millisecond = v;
212 }],
213 D: [twoDigits, noop],
214 ddd: [word, noop],
215 MMM: [word, monthUpdate('monthNamesShort')],
216 MMMM: [word, monthUpdate('monthNames')],
217 a: [word, function (d, v, i18n) {
218 var val = v.toLowerCase();
219 if (val === i18n.amPm[0]) {
220 d.isPm = false;
221 } else if (val === i18n.amPm[1]) {
222 d.isPm = true;
223 }
224 }],
225 ZZ: ['[^\\s]*?[\\+\\-]\\d\\d:?\\d\\d|[^\\s]*?Z', function (d, v) {
226 var parts = (v + '').match(/([+-]|\d\d)/gi),
227 minutes;
228
229 if (parts) {
230 minutes = +(parts[1] * 60) + parseInt(parts[2], 10);
231 d.timezoneOffset = parts[0] === '+' ? minutes : -minutes;
232 }
233 }]
234 };
235 parseFlags.dd = parseFlags.d;
236 parseFlags.dddd = parseFlags.ddd;
237 parseFlags.DD = parseFlags.D;
238 parseFlags.mm = parseFlags.m;
239 parseFlags.hh = parseFlags.H = parseFlags.HH = parseFlags.h;
240 parseFlags.MM = parseFlags.M;
241 parseFlags.ss = parseFlags.s;
242 parseFlags.A = parseFlags.a;
243
244 // Some common format strings
245 fecha.masks = {
246 default: 'ddd MMM dd yyyy HH:mm:ss',
247 shortDate: 'M/D/yy',
248 mediumDate: 'MMM d, yyyy',
249 longDate: 'MMMM d, yyyy',
250 fullDate: 'dddd, MMMM d, yyyy',
251 shortTime: 'HH:mm',
252 mediumTime: 'HH:mm:ss',
253 longTime: 'HH:mm:ss.SSS'
254 };
255
256 /***
257 * Format a date
258 * @method format
259 * @param {Date|number} dateObj
260 * @param {string} mask Format of the date, i.e. 'mm-dd-yy' or 'shortDate'
261 */
262 fecha.format = function (dateObj, mask, i18nSettings) {
263 var i18n = i18nSettings || fecha.i18n;
264
265 if (typeof dateObj === 'number') {
266 dateObj = new Date(dateObj);
267 }
268
269 if (Object.prototype.toString.call(dateObj) !== '[object Date]' || isNaN(dateObj.getTime())) {
270 throw new Error('Invalid Date in fecha.format');
271 }
272
273 mask = fecha.masks[mask] || mask || fecha.masks['default'];
274
275 var literals = [];
276
277 // Make literals inactive by replacing them with ??
278 mask = mask.replace(literal, function ($0, $1) {
279 literals.push($1);
280 return '@@@';
281 });
282 // Apply formatting rules
283 mask = mask.replace(token, function ($0) {
284 return $0 in formatFlags ? formatFlags[$0](dateObj, i18n) : $0.slice(1, $0.length - 1);
285 });
286 // Inline literal values back into the formatted value
287 return mask.replace(/@@@/g, function () {
288 return literals.shift();
289 });
290 };
291
292 /**
293 * Parse a date string into an object, changes - into /
294 * @method parse
295 * @param {string} dateStr Date string
296 * @param {string} format Date parse format
297 * @returns {Date|boolean}
298 */
299 fecha.parse = function (dateStr, format, i18nSettings) {
300 var i18n = i18nSettings || fecha.i18n;
301
302 if (typeof format !== 'string') {
303 throw new Error('Invalid format in fecha.parse');
304 }
305
306 format = fecha.masks[format] || format;
307
308 // Avoid regular expression denial of service, fail early for really long strings
309 // https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS
310 if (dateStr.length > 1000) {
311 return null;
312 }
313
314 var dateInfo = {};
315 var parseInfo = [];
316 var literals = [];
317 format = format.replace(literal, function ($0, $1) {
318 literals.push($1);
319 return '@@@';
320 });
321 var newFormat = regexEscape(format).replace(token, function ($0) {
322 if (parseFlags[$0]) {
323 var info = parseFlags[$0];
324 parseInfo.push(info[1]);
325 return '(' + info[0] + ')';
326 }
327
328 return $0;
329 });
330 newFormat = newFormat.replace(/@@@/g, function () {
331 return literals.shift();
332 });
333 var matches = dateStr.match(new RegExp(newFormat, 'i'));
334 if (!matches) {
335 return null;
336 }
337
338 for (var i = 1; i < matches.length; i++) {
339 parseInfo[i - 1](dateInfo, matches[i], i18n);
340 }
341
342 var today = new Date();
343 if (dateInfo.isPm === true && dateInfo.hour != null && +dateInfo.hour !== 12) {
344 dateInfo.hour = +dateInfo.hour + 12;
345 } else if (dateInfo.isPm === false && +dateInfo.hour === 12) {
346 dateInfo.hour = 0;
347 }
348
349 var date;
350 if (dateInfo.timezoneOffset != null) {
351 dateInfo.minute = +(dateInfo.minute || 0) - +dateInfo.timezoneOffset;
352 date = new Date(Date.UTC(dateInfo.year || today.getFullYear(), dateInfo.month || 0, dateInfo.day || 1, dateInfo.hour || 0, dateInfo.minute || 0, dateInfo.second || 0, dateInfo.millisecond || 0));
353 } else {
354 date = new Date(dateInfo.year || today.getFullYear(), dateInfo.month || 0, dateInfo.day || 1, dateInfo.hour || 0, dateInfo.minute || 0, dateInfo.second || 0, dateInfo.millisecond || 0);
355 }
356 return date;
357 };
358
359 /* istanbul ignore next */
360 if (typeof module !== 'undefined' && module.exports) {
361 module.exports = fecha;
362 } else if (typeof define === 'function' && define.amd) {
363 define(function () {
364 return fecha;
365 });
366 } else {
367 main.fecha = fecha;
368 }
369})(undefined);
\No newline at end of file