index.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.default = lightFormat;
  7. var _index = _interopRequireDefault(require("../toDate/index.js"));
  8. var _index2 = _interopRequireDefault(require("../_lib/format/lightFormatters/index.js"));
  9. var _index3 = _interopRequireDefault(require("../_lib/getTimezoneOffsetInMilliseconds/index.js"));
  10. var _index4 = _interopRequireDefault(require("../isValid/index.js"));
  11. var _index5 = _interopRequireDefault(require("../subMilliseconds/index.js"));
  12. var _index6 = _interopRequireDefault(require("../_lib/requiredArgs/index.js"));
  13. // This RegExp consists of three parts separated by `|`:
  14. // - (\w)\1* matches any sequences of the same letter
  15. // - '' matches two quote characters in a row
  16. // - '(''|[^'])+('|$) matches anything surrounded by two quote characters ('),
  17. // except a single quote symbol, which ends the sequence.
  18. // Two quote characters do not end the sequence.
  19. // If there is no matching single quote
  20. // then the sequence will continue until the end of the string.
  21. // - . matches any single character unmatched by previous parts of the RegExps
  22. var formattingTokensRegExp = /(\w)\1*|''|'(''|[^'])+('|$)|./g;
  23. var escapedStringRegExp = /^'([^]*?)'?$/;
  24. var doubleQuoteRegExp = /''/g;
  25. var unescapedLatinCharacterRegExp = /[a-zA-Z]/;
  26. /**
  27. * @name lightFormat
  28. * @category Common Helpers
  29. * @summary Format the date.
  30. *
  31. * @description
  32. * Return the formatted date string in the given format. Unlike `format`,
  33. * `lightFormat` doesn't use locales and outputs date using the most popular tokens.
  34. *
  35. * > ⚠️ Please note that the `lightFormat` tokens differ from Moment.js and other libraries.
  36. * > See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
  37. *
  38. * The characters wrapped between two single quotes characters (') are escaped.
  39. * Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.
  40. *
  41. * Format of the string is based on Unicode Technical Standard #35:
  42. * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
  43. *
  44. * Accepted patterns:
  45. * | Unit | Pattern | Result examples |
  46. * |---------------------------------|---------|-----------------------------------|
  47. * | AM, PM | a..aaa | AM, PM |
  48. * | | aaaa | a.m., p.m. |
  49. * | | aaaaa | a, p |
  50. * | Calendar year | y | 44, 1, 1900, 2017 |
  51. * | | yy | 44, 01, 00, 17 |
  52. * | | yyy | 044, 001, 000, 017 |
  53. * | | yyyy | 0044, 0001, 1900, 2017 |
  54. * | Month (formatting) | M | 1, 2, ..., 12 |
  55. * | | MM | 01, 02, ..., 12 |
  56. * | Day of month | d | 1, 2, ..., 31 |
  57. * | | dd | 01, 02, ..., 31 |
  58. * | Hour [1-12] | h | 1, 2, ..., 11, 12 |
  59. * | | hh | 01, 02, ..., 11, 12 |
  60. * | Hour [0-23] | H | 0, 1, 2, ..., 23 |
  61. * | | HH | 00, 01, 02, ..., 23 |
  62. * | Minute | m | 0, 1, ..., 59 |
  63. * | | mm | 00, 01, ..., 59 |
  64. * | Second | s | 0, 1, ..., 59 |
  65. * | | ss | 00, 01, ..., 59 |
  66. * | Fraction of second | S | 0, 1, ..., 9 |
  67. * | | SS | 00, 01, ..., 99 |
  68. * | | SSS | 000, 001, ..., 999 |
  69. * | | SSSS | ... |
  70. *
  71. * @param {Date|Number} date - the original date
  72. * @param {String} format - the string of tokens
  73. * @returns {String} the formatted date string
  74. * @throws {TypeError} 2 arguments required
  75. * @throws {RangeError} format string contains an unescaped latin alphabet character
  76. *
  77. * @example
  78. * const result = lightFormat(new Date(2014, 1, 11), 'yyyy-MM-dd')
  79. * //=> '2014-02-11'
  80. */
  81. function lightFormat(dirtyDate, formatStr) {
  82. (0, _index6.default)(2, arguments);
  83. var originalDate = (0, _index.default)(dirtyDate);
  84. if (!(0, _index4.default)(originalDate)) {
  85. throw new RangeError('Invalid time value');
  86. }
  87. // Convert the date in system timezone to the same date in UTC+00:00 timezone.
  88. // This ensures that when UTC functions will be implemented, locales will be compatible with them.
  89. // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/376
  90. var timezoneOffset = (0, _index3.default)(originalDate);
  91. var utcDate = (0, _index5.default)(originalDate, timezoneOffset);
  92. var tokens = formatStr.match(formattingTokensRegExp);
  93. // The only case when formattingTokensRegExp doesn't match the string is when it's empty
  94. if (!tokens) return '';
  95. var result = tokens.map(function (substring) {
  96. // Replace two single quote characters with one single quote character
  97. if (substring === "''") {
  98. return "'";
  99. }
  100. var firstCharacter = substring[0];
  101. if (firstCharacter === "'") {
  102. return cleanEscapedString(substring);
  103. }
  104. var formatter = _index2.default[firstCharacter];
  105. if (formatter) {
  106. return formatter(utcDate, substring);
  107. }
  108. if (firstCharacter.match(unescapedLatinCharacterRegExp)) {
  109. throw new RangeError('Format string contains an unescaped latin alphabet character `' + firstCharacter + '`');
  110. }
  111. return substring;
  112. }).join('');
  113. return result;
  114. }
  115. function cleanEscapedString(input) {
  116. var matches = input.match(escapedStringRegExp);
  117. if (!matches) {
  118. return input;
  119. }
  120. return matches[1].replace(doubleQuoteRegExp, "'");
  121. }
  122. module.exports = exports.default;