lightFormat.cjs 5.6 KB

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