Golang如何将前端的日期数据映射到time.Time中?

Number of views 26

我们正在使用echo框架来开发我们的Web服务端,我定义了如下所示的结构体,我从前端获取到类似这样一串‘2024-09-27’的日期数据,我怎么能把它绑定到struct中?

type TestModel struct {
  Date     time.Time `json:"date" form:"date" gorm:"index"`
  gorm.Model
}

我是这么解析的:

func CreateDiary(c echo.Context) error {
    var getData model.TestModel
    if err := (&echo.DefaultBinder{}).BindBody(c, &getData); err != nil {
        fmt.Print(err.Error())
    }
   return c.JSON(200, getData)
}

不过还是遇到了错误:

code=400, message=parsing time "2024-09-27" as "2006-01-02T15:04:05Z07:00": cannot parse "" as "T", internal=parsing time "2024-09-27" as "2006-01-02T15:04:05Z07:00": cannot parse "" as "T"

应该怎么做?

1 Answers

在Go语言中,使用Echo框架处理日期数据时,需要确保日期格式能够正确地映射到time.Time类型。默认情况下,Echo框架使用的DefaultBinder会尝试将日期字符串解析为RFC3339格式(即"2006-01-02T15:04:05Z07:00")。然而,你提供的日期格式是"2024-09-27",没有时间部分和时区信息,这导致了解析错误。

为了正确处理这种格式的日期字符串,你可以自定义一个解绑器(Unbinder)来处理这种特定的日期格式。以下是一个示例代码,展示了如何实现这一点:

  1. 定义一个新的解绑器,用于处理日期字符串。
  2. 在你的处理函数中使用这个新的解绑器。

首先,创建一个自定义的解绑器:

package main

import (
	"fmt"
	"time"

	"github.com/labstack/echo/v4"
)

// CustomTime 解绑器用于处理日期字符串
type CustomTime struct {
	time.Time
}

const layout = "2006-01-02"

func (ct *CustomTime) UnmarshalJSON(b []byte) error {
	dateStr := string(b)
	dateStr = strings.Trim(dateStr, `"`)
	t, err := time.Parse(layout, dateStr)
	if err != nil {
		return err
	}
	ct.Time = t
	return nil
}

// TestModel 结构体
type TestModel struct {
	Date time.Time `json:"date" form:"date" gorm:"index"`
	gorm.Model
}

// CreateDiary 处理函数
func CreateDiary(c echo.Context) error {
	var getData TestModel
	if err := c.Bind(&getData); err != nil {
		fmt.Println(err.Error())
		return c.JSON(400, map[string]string{"error": err.Error()})
	}
	return c.JSON(200, getData)
}

func main() {
	e := echo.New()
	e.POST("/test", CreateDiary)
	e.Start(":8080")
}

在这个示例中,我们定义了一个CustomTime结构体,并实现了UnmarshalJSON方法来处理日期字符串。然后我们在TestModel结构体中使用CustomTime类型来替代time.Time

接下来,在CreateDiary处理函数中,我们使用c.Bind(&getData)来绑定请求体中的数据到TestModel结构体中。这样,Echo框架会使用我们定义的解绑器来解析日期字符串。

通过这种方式,你可以确保从前端传入的日期字符串能够正确地映射到time.Time类型。