itchyny / calendar.vim

A calendar application for Vim
MIT License
1.95k stars 72 forks source link

wrong times for events after DST change #142

Open arekfu opened 5 years ago

arekfu commented 5 years ago

I am in the CEST (UTC+2) time zone. We are on Daylight Saving Time until the last Sunday in October, when we will switch to CET (UTC+1). (Google) Calendar events planned after the time switch are shown in CEST time; so, for instance, I have a meeting at 2:00 PM on 5th November which calendar.vim shows at 3:00 PM. I think the event time should rather appear in the time zone which will be in use on that day.

itchyny commented 5 years ago

This is same as #95 and is a known issue. But I'm not planning to support DST switch in the near future, sorry.

arekfu commented 5 years ago

Would you accept a PR about this feature?

rtega commented 1 year ago

The solution to this problem is probably rather simple. You can define timezone as a +/- hour:minute or as "Europe/Amsterdam". The first definition is fixed and doesn't keep track of DST. If you use the second definition google calendar automatically takes care of DST.

As a proof of concept, you can verify with calendar.vim that this works by changing the definition of set_timezone here https://github.com/itchyny/calendar.vim/blob/8d4ab7a8d9120a3538216056047d10df3947789b/autoload/calendar/google/calendar.vim#L591 to the following:

function! s:set_timezone(calendarId, obj) abort
  let a:obj.timeZone = 'Europe/Brussels'
endfunction

Now all changes and additions are done according to DST. This doesn't take care of how the hours in the calendar are shown though. Somewhere (I couldn't find where) this must be changed to the +/-hour:minute-suffix format. As far as I know, google calendar returns the time according to the timezone set in the calendar.

rtega commented 1 year ago

Found where the time is corrected. You could change this line and make timezone (defined +/- hour:minute) dependent one the date and time to be converted: https://github.com/itchyny/calendar.vim/blob/8d4ab7a8d9120a3538216056047d10df3947789b/autoload/calendar/time.vim#L135

From vim v8.1.2326 there is the strptime function that can be used for this: let time_zone = strftime("%z",strptime("%Y-%m-%dT%H:%M%z",a:str))

rtega commented 1 year ago

In short, with this fix you'll probably want to remove this line: https://github.com/itchyny/calendar.vim/blob/8d4ab7a8d9120a3538216056047d10df3947789b/autoload/calendar/setting.vim#L46

and each time calendar#setting#get('time_zone') is invoked check whether it is set. If it's not run time_zone = strftime("%z",strptime("%Y-%m-%dT%H:%M%z",time_string)) or equivalent to check the correct offset according to DST.

rtega commented 1 year ago

Basically not that terribly difficult. You need two changes:

One here: https://github.com/itchyny/calendar.vim/blob/8d4ab7a8d9120a3538216056047d10df3947789b/autoload/calendar/time.vim#L28 change the first two lines in this function

function! calendar#time#time_zone(str) abort
  let time_zone = strftime("%z",strptime("%Y-%m-%dT%H:%M:%S%z",a:str))

and add code to pass the original string from the datetime function. I've attached the changed file. You would probably also have to add code to check that a:str is in the correct format to be read by strptime.

And a oneliner here: https://github.com/itchyny/calendar.vim/blob/8d4ab7a8d9120a3538216056047d10df3947789b/autoload/calendar/google/calendar.vim#L592 into

let timezone = has_key(a:obj,'dateTime') ? strftime("%z",strptime("%Y-%m-%dT%H:%M:%S",a:obj.dateTime)) : has_key(a:obj,'date') ? strftime("%z",strptime("%Y-%m-%d",a:obj.date)) : ''

I would propose that you check first whether calendar#setting#get('time_zone') returns something, if not do the strftime/strptime thing with the passed string. time.vim.gz

rtega commented 1 year ago

Been using this solutions for a month now. It seems to work without any problems.

rionda commented 1 year ago

It would be very cool if we could get this in.

rionda commented 1 year ago

The problem seems more serious than just a matter of display.

I added today (well before DST change) an event in late March (after the DST change for where I am) by pressing i and writing 3/27 10:00-17:00, but the event was added to google as being between 11:00 and 18:00. This seems quite confusing, and certainly would lead to errors...