dotws86260 2019-02-28 08:50
浏览 565
已采纳

解析PostgreSQL TIMESTAMP类型的值时出现问题

In PostgreSQL, I have table called 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
);

As you can see only SURVEY_ID and SURVEY_NAME columns are NOT NULL.

In Go, I want to create new entry in that table by POST request. I send JSON object like this:

{
    "survey_name": "NAME",
    "survey_description": "DESCRIPTION",
    "start_period": "2019-01-01 00:00:00",
    "end_period": "2019-02-28 23:59:59"
}

Unfortunatly it raise strange ERROR:

parsing time ""2019-01-01 00:00:00"" as ""2006-01-02T15:04:05Z07:00"": cannot parse " 00:00:00"" as "T"

Where I make mistake and how to fix my problem?

models/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"`
}

controllers/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
    }
    defer request.Body.Close()

    // Execute INSERT SQL statement.
    _, err = database.DB.Exec("INSERT INTO surveys (survey_name, survey_description, start_period, end_period) VALUES ($1, $2, $3, $4);", survey.Name, survey.Description, survey.StartPeriod, survey.EndPeriod)

    // Shape the response depending on the result of the previous command.
    if err != nil {
        log.Println(err)
        utils.ResponseWithError(responseWriter, http.StatusInternalServerError, err.Error())
        return
    }
    utils.ResponseWithSuccess(responseWriter, http.StatusCreated, "The new entry successfully created.")
}
  • 写回答

1条回答 默认 最新

  • dongliao1949 2019-02-28 09:07
    关注

    The error already says what is wrong:

    parsing time ""2019-01-01 00:00:00"" as ""2006-01-02T15:04:05Z07:00"": cannot parse " 00:00:00"" as "T"

    You are passing "2019-01-01 00:00:00" while it expects a different time format, namely RFC3339 (UnmarshalJSON's default).

    To solve this, you either want to pass the time in the expected format "2019-01-01T00:00:00Z00:00" or define your own type CustomTime like this:

    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
    }
    

    Careful, you might also need to implement the Valuer and the Scanner interfaces for the time to be parsed in and out of the database, something like the following:

    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
    }
    

    Go Playground example.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 我想在一个软件里添加一个优惠弹窗,应该怎么写代码
  • ¥15 fluent的在模拟压强时使用希望得到一些建议
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services
  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏
  • ¥15 模糊pid与pid仿真结果几乎一样
  • ¥15 java的GUI的运用
  • ¥15 Web.config连不上数据库
  • ¥15 我想付费需要AKM公司DSP开发资料及相关开发。
  • ¥15 怎么配置广告联盟瀑布流