convert string to time and parse in golang - go

I'm reading a timestamp from a file, and I assign the value to t:
t := "2016-11-02 19:23:05.503705739 +0000 UTC"
When I attempt to parse the string:
time, err := time.Parse("2016-11-02 19:18:57.149197306 +0000 UTC", t)
The result is:
0001-01-01 00:00:00 +0000 UTC
But I expected result to be:
"2016-11-02 19:18:57.149197306 +0000 UTC" ?
Please advise.

You're not correctly providing the layout argument to Parse. You're supposed to be using Mon Jan 2 15:04:05 MST 2006 (this is magic value, you put create a string in the format you want but with that date) in the given format so in your case, it would be 2006-01-02 15:04:05.000000000 +0000 UTC plus the offset which I don't know off the top of my head for MST.

Related

Calculate the Closest Time Difference in HH:MM(am/pm) Format using Go

I got a bit problem when calculating the time difference from PM to AM or vice versa. For instance:
ref, _ := time.Parse("03:04pm", "11:59pm")
t, _ := time.Parse("03:04am", "12:00am")
fmt.Println(t.Sub(ref).Minutes()) // Got -719, my expectation is 1 (minutes)
Actually that's true, but I want to get the smallest difference.
The reason you got -719 is that you do not provide date information and in second time.Parse you have typo in template. Template has to contain pm
time.Parse("03:04pm", "11:59pm") // 0000-01-01 23:59:00 +0000 UTC
time.Parse("03:04am", "12:00am") // 0000-01-01 12:00:00 +0000 UTC
You need to provide day information and pm in template
time.Parse("02 03:04pm", "01 11:59pm") // 0000-01-01 23:59:00 +0000 UTC
time.Parse("02 03:04pm", "02 12:00am") // 0000-01-02 00:00:00 +0000 UTC
see https://stackoverflow.com/a/69338568/12301864

How to format current time into YYYY-MM-DDTHH:MM:SSZ

Never tried Go before and currently doing a small project. One of the task is to get current system time and represent it in YYYY-MM-DDT00:00:00Z format. I believe that Z means that time is represented in UTC format but when i looked into db, all timestamps are like this i.e., 2011-11-22T15:22:10Z.
So how can i format like this in Go?
Update
I was able to format it using following code
t := time.Now()
fmt.Println(t.Format("2006-01-02T15:04:05Z"))
Now the question remains, what Z signifies here. Should i get UTC Time?
Another question, it looks like that the value i am using to format impacts the output i.e., when i used 2019-01-02T15:04:05Z the output became 2029-02-02T20:45:11Z, why?
Go provides very flexible way to parse the time by example. For this, you have to write the "reference" time in the format of your choice. The reference time is Mon Jan 2 15:04:05 MST 2006. In my case, I used this reference time to parse the Now():
fmt.Println(time.Now().UTC().Format(time.RFC3339))
There are also other reference types if you want to see:
RFC822 = "02 Jan 06 15:04 MST"
RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
RFC3339 = "2006-01-02T15:04:05Z07:00"
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
Or you can use you desired reference.
"If a time is in Coordinated Universal Time (UTC), a "Z" is added directly after the time without a separating space. "Z" is the zone designator for the zero UTC offset. "09:30 UTC" is therefore represented as "09:30Z" or "0930Z". Likewise, "14:45:15 UTC" is written as "14:45:15Z" or "144515Z".[16]"
From https://en.wikipedia.org/wiki/Time_zone#UTC
// Some valid layouts are invalid time values for time.Parse, due to formats
// such as _ for space padding and Z for zone information.
and
// Replacing the sign in the format with a Z triggers
// the ISO 8601 behavior of printing Z instead of an
// offset for the UTC zone. Thus:
// Z0700 Z or ±hhmm
// Z07:00 Z or ±hh:mm
// Z07 Z or ±hh
From the source for package time/format.go

How to set the Zone of a Go time value when knowing the UTC time and time offset?

I have an UTC time and a time offset in seconds, and need to return the corresponding Go time value.
It is trivial to instantiate the UTC time value by using the time.Unix() function. But to set the Zone, I need to determine the time.Location.
How can I find the time.Location when knowing the UTC time and time offset ?
Without an actual entry to lookup in the time zone database, you can't know the true location for the time. If you want to work with just an offset, you can create a fixed location using time.FixedZone
edt := time.FixedZone("EDT", -60*60*4)
t, _ := time.ParseInLocation("02 Jan 06 15:04", "15 Sep 17 14:55", edt)
fmt.Println(t)
// 2017-09-15 14:55:00 -0400 EDT
You can opt to specify a non-existent zone name, or none at all, as long as the output format you use doesn't require one.
minus4 := time.FixedZone("", -60*60*4)
t, _ = time.ParseInLocation("02 Jan 06 15:04", "15 Sep 17 14:55", minus4)
fmt.Println(t.Format(time.RFC3339))
// 2017-09-15T14:55:00-04:00

Golang timestamp parsing

I'm trying to parse the timestamp Oct 12 2016 13:59:27 UTC using the following code.
eventDateLayout := "Jan _2 2006 15:04:00 UTC"
eventCheckDate, _ := time.Parse(eventDateLayout,"Oct 12 2016 13:59:27 UTC")
fmt.Println(eventCheckDate)
Result if 0001-01-01 00:00:00 +0000 UTC which is not the expected.
Can this timestamp parsed with golang time library?
In addition to the incorrect time layout, I'd recommend handling the error instead of throwing it away.
It gives you a helpful error message that you can use to efficiently debug:
cannot parse "27 UTC" as ":00 UTC"
Go playground (note the outputted time will be different)

Daylight saving hours in Golang

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.
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.

Resources