index.js
5.7 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
import toDate from '../toDate/index.js';
import formatters from '../_lib/format/lightFormatters/index.js';
import getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index.js';
import isValid from '../isValid/index.js';
import subMilliseconds from '../subMilliseconds/index.js';
import requiredArgs from '../_lib/requiredArgs/index.js'; // This RegExp consists of three parts separated by `|`:
// - (\w)\1* matches any sequences of the same letter
// - '' matches two quote characters in a row
// - '(''|[^'])+('|$) matches anything surrounded by two quote characters ('),
// except a single quote symbol, which ends the sequence.
// Two quote characters do not end the sequence.
// If there is no matching single quote
// then the sequence will continue until the end of the string.
// - . matches any single character unmatched by previous parts of the RegExps
var formattingTokensRegExp = /(\w)\1*|''|'(''|[^'])+('|$)|./g;
var escapedStringRegExp = /^'([^]*?)'?$/;
var doubleQuoteRegExp = /''/g;
var unescapedLatinCharacterRegExp = /[a-zA-Z]/;
/**
* @name lightFormat
* @category Common Helpers
* @summary Format the date.
*
* @description
* Return the formatted date string in the given format. Unlike `format`,
* `lightFormat` doesn't use locales and outputs date using the most popular tokens.
*
* > ⚠️ Please note that the `lightFormat` tokens differ from Moment.js and other libraries.
* > See: https://git.io/fxCyr
*
* The characters wrapped between two single quotes characters (') are escaped.
* Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.
*
* Format of the string is based on Unicode Technical Standard #35:
* https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
*
* Accepted patterns:
* | Unit | Pattern | Result examples |
* |---------------------------------|---------|-----------------------------------|
* | AM, PM | a..aaa | AM, PM |
* | | aaaa | a.m., p.m. |
* | | aaaaa | a, p |
* | Calendar year | y | 44, 1, 1900, 2017 |
* | | yy | 44, 01, 00, 17 |
* | | yyy | 044, 001, 000, 017 |
* | | yyyy | 0044, 0001, 1900, 2017 |
* | Month (formatting) | M | 1, 2, ..., 12 |
* | | MM | 01, 02, ..., 12 |
* | Day of month | d | 1, 2, ..., 31 |
* | | dd | 01, 02, ..., 31 |
* | Hour [1-12] | h | 1, 2, ..., 11, 12 |
* | | hh | 01, 02, ..., 11, 12 |
* | Hour [0-23] | H | 0, 1, 2, ..., 23 |
* | | HH | 00, 01, 02, ..., 23 |
* | Minute | m | 0, 1, ..., 59 |
* | | mm | 00, 01, ..., 59 |
* | Second | s | 0, 1, ..., 59 |
* | | ss | 00, 01, ..., 59 |
* | Fraction of second | S | 0, 1, ..., 9 |
* | | SS | 00, 01, ..., 99 |
* | | SSS | 000, 0001, ..., 999 |
* | | SSSS | ... |
*
* @param {Date|Number} date - the original date
* @param {String} format - the string of tokens
* @returns {String} the formatted date string
* @throws {TypeError} 2 arguments required
* @throws {RangeError} format string contains an unescaped latin alphabet character
*
* @example
* var result = lightFormat(new Date(2014, 1, 11), 'yyyy-MM-dd')
* //=> '2014-02-11'
*/
export default function lightFormat(dirtyDate, dirtyFormatStr) {
requiredArgs(2, arguments);
var formatStr = String(dirtyFormatStr);
var originalDate = toDate(dirtyDate);
if (!isValid(originalDate)) {
throw new RangeError('Invalid time value');
} // Convert the date in system timezone to the same date in UTC+00:00 timezone.
// This ensures that when UTC functions will be implemented, locales will be compatible with them.
// See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/376
var timezoneOffset = getTimezoneOffsetInMilliseconds(originalDate);
var utcDate = subMilliseconds(originalDate, timezoneOffset);
var result = formatStr.match(formattingTokensRegExp).map(function (substring) {
// Replace two single quote characters with one single quote character
if (substring === "''") {
return "'";
}
var firstCharacter = substring[0];
if (firstCharacter === "'") {
return cleanEscapedString(substring);
}
var formatter = formatters[firstCharacter];
if (formatter) {
return formatter(utcDate, substring, null, {});
}
if (firstCharacter.match(unescapedLatinCharacterRegExp)) {
throw new RangeError('Format string contains an unescaped latin alphabet character `' + firstCharacter + '`');
}
return substring;
}).join('');
return result;
}
function cleanEscapedString(input) {
return input.match(escapedStringRegExp)[1].replace(doubleQuoteRegExp, "'");
}