为了账号安全,请及时绑定邮箱和手机立即绑定

解析 PostgreSQL TIMESTAMP 类型值的问题

解析 PostgreSQL TIMESTAMP 类型值的问题

Go
牧羊人nacy 2023-06-12 15:13:56
在 PostgreSQL 中,我有一个名为surveys.CREATE TABLE SURVEYS(  SURVEY_ID UUID PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(),  SURVEY_NAME VARCHAR NOT NULL,  SURVEY_DESCRIPTION TEXT,  START_PERIOD TIMESTAMP,  END_PERIOD TIMESTAMP);如您所见,只有SURVEY_ID和SURVEY_NAME列是NOT NULL.在 Go 中,我想根据请求在该表中创建新条目POST。我像这样发送 JSON 对象:{    "survey_name": "NAME",    "survey_description": "DESCRIPTION",    "start_period": "2019-01-01 00:00:00",    "end_period": "2019-02-28 23:59:59"}不幸是,它引发了奇怪的错误:parsing time ""2019-01-01 00:00:00"" as ""2006-01-02T15:04:05Z07:00"": cannot parse " 00:00:00"" as "T"我在哪里犯了错误以及如何解决我的问题?模型/surveys.go:import (    "database/sql"    "time")type NullTime struct {    time.Time    Valid bool}type Survey struct {    ID int `json:"survey_id"`    Name string `json:"survey_name"`    Description sql.NullString `json:"survey_description"`    StartPeriod NullTime `json:"start_period"`    EndPeriod NullTime `json:"end_period"`}控制器/surveys.go:var CreateSurvey = func(responseWriter http.ResponseWriter, request *http.Request) {    // Initialize variables.    survey := models.Survey{}    var err error    // The decoder introduces its own buffering and may read data from argument beyond the JSON values requested.    err = json.NewDecoder(request.Body).Decode(&survey)    if err != nil {        log.Println(err)        utils.ResponseWithError(responseWriter, http.StatusInternalServerError, err.Error())        return    }
查看完整描述

1 回答

?
手掌心

TA贡献1942条经验 获得超3个赞

错误已经说明出了什么问题:

将时间“2019-01-01 00:00:00”解析为“2006-01-02T15:04:05Z07:00”:无法将“00:00:00”解析为“T”

您正在传递"2019-01-01 00:00:00",而它需要不同的时间格式,即RFC3339(UnmarshalJSON 的默认格式)。

要解决这个问题,您要么想要以预期的格式传递时间"2019-01-01T00:00:00Z00:00",要么像这样定义您自己的类型CustomTime

const timeFormat = "2006-01-02 15:04:05"


type CustomTime time.Time


func (ct *CustomTime) UnmarshalJSON(data []byte) error {

    newTime, err := time.Parse(timeFormat, strings.Trim(string(data), "\""))

    if err != nil {

        return err

    }


    *ct = CustomTime(newTime)

    return nil

}


func (ct *CustomTime) MarshalJSON() ([]byte, error) {

    return []byte(fmt.Sprintf("%q", time.Time(*ct).Format(timeFormat))), nil

}

小心,您可能还需要为要在数据库内外解析的时间实现Valuer和Scanner接口,如下所示:


func (ct CustomTime) Value() (driver.Value, error) {

    return time.Time(ct), nil

}


func (ct *CustomTime) Scan(src interface{}) error {

    if val, ok := src.(time.Time); ok {

        *ct = CustomTime(val)

    } else {

        return errors.New("time Scanner passed a non-time object")

    }


    return nil

}

去游乐场的例子。



查看完整回答
反对 回复 2023-06-12
  • 1 回答
  • 0 关注
  • 69 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信