mymth / vanillajs-datepicker

A vanilla JavaScript remake of bootstrap-datepicker for Bulma and other CSS frameworks
MIT License
719 stars 147 forks source link

Unexpected date inserted depending on `format` specified #179

Closed namikaze-40p closed 3 months ago

namikaze-40p commented 3 months ago

Thanks for this library!

Selecting a date with a specific format will insert an unexpected date.

I tried and found on the demo page that this occurs in Safari on iPadOS and Chrome on macOS.

https://github.com/mymth/vanillajs-datepicker/assets/160984688/a3a3bdbf-c87c-451d-9d36-034b8060c7c2

mymth commented 3 months ago

Those characters are separator characters. (See Date format in the docs for details.) The built-in parser uses them only to split a date string. When parsing a format string, it only cares about which tokens appear in which order. This is because the built-in parser uses format string only to determine the order of the date parts (y, m, and d) in the date string. Then, when parsing a date string, the built-in parser splits the date string with separator characters and parses each part in the order determined from the format string.

So, when the format string:(mm/dd/yyyy) and the date string (03/09/2024) are given, the built-in parser first examines the format string and determines that the order of date parts is "m, d, y". Next, it splits the date string and gets the parts: "", "03", "09", "2024", "". Then, it evaluates each part in the determined order, like below:

Part Treated as Result
"" m ignored / the month of parsed date becomes the current month
"03" d makes the date of the parsed date the 3rd
"09" y makes the year of the parsed date the year 0009
"2004" \<extra> ignored
"" \<extra> ignored

As the result, since the current month is March, the parsed date becomes March 03, 0009.

I actually noticed this when testing the parser. I checked all the locales whether there are languages/countries that use a format starting with a separator character, and confirmed none does (at least by default). Then, I thought about possible cases where such formats are used, but nothing reasonable came up. (Seriously, what's the point of asking users to input a date surrounded by parentheses or prefixed with a tilde, exclamation mark or whatever sign?) So, I concluded that this would be just a theoretical problem with no effects in real-world usage and prioritizing smaller code size would be more beneficial. And decided not to change the algorithm.

Also, unlike some other date picker libraries, this library keeps the input field fully editable. Users can enter a date even without using the picker but only by typing. If the format in the above example is used, users have to type a date including the parentheses. I don't get the point of supporting creating such a user-unfriendly interface.

However, my imagination is limited. I might miss something. If you currently have a need for date input with such a format or know some practical examples, it would be appreciated if you let me know it/them. And if you have an immediate need, you can create your custom parser/formatter like this:

new Datepicker(elem, {
  format: {
    toValue: dateStr => Datepicker.parseDate(dateStr.replace(/^\((.+)\)$/, '$1'), 'm/d/y'),
    toDisplay: date => Datepicker.formatDate(date, '(mm/dd/yyyy)'),
  },
}); 
namikaze-40p commented 3 months ago

Thanks so much for your detailed reply!

So, I concluded that this would be just a theoretical problem with no effects in real-world usage and prioritizing smaller code size would be more beneficial. And decided not to change the algorithm.

I completely agree with your conclusions and policies. I had hoped that perhaps this bug could be easily fixed, but now I understand that the cost and return are not worth it.


From this point forward, I’m writing about my special case of using "[[", so you can skip this section.

I’m developing the feature to insert selected dates into the markdown editor(Obsidian), and I'm using "vanillajs-datepicker”. ("vanillajs-datepicker" is really useful, thanks!)

Its feature inserts a user-selected date with a user-specified "format". Because its markdown editor(Obsidian) allows text to be enclosed in "[[" and "]]" to give it special meaning, some users want to enclose selected dates in "[[" and "]]". Therefore, I needed to support "format" starting with "[[". (Now I have solved this problem by using the "changeDate" event, which is triggered when a date is selected, so that the selected date is not overwritten.)


I'll close this issue. Thanks so much!

mymth commented 3 months ago

Ohhhh, I had never imagined using a date picker in markdown editor. It looks like I should fix this at some point.

Thank you so much for letting me know that!