Skip to content

Protected tokens consistency in format and parse functions (v3?) #2950

@fturmel

Description

@fturmel

How come the format and parse tokens Yand D are protected, but not all their lengths and variants?

I'm guessing it was put in place to help people migrate from other libraries, but the Y, YYYYY, YYYYYY are valid in moment too. DDD and DDDD behave the same in both, so it's probably not impactful for migration mistakes.

EDIT: not quite the same in terms of padding, though. Ex: Jan 3rd 2021:

token date-fns moment
DDD 003 3
DDDD 0003 003

I wouldn't rule out that this protection feature is also helping people that are simply just guessing the tokens without consulting the docs. If the output looks OK at first glance, it probably ships and creates weird bugs in many apps, especially Y.

See #2133

Just wanted to put this out there, and suggest that all variants should be protected in v3.

import { format } from "date-fns";

const now = new Date(2021, 11, 29);

const tokens = [
  "Yo",
  "Y",
  "YY",
  "YYY",
  "YYYY",
  "YYYYY",
  "YYYYYY",
  "Do",
  "D",
  "DD",
  "DDD",
  "DDDD",
  "DDDDD",
  "DDDDDD"
];

tokens.forEach((t) => {
  try {
    console.log(t, format(now, t));
  } catch (e) {
    console.log(t, "Range Error");
  }
});

// Yo 2022nd 
// Y 2022 
// YY Range Error 
// YYY 2022 
// YYYY Range Error 
// YYYYY 02022 
// YYYYYY 002022 

// Do 363rd 
// D Range Error 
// DD Range Error 
// DDD 363 
// DDDD 0363 
// DDDDD 00363 
// DDDDDD 000363 

Related:
https://date-fns.org/docs/format
https://date-fns.org/docs/parse
https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md

export function throwProtectedError(
token: string,
format: string,
input: string
): void {
if (token === 'YYYY') {
throw new RangeError(
`Use \`yyyy\` instead of \`YYYY\` (in \`${format}\`) for formatting years to the input \`${input}\`; see: https://git.io/fxCyr`
)
} else if (token === 'YY') {
throw new RangeError(
`Use \`yy\` instead of \`YY\` (in \`${format}\`) for formatting years to the input \`${input}\`; see: https://git.io/fxCyr`
)
} else if (token === 'D') {
throw new RangeError(
`Use \`d\` instead of \`D\` (in \`${format}\`) for formatting days of the month to the input \`${input}\`; see: https://git.io/fxCyr`
)
} else if (token === 'DD') {
throw new RangeError(
`Use \`dd\` instead of \`DD\` (in \`${format}\`) for formatting days of the month to the input \`${input}\`; see: https://git.io/fxCyr`
)
}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions