Problem/Motivation
The DrupalDateTime constructor takes $time as a parameter. It's defined as follows:
* @param string $time
* A DateTime object, a date/input_time_adjusted string, a unix timestamp.
* Defaults to 'now'.
Inside the constructor it calls its parent, which goes to the DateTimePlus constructor. That too takes a $time parameter. However, it's defined more strict:
* @param string $time
* (optional) A date/time string. Defaults to 'now'.
So when creating a DrupalDateTime object with a \DateTime (which should be fine according to the docs), you get the following warning:
Warning: date_parse() expects parameter 1 to be string, object given in Drupal\Component\Datetime\DateTimePlus->__construct() (line 257 of /var/www/html/core/lib/Drupal/Component/Datetime/DateTimePlus.php).
Proposed resolution
Update DrupalDateTime constructor to accept \DateTime, strings, and timestamps, per the documentation.
Add test coverage for the constructor.
Remaining tasks
Update constructor.
Add test coverage.
User interface changes
None.
API changes
None, the docblock had the API described but the implementation was incorrect.
Data model changes
None.
Why this should be an RC target
From #6:
Adding rc target triage. This isn't Critical or Major, but it does identify some test holes and may lead to some followup issues that add missing test coverage.
Comment | File | Size | Author |
---|---|---|---|
#21 | drupaldatetime-2596043-21.patch | 2.4 KB | mpdonadio |
#11 | 2596043_11.png | 131.74 KB | Anonymous (not verified) |
#10 | interdiff-03-10.txt | 2.61 KB | mpdonadio |
#10 | 2596043-10.patch | 2.89 KB | mpdonadio |
#4 | 2596043-03.patch | 2.71 KB | mpdonadio |
Comments
Comment #1
Anonymous (not verified) CreditAttribution: Anonymous at XIO commentedpjonckiere created an issue. See original summary.
Comment #2
Anonymous (not verified) CreditAttribution: Anonymous at XIO commentedDateHelper does this a couple of times, in DateHelper::daysInYear() for example, thus making it unusable. This is not reported by our automated tests, so we are missing coverage for both DateTimePlus and DateHelper.
I think the DateHelper issues deserve their own tickets, but I thought that it might be useful to know before deciding on what to do here.
Comment #3
mpdonadioWorking on something...
Comment #4
mpdonadioThere are some subtleties with the way the PHP \DateTime object works with timezones, so this needs careful examination.
Comment #6
mpdonadioAdding rc target triage. This isn't Critical or Major, but it does identify some test holes and may lead to some followup issues that add missing test coverage.
Comment #7
mpdonadioComment #8
Anonymous (not verified) CreditAttribution: Anonymous at XIO commentedI manually checked my use case again, and this fixes my problem. Also the test coverage seems solid for the issue at hand, so that's great as well. Thanks!
Is there a reason in particular why you don't pass $timezone here? According to the test it works as expected, but I'm not really sure why. If it doesn't make sense to use a timestamp/timezone combination, I think it should be documented somewhere. It might be out of scope here though.
This will need to be removed.
Comment #9
mpdonadioI'll fix #8 tonight.
Re the first comment, this was the subtleties of DateTime::__construct:
The definition of UNIX timestamps are seconds since 1 January 1970 UTC, so the timezone is implicit.
That is also why the format strings exclude the timezone upon creation and use the $timezone parameter.
I am not 100% convinced this is the best long term solution; there may a better way to handle the timezone, but that would entail messing with the way DateTimePlus works (but thankfully I think the test coverage on that is pretty good).
Comment #10
mpdonadioI kinda of retract my statements in #9. I think this patch is better, but I want a second set of eyes to look at this to make sure we aren't masking a timezone handling problem somewhere else in the code.
Comment #11
Anonymous (not verified) CreditAttribution: Anonymous at XIO commentedThe options aren't endless, so I just tried them all. That would be 'now', a string, a \DateTime() and a timestamp, and that always combined with no timezone, a string or a \DateTimeZone. See the results in the screenshot attached.
Europe/Brussels is my default timezone, which is +1:00 and Australia/Perth is +8:00. So I think this result is what we expect. When nothing is defined it chooses my default timezone, and when something is defined it chooses the timezone as specified. The one exception being the timestamp with no declaration of a timezone, which implicitly is UTC.
The only thing I do want to point out, is that currently every DrupalDateTime has a timezone with a readable name, except when defining it as a timestamp without timezone. I don't think it would have any technical consequences since the getTimeZone() will give back the "+00:00" one, but it might be good to explicitly define something to have more consistency in the rendering of DrupalDateTime objects. I guess that's more of a choice in design.
Edit: removed the embedded image since it came out a bit large
Comment #12
mpdonadio#11, so do you think this is RTBC? What you are describing with timestamps sound more like a followup and not a fix for the bug that was identified?
Comment #13
Anonymous (not verified) CreditAttribution: Anonymous at XIO commentedOh yes, indeed. Looks good to me!
Comment #16
Anonymous (not verified) CreditAttribution: Anonymous at XIO commentedSeems like that was a random test failure.
Comment #18
xjmAdding the proposed reason to make this an RC target to the summary.
Comment #19
alexpottDiscussed with @catch, @xjm, @effulgentsia and we think that we should just change the documentation on the constructor to match the parent class since it already has the ::createFromDateTime() method. Therefore this just becomes a docs fix and is rc eligible
Comment #20
alexpottFor #19
Comment #21
mpdonadioOK, here is a doc-only fix.
Comment #22
mpdonadioREDACTED
Comment #23
mpdonadioTime to put away the computer for the day. Ignore #22. This can be reviewed.
Comment #25
Anonymous (not verified) CreditAttribution: Anonymous at XIO commentedI double checked that the DateHelper methods work with DrupalDateTime, and they do. This will at least take away possible confusion, so let's get it in.
I do think we should add the fix from #10 in a later version.
Comment #27
alexpottI'm not convinced that #10 will really be necessary.
Committed 8a3e98e and pushed to 8.0.x. Thanks!
Comment #29
alexpottThe reason I think #10 will probably be unnecessary is that magical constructors that do different things depending on argument type are tricky beasts to review and code with.