Opened 15 months ago

Last modified 15 months ago

#15239 new bug

Manually entered 4 digit Years get converted in unexpected ways

Reported by: Michael Häfliger Owned by: Michael Häfliger
Priority: minor Milestone: none
Component: ui.datepicker Version: 1.12.1
Keywords: Cc:
Blocked by: Blocking:

Description (last modified by Michael Häfliger)

https://jsfiddle.net/Haeflimi/dvqvw8gv/35/

When the Datepicker is used with a 2 digit Year Format ( dd.mm.y ) It converts four digit Years (that can be entered in the field manually) In a strange manner.

This doesn't show when picking a date with the picker.

However, when you enter a date manually and you enter a 4 digit year, it gets converted to a 2 digit year in a strange and unexpected manner:

Input: 13.09.2017

Expected Output: 13.09.17

Actual Output: 13.09.20

The main problem here is, that when used in a submitted Form for example, the User probably doesn't even realize that he entered something wrong. Backend validation is still going to pass without complaints. But we end up with wrong data- which is bad.

This does behave the same way in every browser and with every jQuery UI version i've tested it with.

Change History (5)

comment:1 Changed 15 months ago by Michael Häfliger

Description: modified (diff)

comment:2 Changed 15 months ago by Scott González

Owner: set to Michael Häfliger
Status: newpending

You shouldn't expect 13.09.17 as the value since the value that was entered was not valid. I'd suggest using maxLength to prevent the invalid inputs. Unless you have suggestion that doesn't involve magically guessing what format was used, I don't think there's anything for us to do.

comment:3 Changed 15 months ago by Michael Häfliger

Status: pendingnew

I see your Point. The Input is technically invalid.

But it's the datepicker that actually changes/ messes up the user input by doing this semi- validation step of converting a 4 digit Year into a 2 digit Year. My suggestion would be to do it right, or dont do it at all. Either completly validate the field with datepicker and convert the year sensibly. Or don't do it at all and pass along the data as entered. - That way i could at least set up proper validation/ handling for this on the backend.

As for the magical guesswork: I don't think there is guessing involved to fix the 4 Digit to 2 Digit conversion. When somone enters 4 Digits in a place where a Year is expected, we can safely assume that we need to look at the last two digits when we want to save it in a 2 digit Year format. - I can't think of any exceptions here.

Using maxLength to work around this would work i guess. But in a CMS Setting where datepicker is used in some core component this is not that easy fixable.

comment:4 Changed 15 months ago by Michael Häfliger

Any new thoughts on this?

I dove into the code that is handling this. Having a method parseDate() that returns a Date of 01-01-2020 when entering 01.01.2017 seems rather buggy to me in any case.

Although i am not very provicient in JavaSrcript i think i found a way to fix this by just altering one line of Code:

https://github.com/jquery/jquery-ui/blob/master/ui/widgets/datepicker.js#L1175:

Change to:

digits = ( match === "y" && iValue === 4 ? new RegExp( "\\d{" + minSize + "," + size + "}$" ) : new RegExp( "^\\d{" + minSize + "," + size + "}" ) ),

If you are willing to consider merging this i will create a pull request.

comment:5 Changed 15 months ago by Michael Häfliger

As a side Note:

I've tried to implement the maxLenght workaround approach suggested. This doesn't work reliably however. Since there is no maxLenght option in datepicker, i guess you refer to the HTML input tag Attribute that could be applied to the input field.

Here's the problem: You can't reliably tell how long a valid input, using a certain Date Format is going to be.

Take my Example: German Date Format "dd.mm.y" when typed out has 8 Characters like: 01.01.17 So i set maxLenght to 8 and expect that to prevent my users from entering 01.01.2017 and getting 01.01.20

Now a real User comes along and enters 1.1.2017 - this has 8 Characters, so the maxLenght check will allow for it. - But the Datepicker is still going to turn it into 01.01.20

Note: See TracTickets for help on using tickets.