Problem/Motivation
When using a datetime form element that does not allow to input seconds as follow:
$form['datetime_without_seconds'] = [
'#type' => 'datetime',
'#title' => $this->t('Datetime without seconds'),
'#default_value' => new DrupalDateTime(),
'#date_time_element' => 'text',
'#date_time_format' => 'H:i',
];
And submitting the form without changing the value, we get a validation error.
It's caused by the \Drupal\Core\Datetime\Element\Datetime::valueCallback()
method that adds ":00" to times that don't have seconds. The associated comment says "Seconds will be omitted in a post in case there's no entry." so I can't understand why it's been done.
Proposed resolution
Only add that seconds when the time format needs it.
Fix the logic in Datetime:valueCallback() for massaging input values so that DrupalDateTime::createFromFormat() does the actual work based on the format specified by the form element.
Remaining tasks
Task | Novice task? | Contributor instructions | Complete? |
---|---|---|---|
Create a patch | Instructions | Done | |
Update the issue summary | Instructions | Done | |
Add automated tests | Instructions | Done | |
Manually test the patch | Novice | Instructions | |
Review patch to ensure that it fixes the issue, stays within scope, is properly documented, and follows coding standards | Instructions |
User interface changes
None.
API changes
None.
Data model changes
None.
Comment | File | Size | Author |
---|---|---|---|
#64 | Screen Shot 2023-02-03 at 11.40.06 AM.png | 115.18 KB | smustgrave |
#57 | interdiff_53-57.txt | 1.78 KB | raman.b |
#57 | 2723159-57.patch | 6.79 KB | raman.b |
#57 | 2723159-57-test-only.patch | 5.84 KB | raman.b |
#53 | drupal-datetime_form_element_cannot_validate_without_seconds-2723159-53.patch | 6.75 KB | Arrow |
Comments
Comment #2
DuaelFrChanged the proposed solution and updated remaining tasks.
Comment #4
DuaelFrTypo in title
Comment #5
GoZ CreditAttribution: GoZ at Centarro commentedIn this case, you assume everyone will use H:i:s format. Some country could use dot instead of colon. (or another format).
I think the all condition is wrong. Basing on a 5 length is also wrong, this depends of format. If format is 'H : i', strlen will be > 5.
I'm not even sure this condition should be there. If format is H:i:s user should input seconds. If it doesn't, a message is displayed.
If we take care of this specific case, why don't we take care of missing minutes ? (i don't think we should neither)
Sorry to answer review by other questions and put the issue in another way.
Comment #6
DuaelFrThanks for your review @GoZ!
I think you are right that we should not have these lines at all but I also think it has to be handled in a follow-up issue that's probably going to be postponed until D9 to avoid BC break.
The patch I proposed fixes the issue while staying consistent with the existing code that adds ":00" and not ".00" or anything else. I think the condition I added should prevent it from happening when it does not have to.
Could we focus on fixing the actual issue then discuss about removing that entire bit of code? :)
Comment #7
mpdonadioComment #8
DuaelFr@mpdonadio is there something I can do to move this issue forward? Thanks
Comment #9
mpdonadio#8, sorry, I was away this weekend.
This is a head scratcher. I think this is OK, but I want to look at the test in context and see what is going on with the debugger.
I am leaning towards fixing issue issue here, and creating a followup to handle the fact that this is a fragile piece of code that makes some bold assumptions about the time format.
Comment #10
DuaelFrThanks for your answer and your time. (I hope your weekend was as refreshing as mine ^^)
I'll keep following this issue in case you need something.
Comment #11
mpdonadio[Sorry, I found some small revisions to this after I posted.]
Played with this for a while applied...
I'm not sure this is doing what you think it is doing. When `$time_format = 'H;s', then `strrpos('H:i', ':s') === FALSE`, so this final clause will always be FALSE, so the seconds are never appended. In fact, I can remove this `if` and the test passes. DrupalDateTime::createFromFormat() (which essentially calls \DateTime::createFromFormat()), is pretty unforgiving with formats. I'm not sure why that `if()` was there (I added the related issues, but didn't slog through them).
I think it would be safer to check for the "Success" message and that all of the elements have the expected values. Instead of using date(), just hardcode some values so you can explicitly test expectations.
Nit, needs newline.
`'#default_value'` should be NULL. In your submit handler, use `$form_state->setRebuild();` so the submitted values override this. Then you have something to explicitly test against.
Nit, need blank line before final brace. Also in DateFormTest.
Comment #12
mpdonadioNot sure if the test really belong in the datetime.module (maybe system.module would be better), but here is my take on the proper fix and expanded test coverage. The change to the Datetime class is best read applied so you can see it in context of what is going on and why removing that if() statement is OK.
Comment #13
mpdonadioMaybe add something with non traditional separators to make sure this works?
Should check for both the message div and the message itself.
Nit, needs trailing comma after $value.
Oops.
Comment #14
DuaelFrI'm not confident about removing these three lines of code but I trust you.
Here is a patch that fixes the last things from #13.
Comment #16
DuaelFrThese patches introduce a new issue where dates cannot be defined with 00 seconds without getting the following error message:
Comment #17
DuaelFrNow I understand what the comment was saying. I don't know if it's a bug or a feature but Chrome does not send seconds when they are set as "00". Firefox does not seem to do the same. So, if you are using Chrome and sets the time as 17:00:00, Drupal is going to receive 17:00.
Comment #18
mpdonadioSo I guess we are back to the approach in #2?
Reworked the patch to remove the dependency on datetime since this is about the form element. Also aligned it with #2840220: "Date and time" Form API element allows entry beyond min/max values so they will merge better (need to look at these closer for naming).
This can probably still go against 8.2.x since it is a bug, but leaving at 8.3.x for now.
Comment #19
mpdonadioI had already made the patch, but if we should fix this comment before commit to make it more clear what this is really for.
Comment #20
DuaelFrFrom #5:
I don't know what to do with that statement. It seems that the colon-separated format is the international one but we also allow to set a custom format that uses something else. It won't work with the datetime html element but it should work with a standard textfield. Did you already think about that?
Comment #21
mpdonadio#20. Thought about that on was to work this morning. One thought is a comment. Another is something like
to explicitly check for ':s'. Otherwise, I am not really sure how we can make this bulletproof, but am open to ideas.
Comment #22
mpdonadioI wonder if we should also (or instead of) check `'#date_time_element' === 'time'` since it looks like this was a Chrome problem w/ the HTML5 time element? If the input is 'text' then we can use it as-is?
Maybe
is the better change here?
Comment #23
DuaelFrIt looks legit :)
Comment #25
mpdonadioOK, change in #22 and make the test a BTB.
Comment #26
mpdonadioComment #27
jhedstromThe fix is checking explicitly for
time
, but all the tests are usingtext
. That indicates we need more test coverage I think...Comment #28
mpdonadioNice catch.
Comment #29
DuaelFrSee #27 for needed tests.
Comment #30
DuaelFrWrong tag, sorry
Comment #31
juanjesustrigo CreditAttribution: juanjesustrigo at La Drupalera by Emergya commentedI'll work on this
Comment #32
juanjesustrigo CreditAttribution: juanjesustrigo at La Drupalera by Emergya commentedI will not work on this issue any more.
Comment #33
pepegarciag CreditAttribution: pepegarciag at La Drupalera by Emergya commentedI will take this one.
Comment #34
pepegarciag CreditAttribution: pepegarciag at La Drupalera by Emergya commentedAccording to #27 here is a try changing the tests checking for the correct #date_time_element.
Comment #36
mpdonadioOk, I think we are chasing our tail here.
When you use 'date' and 'time' for '#datetime', the formats needs to be 'Y-m-d' and 'H:i:s'. When you use 'text', you can specify your own.
We need to account for that, and Chrome stripping the :00 in both the patch and the test coverage.
Comment #37
pepegarciag CreditAttribution: pepegarciag at La Drupalera by Emergya commentedComment #38
DuaelFr@mpdonadio What do you suggest?
Should we rewrite the entire element to force or ignore format when the type is 'date' or 'time' ?
Comment #39
mpdonadio#38
I think we need to rethink the logic around this change and what we are actually solving. It could just be that we need to update the tests to test both 'text' and 'time', and then simulate what Chrome is going to do. And then document the change better. Need to think about this again.
Comment #40
mpdonadioCan anyone confirm the behavior in #17? I can't in Chrome 57.0.2987.110 on OSX.
Comment #41
DuaelFrI can confirm (Chrome 56.0.2924.87 on Linux)
Comment #42
mpdonadioAwesome.
OK, lets update the test to cover four scenarios:
1. HTML5 time w/ hours, minutes, second in the user input
2. HTML5 time w/ hours, minutes, in the user input (w/ comment that this is simulating Chrome)
3. Text input w/ hours, minutes, seconds in the user input in a H:i:s format
4. Text input w/ hours, minutes in the user input in a non H:i format
That should make sure this works as intended.
Comment #43
tar_inet CreditAttribution: tar_inet as a volunteer commented#42 @mpdonadio I hope these changes cover all needs. I'm not sure if the Chrome comment is in the best possible place, please, could you review it?
Comment #44
mpp CreditAttribution: mpp commentedNote that when using the HTML 5 element, the format is up to the browser but the backend decides to display the error with a format that might be different:
Which may result in a [dd][mm][yyyy] input (HTML5 element) with a warning to enter the date in the [yyyy][mm][dd] format (the date format for the field).
Comment #46
BarisW CreditAttribution: BarisW at LimoenGroen for gemeente Leidschendam-Voorburg commented#44 is exactly my issue. We have a Dutch website, where a date is entered as DD/MM/YYYY, however if a user enters an invalid date, the error message tells the user to enter the date in a YYYY/MM/DD format. Which is impossible due the the formatting of the HTML5 element.
I can't figure out how to localize the html_date value (which is used by the getHtml5DateFormat() callback).
Comment #50
DiDebruPatch #43 worked for me thank ,you.
But the time values in dropdown dont get the right format if I am on a multilingual site with translated formats it will always get the default format.
Correct format in form element.
False format in dropdown.
Comment #51
ArrowRerolled for latest dev
Comment #53
ArrowThe previous failed do to drupal_set_message() being deprecated. This uses the messenger service instead.
Comment #57
raman.b CreditAttribution: raman.b at OpenSense Labs commentedComment #60
hop CreditAttribution: hop commentedModule https://www.drupal.org/project/datetimehideseconds works great.
Comment #64
smustgrave CreditAttribution: smustgrave at Mobomo commentedThis issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. 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.
Using the test case that was added.
Can confirm the issue in question is fixed. When I don't include seconds it auto adds 00
It seems to be fixing but would like to have a followup to update the widget so that the seconds option isn't there.
Comment #65
Deshna Chauhan CreditAttribution: Deshna Chauhan commentedAdded patch against #57 in version 10.1
Comment #66
BramDriesenHiding patch #65 as it's incomplete.
@Deshna Chauhan Please stop uploading incomplete and broken re-roll patches without an interdiff.
Comment #67
apaderno@Deshna When you notice that you patch is 1.66 KB instead of 6.79 KB a previous patch is, you should wonder if your patch does not miss some parts.
It happened to me too, and I learned to first check my patch size, before uploading it.
Comment #68
quietone CreditAttribution: quietone at PreviousNext commented@Deshna Chauhan, I am removing credit for the unhelpful patch per How is credit granted for Drupal core issues.