From 112b174e5fad5417a0083eca35c75e01751c4858 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Thu, 31 Aug 2017 17:32:04 +0200 Subject: [PATCH 1/4] [bug] invalid time for reccurent events after Daylight Saving Time change --- app/helpers/application_helper.rb | 12 ++++++++++++ app/models/event.rb | 3 +++ 2 files changed, 15 insertions(+) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index ae40ef803..445acf540 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -80,6 +80,18 @@ module ApplicationHelper nil end + ## + # Apply a correction for a future DateTime due to change in Daylight Saving Time (DST) period + # @param datetime {DateTime} + # Inspired by https://stackoverflow.com/a/12065605 + ## + def dst_correction(datetime) + datetime = datetime.in_time_zone(Time.zone.tzinfo.name) + datetime = datetime - 1.hour if datetime.dst? && !Time.now.dst? + datetime = datetime + 1.hour if Time.now.dst? && !datetime.dst? + datetime + end + private ## inspired by gems/actionview-4.2.5/lib/action_view/helpers/translation_helper.rb diff --git a/app/models/event.rb b/app/models/event.rb index 4c9e28395..7d0678171 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -1,5 +1,6 @@ class Event < ActiveRecord::Base include NotifyWith::NotificationAttachedObject + include ApplicationHelper has_one :event_image, as: :viewable, dependent: :destroy accepts_nested_attributes_for :event_image, allow_destroy: true @@ -87,8 +88,10 @@ class Event < ActiveRecord::Base r.events.each do |date| days_diff = availability.end_at.day - availability.start_at.day start_at = DateTime.new(date.year, date.month, date.day, availability.start_at.hour, availability.start_at.min, availability.start_at.sec, availability.start_at.zone) + start_at = dst_correction(start_at) end_date = date + days_diff.days end_at = DateTime.new(end_date.year, end_date.month, end_date.day, availability.end_at.hour, availability.end_at.min, availability.end_at.sec, availability.end_at.zone) + end_at = dst_correction(end_at) if event_image ei = EventImage.new(attachment: event_image.attachment) end From 31cdc5c695b48118590ff6a9c587b639584e1e00 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 4 Sep 2017 16:50:07 +0200 Subject: [PATCH 2/4] [bug] reccursive events have difference with requested time when crossing DST (#77) --- app/helpers/application_helper.rb | 11 ++++++----- app/models/event.rb | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 445acf540..6f941cced 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -82,14 +82,15 @@ module ApplicationHelper ## # Apply a correction for a future DateTime due to change in Daylight Saving Time (DST) period + # @param reference {ActiveSupport::TimeWithZone} # @param datetime {DateTime} # Inspired by https://stackoverflow.com/a/12065605 ## - def dst_correction(datetime) - datetime = datetime.in_time_zone(Time.zone.tzinfo.name) - datetime = datetime - 1.hour if datetime.dst? && !Time.now.dst? - datetime = datetime + 1.hour if Time.now.dst? && !datetime.dst? - datetime + def dst_correction(reference, datetime) + res = datetime.in_time_zone(reference.time_zone.tzinfo.name) + res = res - 1.hour if res.dst? && !reference.dst? + res = res + 1.hour if reference.dst? && !res.dst? + res end diff --git a/app/models/event.rb b/app/models/event.rb index 7d0678171..6ad394788 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -88,10 +88,10 @@ class Event < ActiveRecord::Base r.events.each do |date| days_diff = availability.end_at.day - availability.start_at.day start_at = DateTime.new(date.year, date.month, date.day, availability.start_at.hour, availability.start_at.min, availability.start_at.sec, availability.start_at.zone) - start_at = dst_correction(start_at) + start_at = dst_correction(availability.start_at,start_at) end_date = date + days_diff.days end_at = DateTime.new(end_date.year, end_date.month, end_date.day, availability.end_at.hour, availability.end_at.min, availability.end_at.sec, availability.end_at.zone) - end_at = dst_correction(end_at) + end_at = dst_correction(availability.start_at,end_at) if event_image ei = EventImage.new(attachment: event_image.attachment) end From 1af07f5e549e7eede8cb446b152916e55a54d00d Mon Sep 17 00:00:00 2001 From: Sylvain Date: Mon, 4 Sep 2017 17:27:18 +0200 Subject: [PATCH 3/4] [ongoing] rake task to fix existing recursive events --- CHANGELOG.md | 1 + lib/tasks/fablab/fix.rake | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d45d77edf..7ea9b56b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - Updated puma for compatibility with openSSL > 1.0 - Documented installation on ArchLinux - [TODO DEPLOY] `rake db:seed` then `rake fablab:fix:migrate_admins_group` +- [TODO DEPLAY] `rake fablab:fix:recursive_events_over_DST` ## v2.5.10 2017 August 16 diff --git a/lib/tasks/fablab/fix.rake b/lib/tasks/fablab/fix.rake index 23eaa049b..252563302 100644 --- a/lib/tasks/fablab/fix.rake +++ b/lib/tasks/fablab/fix.rake @@ -57,5 +57,20 @@ namespace :fablab do end end end + + task recursive_events_over_DST: :environment do + #TODO intensive testing before release + include ApplicationHelper + groups = Event.group(:recurrence_id).count + groups.keys.each do |recurrent_event_id| + initial_event = Event.find(recurrent_event_id) + Event.where(recurrence_id: recurrent_event_id).where.not(id: recurrent_event_id).each do |event| + availability = event.availability + availability.start_at = dst_correction(initial_event.availability.start_at, availability.start_at) + availability.end_at = dst_correction(initial_event.availability.end_at, availability.end_at) + availability.save! + end + end + end end end From 9f136b479a5e44eaf398d5b5d826b133cb31ff41 Mon Sep 17 00:00:00 2001 From: Sylvain Date: Tue, 5 Sep 2017 10:36:49 +0200 Subject: [PATCH 4/4] rake task to fix existing recursive events --- lib/tasks/fablab/fix.rake | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/tasks/fablab/fix.rake b/lib/tasks/fablab/fix.rake index 252563302..a213fe79d 100644 --- a/lib/tasks/fablab/fix.rake +++ b/lib/tasks/fablab/fix.rake @@ -59,16 +59,17 @@ namespace :fablab do end task recursive_events_over_DST: :environment do - #TODO intensive testing before release include ApplicationHelper groups = Event.group(:recurrence_id).count groups.keys.each do |recurrent_event_id| initial_event = Event.find(recurrent_event_id) Event.where(recurrence_id: recurrent_event_id).where.not(id: recurrent_event_id).each do |event| availability = event.availability - availability.start_at = dst_correction(initial_event.availability.start_at, availability.start_at) - availability.end_at = dst_correction(initial_event.availability.end_at, availability.end_at) - availability.save! + if initial_event.availability.start_at.hour != availability.start_at.hour + availability.start_at = dst_correction(initial_event.availability.start_at, availability.start_at) + availability.end_at = dst_correction(initial_event.availability.end_at, availability.end_at) + availability.save! + end end end end