It's Go Time: Better Time in Golang

Posted 20 Jun 2015 to golang, arrow and has Comments

Dealing with time in Go is a pain. The built-in time package doesn’t include much in the way of helper functions. Formatting time is especially difficult; unlike many other languages in the C-family, Go has no support for strftime-based formatting. Instead, you have to remember a specific date (1/2 3:04:05 2006 -0700) and format that date’s values in the form you’d like to mimic. For instance, if I wanted to format a date into the format mm/dd/yyyy HH:MM:SS, here’s what you have to do:

fmt.Println("Today's date:", time.Now().Format("01/02/2006 03:04:05"))

Of course, this typically require having to look up the magic date in the docs to make sure you’ve got the right month/day/year. I’m lazy, so naturally I’d rather just have the same strftime format I’m used to.

Time Flies Like an Arrow; Fruit Flies Like a Banana

The Arrow library provides a C-family style strftime-based formatting and parsing in Golang (among other helpful date/time functions). Here’s an example of formatting and parsing:

// formatting
fmt.Println("Current date: ", arrow.Now().CFormat("%Y-%m-%d %H:%M:%S"))

// parsing
parsed, _ := arrow.CParse("%Y-%m-%d", "2015-06-03")
fmt.Println("Some other date: ", parsed)

You can also get the time at the beginning of the minute / hour / day / week / month / year.

t := arrow.Now().AtBeginningOfHour().CFormat("%Y-%m-%d %H:%M:%S")
fmt.Println("The first second of this hour was at:", t)

t = arrow.Now().AtBeginningOfWeek().CFormat("%Y-%m-%d %H:%M:%S")
fmt.Println("The first second of the week was at:", t)

You can also more easily sleep until specific times:

// sleep until the next minute starts
arrow.SleepUntil(arrow.NextMinute())
fmt.Println(arrow.Now().CFormat("%H:%M:%S"))

There are also helpers to get today, yesterday, and UTC times:

day := arrow.Yesterday().CFormat("%Y-%m-%d")
fmt.Println("Yesterday: ", day)

dayutc := arrow.UTC().Yesterday().CFormat("%Y-%m-%d %H:%M")
fmt.Println("Yesterday, UTC: ", dayutc)

newyork := arrow.InTimezone("America/New_York").CFormat("%H:%M:%s")
fmt.Println("Time in New York: ", newyork)

And for generating ranges when you need to iterate:

// Print every minute from now until 24 hours from now
for _, a := range arrow.Now().UpTo(arrow.Tomorrow(), arrow.Minute) {
     fmt.Println(a.CFormat("%Y-%m-%d %H:%M:%S"))
}

Much easier. There’s more magic not listed here; check out the docs on godoc.org for the full list.