Problem/Motivation
As originally reported in #2900251: "Date and time" Form API element allows to type 6 digit year component, The core date Form API element (and therefore, field widgets) allows values that don't match the min/max settings for the field.
This can lead to problems, such as users being able to enter more than 4 digits for the year. It should be limited to 4 digits.
Root cause
An empty "Date" field loads with no min/max year set.
\lib\Drupal\Core\Datetime\Element\Datetime::processDatetime() has this comment:
* Optional properties include: * - #date_year_range: A description of the range of years to allow, like * '1900:2050', '-3:+3' or '2000:+3', where the first value describes the * earliest year and the second the latest year in the range. A year * in either position means that specific year. A +/- value describes a * dynamic value that is that many years earlier or later than the current * year at the time the form is displayed. Used in jQueryUI datepicker year * range and HTML5 min/max date settings. Defaults to '1900:2050'.
When this element loads and is empty / doesn't have a defaul value this section of code is never hit:
// Adds the HTML5 date attributes.
if ($date instanceof DrupalDateTime && !$date->hasErrors()) {
$html5_min = clone($date);
$range = static::datetimeRangeYears($element['#date_year_range'], $date);
$html5_min->setDate($range[0], 1, 1)->setTime(0, 0, 0);
$html5_max = clone($date);
$html5_max->setDate($range[1], 12, 31)->setTime(23, 59, 59);
$extra_attributes += array(
'min' => $html5_min->format($date_format, $format_settings),
'max' => $html5_max->format($date_format, $format_settings),
);
}
Date fields that have a value may set min max year to unwanted values
When the value of a date is set either via the default value or a saved date then the max min is calculated and set. This defaults to 1900-2050 (hard coded). However if the field year is set to a time before 1900 or above 2050 then this date is used _forever_ as the max or min value of that field. For example:

I can enter 1776-07-04 as a date in an empty element, and then this year gets used as the min year on the element instead of the range defined on the element (which is by design per a comment in DateElementBase::datetimeRangeYears()), but then you cant edit the year to be less than this (E.g. 1775) ever again. Same goes if you set the date to 2060 you can't then set it to 2062 (And worse there is no error shown on Chrome for this situation, it just silently fails).
Proposed resolution
- Add the date_range_yearsconfiguration setting to the field edit form
- If there is no data in this fields storage default to the current settings for date_range_years (1900-2050)
- If there is data in this fields storage default to blank (?) for backwards capacitity
- Allow the date_range_years config setting to be modified, validated and saved for this field
- Add a description to the date_range_years field that if the field is left blank it will not add max-min to field at all
- Perhaps this ticket covers some of that work? https://www.drupal.org/project/drupal/issues/2836054
- The form element on the form display, If date_range_years is not empty should:
- Use the date_range_years setting saved in the config.
- Add the min/max elements even when the value on the element is empty.
- Update code/docs to explain the new features when '#date_year_range' === NULL?
- Show an error when the max value is exceeded (is this from the browser?)
- Validate the date/range year submission from the widget [3269890]
Remaining tasks
- Fix up patch of deprecation
- Review
- Commit
User interface changes
NA
API changes
NA
Data model changes
NA
| Comment | File | Size | Author |
|---|---|---|---|
| #63 | After Patch.png | 14.45 KB | prasanth_kp |
| #37 | 2840220-37.patch | 2.71 KB | smustgrave |
| #37 | interdiff-35-37.txt | 5.1 KB | smustgrave |
| #37 | 2840220-37-tests-only.patch | 1.44 KB | smustgrave |
Comments
Comment #2
mpdonadioI am a little worried about BC beyond the field widgets, too, for those using just the form elements. I'll post a test-only patch that demonstrates these problems sometime soon.
Comment #3
mpdonadioDemo to demonstrate the problem. Left this in WTB b/c that is where all of the other element tests are right now.
Comment #6
mpdonadioThoughts?
Comment #10
osab commentedhttps://www.drupal.org/files/issues/2840220-06.patch - didn't help me (D8.4.5, php7.1)
I checked Data and Data range fields.
Comment #12
zimphire commentedRerolled https://www.drupal.org/files/issues/2840220-06.patch for Drupal 8.6.x.
Comment #13
zimphire commentedNow for an actual git patch. Sorry :(
Comment #15
matsbla commentedI tested patch in #13, but I still experience the problem.
I have a datefield filter in views and I've pre-set the deafult value to: '1830-01-01 00:00:00'
I then apply the patch, run cron and clear cache.
Still, after, I get min="1830-01-01" inside my input element.
Comment #16
matsbla commentedComment #17
mpdonadioOk, reroll to convert the test to BTB.
Comment #19
jhedstromJust some tiny nits and a question/comment below.
Nit: needs short array syntax
This shouldn't be necessary as it's the same as the one declared by
BrowserTestBase.It's not clear to me where these ranges are coming from, and how they are being set in
FormTestDatetimeForm. Can some clarifying comments be added either to the form class or to the test itself?Tiny nit: Can you spell out within here?
Comment #20
cainaruWe just ran into this issue. A student accidentally entered 10/01/1850 instead of 10/01/1848 and saved the node. The student then tried to edit the node again to correct the date, but received an error stating "Value must be greater than or equal to 1850-01-01" or "Value must be 01/01/1850 or later" (see images below).
We haven't applied the patch from #17 yet, but the following work-around was successful (in case anyone reading this is unable to apply the patch yet but needs some sort of temporary solution):
Comment #21
cainaruComment #28
smustgrave commentedBelieve this is a duplicate of https://www.drupal.org/project/drupal/issues/2900251 anyone willing to confirm?
Comment #29
scottop commentedNo, this is a different issue.
There is a workaround— add the Datetime Extras module. The problem is not in the data, but in the validation that the entry form imposes. The Datetime Extras module allows you to set the allowable date range for a valid entry, instead of getting the HTML 4 default 0f 1900–2050.
Comment #30
smustgrave commentedFor #19
Comment #31
ravi.shankar commentedAddressed point 1, 2 and 4 of comments #19, still needs work for point number 3 of comment #19.
Comment #32
smustgrave commentedIgnoring #31 because of the deprecation errors.
Regarding #19.3 Also not understanding where the data ranges are coming from.
Also the solution here looks pretty similar to https://www.drupal.org/project/drupal/issues/2900251 which is currently marked RTBC.
So if https://www.drupal.org/project/drupal/issues/2900251 isn't addressing this issue maybe this is postponed until that is merged?
Also needs an IS update to be more clear.
Comment #33
ravi.shankar commentedTrying to fix tests of patch #31 and fixed Drupal CS issues.
Comment #34
ravi.shankar commentedFixed failed tests of patch #33 and added test only patch this might help.
Still needs work for #32.
Comment #35
smustgrave commentedUpdated the IS slightly about what's left todo.
Finally figured out the dates.
First set are from when the tests were created initially
Second set I think is around US. 1776 at least is. But it's before the min 1900
Third set I believe is just a random set after 2050
Comment #36
smustgrave commentedTests need to be refined
Comment #37
smustgrave commentedBefore the tests get worked on how exactly is this suppose to work?
I added a date field to a content type and min/max gets set to 1900-01-01 and 2050-12-31 with this patch. Previously it was getting no min or max.
How am I suppose to set a 1756 time? Is that covered in https://www.drupal.org/project/drupal/issues/2942828
Pulling the tests from https://www.drupal.org/project/drupal/issues/290025 to test the min/max variable at least.
Removing the old ones until
Comment #38
smustgrave commentedComment #52
quietone commentedsmustgrave closed #2900251: "Date and time" Form API element allows to type 6 digit year component as a duplicate. I have added it as a related issue and I am moving credit.
Comment #53
quietone commentedThis could use an issue title update. What 'buggy' behavior is being fixed here?
Comment #54
smustgrave commented@quietone what about "Datetime missing min/max attributes"
This issue fixes a problem where min and max attributes were not be added to the date field.
The original issue talks about this but I don't know how they set that up with this patch.
Any suggestion on how best to proceed?
Comment #56
jaime@gingerrobot.com commentedComment #57
jaime@gingerrobot.com commentedComment #58
jaime@gingerrobot.com commentedComment #59
jaime@gingerrobot.com commentedComment #60
jaime@gingerrobot.com commentedComment #61
jaime@gingerrobot.com commentedComment #62
gaurav-mathur commentedThis issue is already resolve in the latest version , Adding screenshot.
Thankyou
Comment #63
prasanth_kp commented#37 Patch Applied on 10.1.x-dev and it fixes the issue.
Comment #64
mark_fullmerComment #65
mark_fullmerI've updated the title to capture the bugginess:
"Date and time" Form API element allows entry beyond min/max valuesComment #66
feyp commentedThis issue is being reviewed by the kind folks in Slack, #need-reveiw-queue. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.
Looking at the proposed resolution in the issue summary, it seems that the patch only implements the "Add the min/max elements even when the value on the element is empty." part. All the rest is missing, which is a lot. So this is very far from ready, unfortunately.
If this change breaks the functionality of the date field for working with dates outside the default range, then I think we also can't just rescope this issue and do the rest in a follow-up. We must at least ensure that people who use the field with existing data outside of the default range can still use the date field until the follow-up is implemented.
The issue linked from the top of the issue summary mentions that it is annoying for editors when they accidentally enter a 6 digit year instead of entering a 4 digit year and then the first 2 digits of the next date component. I tested the patch in both current Firefox and Chromium on Linux and although min and max are now set to the default date range, I can still enter 6 digit years. Only when I then try to submit the form, instead of getting an error from Form API about the required date format, I now get a browser validation error (which will also enforce that the date is within the date range specified). I'm not sure how to fix this, maybe this would need some Javascript?
I would also suggest to use an ordered list instead of an unordered list for the proposed resolution in the issue summary, as that will make it easier to refer to individual items in comments.
Comment #68
Dimm commentedhttps://www.drupal.org/project/datetime_more
The "Datetime More Widget" module allows the user to independently specify the minimum and maximum year 0001-9999.