Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the idiomatic way to work with dates without time in golang?

Tags:

I'm writing a REST API in Go, working with dates that don't represent a single point in time.

It's JSON data going to and from the server in "2006-01-02" format, with that data talking to a mysql database using DATE columns.

One thing I've tried is to create a struct that embeds a Time, and implements JSON and SQL conversion interface implementations to be able to correctly interact with the endpoints while still having Time methods available for date math and formatting. e.g.:

package localdate  import (     "time"     "encoding/json"     "database/sql/driver" )  type LocalDate struct {     time.Time }  func NewLocalDate(year int, month time.Month, day int) LocalDate {     time := time.Date(year, month, day, 0, 0, 0, 0, time.UTC)     return LocalDate{Time: time} }  const LocalDateFormat = "2006-01-02" // yyyy-mm-dd  func (ld *LocalDate) UnmarshalJSON(data []byte) error {     // parse and set the ld.Time variable }  func (ld *LocalDate) MarshalJSON() ([]byte, error) {     return json.Marshal(ld.Format(LocalDateFormat)) }  // sql.Scanner implementation to convert a time.Time column to a LocalDate func (ld *LocalDate) Scan(value interface{}) error {}  // sql/driver.Valuer implementation to go from LocalDate -> time.Time func (ld *LocalDate) Value() (driver.Value, error)  {}  // used to convert a LocalDate into something we can plug into a query // we could just use ld.Time, but that would send '2015-01-01 00:00:00 +0000 UTC' // instead of '2015-01-01' for the DATE query parameter.  (Which works for mysql, but is officially invalid SQL) func (ld *LocalDate) SqlDate() string  {     return ld.Format(LocalDateFormat) } 

And then other structs can be of this type, and get 90% there to representing the date type in my problem domain.

The above code works, but I feel like I'm fighting against the Go current. So a couple questions for the veterans of the language:

Do you think this code will cause more pain than it'll save?
If so, what style would you recommend?

like image 311
Dan Tanner Avatar asked Feb 11 '15 04:02

Dan Tanner


People also ask

How do you store dates in go?

For example, a 4-digit year might be represented by %Y . In Go, though, these parts of a date or time are represented by characters that represent a specific date. To include a 4-digit year in a Go date format, you would actually include 2006 in the string itself.

How do you get only time in Golang?

With the help of time. Now() function, we can get the current time in Golang by importing time module. Return: Return current date and time.

What is the datatype of time in Golang?

Time datatype has a base type structure that contains time, date, location, timezone, and monotonic time. Go time package has methods to extract individual parts from time instant (like date, time, day, location, etc).


2 Answers

I use civil.Date from the package cloud.google.com/go/civil

like image 155
mvndaai Avatar answered Oct 19 '22 19:10

mvndaai


I think you can store your data as time.Time but convert it to a string for JSON purposes:

type LocalDate struct {   t time.Time `json:",string"` // might even work anonymously here } 

To see how to make this work with SQL: https://github.com/go-sql-driver/mysql#timetime-support

like image 45
Alexei Andreev Avatar answered Oct 19 '22 19:10

Alexei Andreev