欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

parse('2-12-12', 'yyyy-MM-dd', new Date()) returns a valid date #942 有大用

parse('2-12-12', 'yyyy-MM-dd', new Date()) returns a valid date #942

 Open
OCJvanDijk opened this issue on 19 Oct 2018 · 7 comments

Comments

@OCJvanDijk

commented on 19 Oct 2018  

Is this intended? I would expect parse('2-12-12', 'yyyy-MM-dd', new Date()) to fail as the correct format would be '0002-12-12'.

@OCJvanDijk OCJvanDijk changed the title parse('1-12-12', 'yyyy-MM-dd', new Date()) returns a valid dateparse('2-12-12', 'yyyy-MM-dd', new Date()) returns a valid date on 19 Oct 2018
@VasilioRuzanni

commented on 11 Nov 2018  

To add up to it, this also gets parsed just fine:

parse('1-12-2018', 'dd-MM-yyyy', new Date());

while I assume it to fail. It would only be parsed when pattern is d-MM-yyyy or if date string is explicitly 01-12-2018.

Otherwise, it somewhat kills the whole purpose of passing the pattern as it doesn't follow it strictly.

UPDATE: I have misread the original comment at first, it seems to outline the same exact issue.

@kossnocorp
Member

commented on 14 Nov 2018

You both have a fair point. We didn't put much thought into that but just tried to parse as many cases as possible.

Before we proceed to make parse strict, could you please tell about your cases where it caused troubles? Understanding the exact issue will help figure out the optimal solution. Thanks!

@VasilioRuzanni

commented on 20 Nov 2018  

@kossnocorp Aside from this is how moment and luxon handle this kind of stuff, its useful to consistently control user input in one-way flow environments (e.g., react), where you update some state on every stroke (often the case). In that case its fine to allow strictly incorrect input, but the issue appears when an incomplete input is parsed as something valid.

E.g., simple use case: user enters 05-12-20 and its being immediately parsed as a valid date that is formatted with a strict pattern and ends up being 05-12-2020. But what the user really wanted to type is 05-12-2018, he just didn't have a chance to type the remaining 18 piece. Now the user backspaces one character and its immediately parsed to 05-12-0201, etc, and the story repeats.

I ended up using luxon for the current project just because of this, but will immediately switch back to date-fns once there is such capability (because date-fns is way more awesome API-wise).

@OCJvanDijk
Author

commented on 25 Nov 2018

I was building a date picker where you could either type or select a date on a calendar view. The calendar view would update to show the month with the entered date as selected immediately when the user finished typing a date. But because of this it would already move to the year 2, then 20, then 201 etc as the user was typing.

I fixed it by doing an input === format(parse(input, pattern), pattern) check.

@benbcai

commented on 5 Mar

The inability to do strict parsing also prevents my team from using date-fns. To illustrate the use case that @VasilioRuzanni and @OCJvanDijk mentioned, take a look at the first example here. The default date is today's date in the format MM/dd/yyyy. As an example, today's date is 03/04/2019. If you delete the last two digits from the year, you end up with 03/04/20. My intention may be to change the year from 2019 to 2018 by deleting 19. However, the parse function in date-fns accepts 20 as a valid year in the 4-digit year format yyyy. As a result, the calendar picker would change the date to March 4th, 2020.

date-parsing

@chrisbruford

commented on 5 Jul  

To add to the use-cases:

We use parse as part of some custom validators in our angular app where dd/mm/yyyy is the only accepted format - using parse handles other parts of the validator but we've had to introduce an additional regexp test to ensure the correct format before passing through to date-fns for parsing.

Not the end of the world but would be good if parse actually enforced the format being passed in

@clementprdhomme

The current hack you can do is to check whether the string is the same length as the format:

import parse from 'date-fns/parse';
import isDate from 'date-fns/isDate';
import isValid from 'date-fns/isValid';

/**
 * Parse a string as a Date object
 * @param {string} str String to parse
 * @param {string} format Format of the date (see date-fns formats)
 */
const parseDate = (str, format) => {
  // This condition is necessary since date-fns doesn't strictly parse the dates
  // anymore:
  // https://github.com/date-fns/date-fns/issues/942
  if (str.length !== format.length) {
    return undefined;
  }

  const parsed = parse(str, format, new Date());
  if (isDate(parsed) && isValid(parsed)) {
    return parsed;
  }

  return undefined;
};


来自  https://github.com/date-fns/date-fns/issues/942

普通分类: