Recently I needed to find the number of days between two dates in Go and kept coming across implementations that didn't quite suit my needs.
So I rolled my own, and I'm pretty proud of how robust it is! :)
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(daysBetween(date("2012-01-01"), date("2012-01-07"))) // 6
fmt.Println(daysBetween(date("2016-01-01"), date("2017-01-01"))) // 366 because leap year
fmt.Println(daysBetween(date("2017-01-01"), date("2018-01-01"))) // 365
fmt.Println(daysBetween(date("2016-01-01"), date("2016-01-01"))) // 0
}
func daysBetween(a, b time.Time) int {
if a.After(b) {
a, b = b, a
}
days := -a.YearDay()
for year := a.Year(); year < b.Year(); year++ {
days += time.Date(year, time.December, 31, 0, 0, 0, 0, time.UTC).YearDay()
}
days += b.YearDay()
return days
}
func date(s string) time.Time {
d, _ := time.Parse("2006-01-02", s)
return d
}
Discussion (6)
Not quite as robust as I'd like. Not all days have 24 hours in them. 😔
This still doesn't work: Not all days have 24 hours.
In most countries in Europe and North America it varies between 23 and 25.
Thanks for sharing this. I like your approach. What are your thoughts on ensuring that "a" and "b" are within the same time.Location (Timezone) as each other?
For my thinking if they are in different time zones they might be viewed as in a different YearDay than accurate for the two.
I passed in time.Location, used that instead of time.UTC (although that seems moot, except for the benefits of the simplicity of consistency) and ensured that "a" and "b" are in the same TZ.
That sounds extremely reasonable. 🙂