Подтвердить что ты не робот

Какой идиоматический способ работать с датами без времени в голанге?

Я пишу REST API в Go, работая с датами, которые не представляют собой один момент времени.

Данные JSON поступают на сервер и с сервера в формате "2006-01-02", причем эти данные говорят с базой данных mysql, используя столбцы DATE.

Одна вещь, которую я пробовал, - создать структуру, которая встраивает Time, и реализует реализации интерфейса преобразования JSON и SQL, чтобы иметь возможность правильно взаимодействовать с конечными точками, сохраняя при этом доступные методы времени для математики и форматирования даты. например:.

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)
}

И тогда другие структуры могут быть этого типа и получить 90% для представления типа даты в моей проблемной области.

Вышеприведенный код работает, но я чувствую, что борюсь против тока Go. Итак, пара вопросов для ветеранов языка:

Считаете ли вы, что этот код вызовет больше боли, чем он спасет?
Если да, то какой стиль вы бы порекомендовали?

4b9b3361

Ответ 1

Я думаю, что вы можете хранить свои данные как time.Time, но преобразовать их в строку для целей JSON:

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

Чтобы узнать, как сделать эту работу с SQL: https://github.com/go-sql-driver/mysql#timetime-support