- Issue created by @jaroslav ΔervenΓ½
- Status changed to Needs review
almost 2 years ago 6:27pm 5 February 2023 Thank you very much for reporting this issue.
I do not reproduce it on
2.0.x
though.See test in attached screenshot.
Can you please try again using the dev branch?
FYI I'm working on a new version and will publish a new release soon.
- Status changed to Postponed: needs info
over 1 year ago 7:21pm 23 March 2023 Marking this issue as Postponed as I cannot reproduce it.
Feel free to reopen it with further details if you encounter the same issue.
- πΊπ¦Ukraine tfrajj
Looks like the issue is reproducible when:
- Field settings Date type is All Day
- Storage timezone and user timezone are different
- π©π°Denmark robotjox
same problem for me. All day events using date range are offset by 2 hours.
- Assigned to matthieuscarset
- Status changed to Needs work
over 1 year ago 10:44pm 20 May 2023 Thanks for reporting the issue again.
There is certainly something missing with the timezone when it comes to preprocessing the view results.
Assigning this issue to me and working on it.
-
matthieuscarset β
committed 767b8310 on 2.1.x
Use users' timezone to populate calendars #3339333
-
matthieuscarset β
committed 767b8310 on 2.1.x
- π¨π¦Canada sdsheridan Toronto
This may be related. I'm using date range field, and it would appear that the calendar is using the underlying UTC times (as stored in the database for date range values), and not converting them to the timezone selected for the calendar (specifically set to Toronto), not to the site's time (also Toronto) in the absence of the calendar's timezone, nor the user's timezone (also set to Toronto). So looks to me like the module is missing some time-zone adjustment for the start and end time values.
Not sure where this is best remedied, as it seems to be affecting both how the span box is drawn, as well as the title attribute of the node title link (both using the UTC dates).
However, the hierarchy should probably be something like:
if ( calendar timezone is set ) { adjust dates based on calendar timezone offset; } elseif ( user timezone is set ) { adjust dates based on user's timezone offset; } elseif ( site timezone is set ) { adjust dates based on site's timezone offset; }
shawn
- π¨π¦Canada sdsheridan Toronto
Just following up, looks like there might be three places that need adjustments:
- You might want to create a method in class
CalendarViewBase
that established the timezone to use as per the above. - Use that method in function
getRowValues
when setting the $values{'title'] at the end of the function to pass to the$this->dateFormatter->format(...)
calls. - Looks like the last spot might be the
populateCalendar
method, where the computation of$start_day
and$end_day
would need to be adjusted for the same timezone offset as above.
Hope that helps!
shawn
- You might want to create a method in class
- π¨π¦Canada sdsheridan Toronto
So as a follow up to my follow-up, I tried the above, and for some reason the
dateFormatter->format(...)
is ignoring the timezone / not making an adjustment for the timezone offset; not sure why. So I hacked this temporarily to add the offset to the timestamps ingetRowValues()
. The title and rendering are not showing correctly in the calendar with this hack.shawn
The title and rendering are not showing correctly in the calendar with this hack.
Did you mean title and rendering are now showing correctly? If yes, could you please share your diff?
- π¨π¦Canada sdsheridan Toronto
Whoops! Yes, that should have been "...are now showing correctly...".
I'll try to generate a diff, but in the meantime, here's what I did (both in src/Plugin/views/style/CalendarViewBase.php):
1. Created a new helper functiongetTImeZone
that i placed right beforegetRowValues
:/** * Helper function to determine what timezone to use if formatting and start- * and end-date rendering determination. * * @param EntityField $field The date field being used. * @return string The timezone string. */ public function getTimeZone(EntityField $field) { $timezone = 'UTC'; if ( !empty($field->options['settings']['timezone_override']) ) { $timezone = $field->options['settings']['timezone_override']; } elseif ( ( $user_timezone = \Drupal::currentUser()->getTimeZone() ) && !empty($user_timezone) ) { $timezone = $user_timezone; } elseif ( ( $system_timezone = \Drupal::config('system.date')->get('timezone')['default'] ) && !empty($system_timezone) ) { $timezone = $system_timezone; } $tz = new \DateTimeZone($timezone); $time_now = new \DateTime('now', $tz); $offset = $tz->getOffset($time_now); return ['timezone' => $timezone, 'offset' => $offset]; }
2. Modified the getRowValues function to use the new timezone function as follows:
/** * Get the value out of a view Result for a given date field. * * @param \Drupal\views\ResultRow $result * A given view result. * @param \Drupal\views\Plugin\views\field\EntityField $field * A given date field. * * @return array * Either the timestamp or nothing. */ public function getRowValues(ResultRow $row, EntityField $field) { $delta = 0; if ($delta_field = $field->aliases['delta'] ?? NULL) { $delta = $row->{$delta_field} ?? 0; } // Get the result we need from the entity. $this->view->row_index = $row->index ?? 0; $items = $field->getItems($row) ?? []; $item = $items[$delta]['raw'] ?? $items[0]['raw'] ?? NULL; $values = $item instanceof FieldItemInterface ? $item->getValue() : []; unset($this->view->row_index); // Skip empty fields. if (empty($values) || empty($values['value'])) { return []; } $timezone = $this->getTimeZone($field); // PATCHED to adjust timezone. // Make sure values are timestamps. $values['value'] = $this->ensureTimestampValue($values['value']) + $timezone['offset']; // PATCHED to add timezone offset to UTC value. $values['end_value'] = ( $this->ensureTimestampValue($values['end_value'] ?? $values['value']) ) + $timezone['offset']; // PATCHED to add timezone offset to UTC value. // Get first item value to reorder multiday events in cells. $all_values = $field->getValue($row); $all_values = \is_array($all_values) ? $all_values : [$all_values]; $values['first_instance'] = reset($all_values); // Expose the date field if other modules need it in preprocess. $config = $field->configuration ?? []; $field_id = $config['field_name'] ?? $config['entity field'] ?? $config['id'] ?? NULL; $values['field'] = $field_id; // Get a unique identifier for this event. /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ $entity = $field->getEntity($row); $key = $entity->getEntityTypeId() . ':' . $entity->id() . ':' . $field_id; $values['hash'] = md5($key . $delta); // Prepare a title by default (e.g. on hover). $start = $values['value']; $end = $values['end_value'] ?? $start; $title_string = $start && ($start !== $end) ? '@title from @start to @end' : '@field: @title @date'; $values['title'] = $this->t($title_string, [ '@field' => $field->label(), '@title' => $entity->label(), '@date' => $this->dateFormatter->format($start, 'long', '', $timezone['timezone']), // PATCHED - even though passed the timezone to dateFormatter, '@start' => $this->dateFormatter->format($start, 'short', '', $timezone['timezone']), // seemed to make no diff until adjusted for the offset above, '@end' => $this->dateFormatter->format($end, 'short', '', $timezone['timezone']), // so these could probably return to the way they were. ]); return $values; }
Will try the dev version when i get a chance. Pushing to get this project to beta right now, so hopefully after that.
shawn
- πΊπΈUnited States hockey2112
Any word on this? I am experiencing the same thing with multi-day fields stretching into an extra day.
- πΊπΈUnited States jwineichen
I've attempted to put this change into a patch. First time but I've tried to follow the patching documentation, so I think it's correct. It seems to be working on my local.
Just here to report that I have used the patch on #14 and it seems to correct the same issue for me.
- @matthieuscarset opened merge request.
-
matthieuscarset β
committed 308ca93a on 2.1.x
Issue #3339333: Date range - offset one day
-
matthieuscarset β
committed 308ca93a on 2.1.x
- Status changed to Needs review
over 1 year ago 10:10am 15 September 2023 Thanks a lot once again for reporting this issue and for providing patches.
The fix is merged on
2.1.x
.Marking this issue as NEED REVIEW so please, test the
2.1.x-dev
branch and let me know if it fix your situations.I'll then release a new version.
Looking forward to hearing from you.
- Issue was unassigned.
I'm actually trying to troubleshoot an issue which I do not think is related to this patch. But since I was using 2.1.1 and updated with the patch to 2.1.3, I am not sure where the problem is coming from...
When I am logged in, I do not see the events, but when I log out, everything is fine...
I'll start by trying the dev branch and see if it resolves the issue.
Ok, so far I've tried the dev branch and the problem persists. I rolled back to 2.1.1 ensured the events were showing as expected, then updated to 2.1.2 and the events are gone while I'm logged in, and back when I'm logged out. If anyone has any ideas on what I can try, please let me know, but I'm going through the code diff and seeing if I can spot the issue.
Also, I'm guessing this should be a new issue at this point since the patch seems to be unrelated.
Heh... don't mind me, I seem to have had some weird caching glitch somewhere... all of a sudden I was able to see the events again... All is good on the dev branch.
- Status changed to Fixed
over 1 year ago 3:42pm 15 September 2023 Thank you for testing.
Marking as fixed!
Release coming soon.
Automatically closed - issue fixed for 2 weeks with no activity.
- Status changed to Fixed
about 1 year ago 3:29pm 22 October 2023 - π¨π¦Canada sdsheridan Toronto
It would seem we're not quite there yet. Just downloaded the latest release, and we have an offset problem in the bubble. There's an error in the logic in CalendarViewBase::getRowValues(). In particular, this bit of code:
// Get offset to fix start/end datetime values. $timezone = $this->getTimezone($field); $same_tz = date_default_timezone_get() == $timezone; $offset = $same_tz ? 0 : $this->getTimezoneOffset('now', $timezone); $values['value'] += $offset; $values['end_value'] += $offset;
If the site's timezone is anything other than UTC, and the field's timezone is the same as the site's timezone (which will often be the case), then the offset will be zero, and the start and end values will not be modified. However, the start and end values are in UTC (that's how they're stored in the DB), not in the site's or the field's timezones (unless they're UTC), and so the start and end values remain UTC, not those of the site or field's timezones.
For example (i.e., how to replicate this), my php.ini timezone is America/Toronto, as is my site's timezone, and the calendar and field use the default timezone (i.e., no timezone specified, to they fall back to the site's timezone). So
date_default_timezone_get()
will return "America/Toronto", as will$this->getTimezone($field)
, resulting in a zero offset, and leaving the bubble/title start and end times in GMT, even though they should be adjusted for the offset to Toronto time.So, I think the test for same timezone should be removed, and the offset should simply be computed. Thus, the above code should be:
// Get offset to fix start/end datetime values. $timezone = $this->getTimezone($field); $offset = $this->getTimezoneOffset('now', $timezone); $values['value'] += $offset; $values['end_value'] += $offset;
What's interesting is that the text of the displayed calendar item does have the correct date/time value(s), including after this change. I've not taken the time to hunt down why that is, but I assume the rendering of the item is handling the timezone offset properly (views and some other module rendering the "When" field independent of this function call), and not using the values from this function call.
shawn
- Status changed to Active
about 1 year ago 5:09am 23 October 2023 - πΊπΈUnited States GBlicharz
I tried the changes suggested in #25 π Date range - offset one day Needs review using the latest version of this module (v2.1.6), and it solved the offset by one day issue we were having. I have not written a patch before, and it's unclear to me how the suggested changes would work along side the changes in this branch (3339333).
-
matthieuscarset β
committed 5b2757c8 on 2.1.x
fix: Offset one day caused by timezone #3339333
-
matthieuscarset β
committed 5b2757c8 on 2.1.x
- π¨π¦Canada ciesinsg
Is there any work around for this issue while we wait for a patch/update?
Regarding #27 π Date range - offset one day Needs review , unfortunately I don't know how to make a patch for this either, but hopefully someone sees your comment and gives some input on how this can be done.
- Status changed to Needs review
about 1 year ago 2:06pm 30 November 2023 Thanks a lot to you all for your contribution and efforts. Sorry for the inconvenience
There is a new release 2.1.7 β which should fix this bug.
Please test/review and let me know!
- Status changed to Active
about 1 year ago 5:32pm 30 November 2023 - πΊπΈUnited States GBlicharz
I confirmed that version 2.1.7 solved the issue we had been seeing. Thank you!
- Status changed to Fixed
about 1 year ago 5:58am 1 December 2023 Automatically closed - issue fixed for 2 weeks with no activity.