Problem/Motivation
Datetime field limits are currently hard-coded in Core.
While this may seem helpful to prevent long select lists (#2836054: Allow configuring of datelist year range date_year_range via UI) it's a bug for HTML datepicker input fields, where such a limitation can block valid use-cases, e.g. entering a date < 1900.
Furthermore, years go on and having a hard-coded limit in code is maintenance.
https://git.drupalcode.org/search?search=%23date_year_range&nav_source=n...
Steps to reproduce
- Add a datetime field to an entity type
- Enter a date <= 1899 or >= 2051 and see a form validation error - no way to save the entity
- Find no way to alter these limits in the UI
Proposed resolution
Make the Date and Date Range configurable, to have a MINIMUM and a MAXIMUM allowed date to show in the frontend.
Both fields should support absolute and relative dates.
User should be aware that if using a list (select) widget having list with very many entries can slow down browsers
This will allow custom date intervals like the ones below:
- Show only the dates between last month (Present minus 1 month) and 1 week from now (Present plus 7 days).
- If we wanted to show a date range from 2000 until yesterday we could do that by excluding the current day (Present) because the date for "yesterday" changes everyday.
Use cases:
- In a birthdate field, never show (never allow) dates from the future.
- Allow entering a birthdate < 1900
#2836054: Allow configuring of datelist year range date_year_range via UI already has a related MR!
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
Issue fork drupal-2942828
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
dalra commentedComment #3
mpdonadioNot sure if this falls under the "do-it-all" use case we are trying to avoid in core, but this would be a great addition for DateTime Extras.
Comment #4
dalra commentedThis is actually required by law in the US and in most other countres.
In Europe it is included in the General Data Protection Regulation (GDPR) - Enforcement date: 25 May 2018.
eugdpr.org/gdpr-faqs.html
What about Data Subjects under the age of 16?
Parental consent will be required to process the personal data of children under the age of 16 for online services; member states may legislate for a lower age of consent but this will not be below the age of 13.
So what's this have to do with Drupal date?
We need to make sure we do not allow user registration below the age of 13.
But the date field is not restricted to certain values and allows the user to enter any value.
By allowing that, the site owner is KNOWINGLY BREAKING THE LAW and risking heavy fines (because nothing is stopping children under 13 from registering). Now, any birth date is accepted.
By having the option to set a custom interval, we could create a birth date field like this one:
1970 to (Present minus 13 years)
Only the birth dates in this interval should be selectable (and allowed) by the user in the front-end. It allows the registration of those who are 13 today but it prevents it for those who will be 13 tomorrow.
At the moment, the date range cannot be changed and users can choose dates between 1970 and 2038.
This interval is completely inadequate for most cases.
For example, users now can select 2038 as their year of birth.
Comment #5
dalra commentedComment #6
mpdonadioAge compliance can be implemented in contrib and or in custom code in numerous ways right now. The datetime and daterange elements both have `#date_year_range` attributes that can be added (via alters) where needed (though I think that just sets min/max attributes on the elements. And, adding your own validation functions can also be done with alters.
I am not saying this isn't a useful feature, but I do not see where this becomes a mandatory for Drupal core to implement this feature on all datetime, daterange, and timestamp fields regardless of how they are being used.
Comment #7
dalra commentedWell, if my suggestion with the Present sounds too complicated to be in core, would you agree that at least the option to manually narrow down the date range is needed?
I am talking only about the daterange element here.
I propose to have an option to set a minimum and maximum allowed date because in most cases, the default interval 1970-2038 is too broad.
For example, if we need to collect some dates between 2000 and 2001, it does not make sense to show to the users in the dropdown menu all the years from 1970 to 2038.
Some users will just enter bad data.
I agree that it could be done with a custom module plus validation, but at least this minimum and maximum allowed date instead of 1970 and 2038 would be what most people want.
Comment #8
akmalfikri commentedIs there any temporary solution for this, eg on JS or client side?
Comment #9
michiellucas commentedYou can use this contrib module with the provided patch to configure the year reange
Comment #10
wturrell commented@michiellucas - I'm guessing you meant to link to DateTime Extras?
@akmalfikri - try something like this in a custom module inside a HOOK_form_alter method (match the method to the correct form(s):
$form['field_dob']['widget'][0]['value']['#date_year_range'] = '1930:-13';A slightly annoying thing about `#date_year_range`: while it can do relative dates (as above), you apparently can't reverse the year order by swapping the numbers around? (anecdotally quite a common request, e.g. Date of Birth fields).
I found some code that does this by hooking into template_preprocess_select and grabbing, reversing the array.
Comment #12
berdirYeah, reverse would definitely be very helpful, just landed here as well when searching for an existing issue about that.
+1 on exposing the year range setting in the widget that seems simple enough, don't want to add another contrib module just for that so I'm currently using custom code for that.
Comment #20
mygumbo commentedWhat is the status of getting this into core, please?
Comment #21
pieterdcThanks @wturrell for your hint to @akmalfikri, it has proven to be useful to me as well.
On top of that, I used #3269890: #date_year_range is not validated server-side to enforce the year range on server-side validation (instead of only client-side, via HTML 5).
Comment #23
jaime@gingerrobot.com commentedComment #24
jaime@gingerrobot.com commentedComment #27
anybodyI totally agree with @berdir in #12.
It's a not a good decision and assumption for a popular (not only developer) CMS like Drupal to set a hard-coded date limit in code, which non-developers can not change easily. Having dates outside of that area is absolutely possible!
See https://git.drupalcode.org/search?search=%23date_year_range&nav_source=n...
Some examples:
- Using Drupal for genealogy or other historical dates (< 1900)
- Using Drupal for birthdates (>= today doesn't make sense)
I updated the issue summary and changed this to a Bug report because of the reasons given above.
I see two possible solutions here:
I'd vote for (2) because I think (1) would at least resolve the bug but wouldn't solve the need for a better UX solution at the same time.
Please note the various related issues around.
I adjusted the issue summary accordingly and added the template.
Comment #28
anybodyComment #30
anybodyComment #31
anybodySetting year zero (0) as minimum for the workaround I ran into this: #3585723: #date_year_range does not support years < 1000
Also I think we should allow setting no value for one of both values: #3556851: Deprecated function: preg_match(): Passing null to parameter #2 ($subject)
Comment #32
anybody