我在Go中编写REST API,处理不能代表单个时间点的日期。
它的JSON数据往返于服务器" 2006-01-02"格式,该数据使用DATE列与mysql数据库通信。
我尝试过的一件事是创建一个嵌入Time的结构,并实现JSON和SQL转换接口实现,以便能够正确地与端点交互,同时仍然有Time方法可用于日期数学和格式化。 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)
}
然后其他结构可以是这种类型,并获得90%来表示我的问题域中的日期类型。
以上代码有效,但我觉得我正在与Go当前战斗。对于语言的退伍军人来说,有几个问题:
你认为这段代码会比它节省更多的痛苦吗? 如果是这样,你会推荐什么样的风格?
答案 0 :(得分:4)
我使用了cloud.google.com/go/civil软件包中的civil.Date
答案 1 :(得分:3)
我认为您可以将数据存储为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