How to get seconds of day (1 - 86400) in Go?
Just like http://joda-time.sourceforge.net/apidocs/org/joda/time/base/AbstractDateTime.html#getSecondOfDay()
Update/Clarifications
Note: This function returns the nominal number of seconds of day in the (0 - 86399) range. If you're looking for the "number of seconds elapsed since midnight", which may not be in (0 - 86399) range due to daylight saving time, please see @icza's answer.
Update: Please note also that the question refers to Joda Time implementation, which, according to Joda Time getSecondOfDay on DST switch day, seems to correspond to the nominal number of seconds implementation (as in my answer below) as opposed to the "number of seconds elapsed since midnight" (as in @icza's answer).
package main
import (
"fmt"
"time"
)
func getSecondOfDay(t time.Time) int {
return 60*60*t.Hour() + 60*t.Minute() + t.Second()
}
func main() {
t := time.Now()
fmt.Println(getSecondOfDay(t))
}
If we define "seconds of day" as the "elapsed seconds since midnight", then to get correct result even on days when daylight saving time happens we should subtract the time representing midnight from the given time. For that, we may use Time.Sub()
.
func daySeconds(t time.Time) int {
year, month, day := t.Date()
t2 := time.Date(year, month, day, 0, 0, 0, 0, t.Location())
return int(t.Sub(t2).Seconds())
}
Testing it:
for _, t := range []time.Time{
time.Date(2019, 1, 1, 0, 0, 30, 0, time.UTC),
time.Date(2019, 1, 1, 0, 1, 30, 0, time.UTC),
time.Date(2019, 1, 1, 0, 12, 30, 0, time.UTC),
time.Date(2019, 1, 1, 12, 12, 30, 0, time.UTC),
} {
fmt.Println(daySeconds(t))
}
Output (try it on the Go Playground):
30
90
750
43950
Let's see how this function gives correct result when daylight saving time happens. In Hungary, 25 March 2018 is a day when the clock was turned forward 1 hour at 02:00:00
, from 2 am
to 3 am
.
loc, err := time.LoadLocation("CET")
if err != nil {
fmt.Println(err)
return
}
t := time.Date(2018, 3, 25, 0, 0, 30, 0, loc)
fmt.Println(t)
fmt.Println(daySeconds(t))
t = t.Add(2 * time.Hour)
fmt.Println(t)
fmt.Println(daySeconds(t))
This outputs (try it on the Go Playground):
2018-03-25 00:00:30 +0100 CET
30
2018-03-25 03:00:30 +0200 CEST
7230
We print the daySeconds
of a time being 30 seconds after midnight, which is 30
of course. Then we add 2 hours to the time (2 hours = 2*3600 seconds = 7200), and the daySeconds
of this new time will be properly 7200 + 30 = 7230
, even though the time changed 3 hours.