Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Daylight saving hours in Golang

Tags:

dst

go

I have been designing a UI for a scheduling interface, where a user can set timers a number of hours into the future. I want to be able to handle daylight saving if possible, I thought it would be quite simple. Whilst checking out time.Time in the golang packages I ran into the following inconsistency, if that is what it is.

package main

import (
   "fmt"
   "time"
)

    func main(){
        const timeFormat = "2 Jan, 2006 3:04pm (MST)"
        test , err := time.Parse( timeFormat, "25 Oct, 2015 1:59am (BST)" )
        fmt.Println( test , test.UTC() , err)
        dur , _ := time.ParseDuration( "1m" )
        test = test.Add( dur )
        fmt.Println( test , test.UTC())

        fmt.Println( "--------------------"  )

        test , err = time.Parse( timeFormat, "25 Oct, 2015 2:01am (BST)" )
        fmt.Println( test , test.UTC() , err)
        test = test.Add( dur )
        fmt.Println( test , test.UTC())

        test = test.Sub( dur )
        fmt.Println( test , test.UTC())
     }   

I know that 2am on the 25 Oct 2015 in BST will should cause the clock to go back to 1am GMT (UTC). If I increment 1:59am BST by one minute the time does indeed switch to GMT.

2015-10-25 01:59:00 +0100 BST 2015-10-25 00:59:00 +0000 UTC <nil>
2015-10-25 01:00:00 +0000 GMT 2015-10-25 01:00:00 +0000 UTC
--------------------
2015-10-25 02:01:00 +0000 BST 2015-10-25 02:01:00 +0000 UTC <nil>
2015-10-25 02:02:00 +0000 BST 2015-10-25 02:02:00 +0000 UTC

However if I parse a time after 2am in BST I would expect it to switch to GMT just as incrementing the time over the transition would have. In case the transitional code was called by the Add routine I add a minute again but this also does not revert the time to GMT.

I would have expected one of the following to occur

a) for BST to always remain GMT+1

b) to any time where BST is "invalid" to automatically change to the correct GMT time (invalid BST is between 2am after the last Sunday in October and 2am after the last Sunday in March the following year)

c) an error to be thrown if a date is created within those dates with BST (and perhaps other daylight saving hours in other countries).

Otherwise I'll have to check if a user enters a date in BST whether that date lies outside BST and adjust or force users to UTC times, which kind of defeats the object of having daylight saving functions built into the library.

Whilst researching I spotted this https://www.youtube.com/watch?v=-5wpm-gesOY and have decided it is definitely not as simple as I had at first assumed...

Any insight or a better way to handle daylight saving times would be appreciated.

Using go version 1.0.2 on Debian Wheezy

Edited: retried using go version 1.3.3 and got this output

2015-10-25 01:59:00 +0100 BST 2015-10-25 00:59:00 +0000 UTC <nil>
2015-10-25 01:00:00 +0000 GMT 2015-10-25 01:00:00 +0000 UTC
--------------------
2015-10-25 01:00:00 +0000 GMT 2015-10-25 01:00:00 +0000 UTC <nil>
2015-10-25 01:01:00 +0000 GMT 2015-10-25 01:01:00 +0000 UTC

So appears to work as I expected in later versions... Have also found this question Daylight saving time and time zone best practices So will be giving it a thorough read.

Thanks.

like image 219
hairy_marmite Avatar asked Mar 16 '15 18:03

hairy_marmite


1 Answers

Go, like everybody else but Microsoft, uses the IANA Time Zone Database which has regular updates that are included in the current Go release.

You used go1.0.3 which was released in March 2012 (Release History). The British time zone data for 2015 was added later.

ALWAYS use a current version of Go for time zone calculations.

like image 78
peterSO Avatar answered Oct 05 '22 02:10

peterSO