英文:
How to convert HTML DateTime to Golang Time object
问题
我是你的中文翻译助手,以下是翻译的内容:
我是golang的初学者。
我正在尝试从HTML的日期输入中获取输入。
<input type="date" id="birthDate" name="BirthDate" required placeholder="YYYY-MM-DD">
并将其提交到create方法中。
func (c *customerController) CreateCustomer(ctx *gin.Context) {
var customer Customer
if err := ctx.ShouldBindJSON(&customer); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := c.service.CreateCustomer(customer); err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create customer"})
return
}
ctx.Status(http.StatusOK)
}
Customer对象:
type Customer struct {
ID uint `gorm:"primarykey"`
FirstName string `gorm:"type:varchar(100);not null"`
LastName string `gorm:"type:varchar(100);not null"`
BirthDate time.Time `gorm:"not null"`
Gender string `gorm:"type:varchar(6);not null"`
Email string `gorm:"type:varchar(100);not null;unique"`
Address string `gorm:"type:varchar(200)"`
}
当我尝试添加新的Customer时,我收到Http错误400,因为HTML的日期类型与golang的Time对象不匹配。
错误消息是{"error":"parsing time \"2014-05-05\" as \"2006-01-02T15:04:05Z07:00\": cannot parse \"\" as \"T\""}
我该如何解决这个问题?
提前感谢您的帮助。
英文:
I am beginner at golang.
I am trying to take input from HTML input type date
<input type="date" id="birthDate" name="BirthDate" required placeholder="YYYY-MM-DD">
and post this create method
func (c *customerController) CreateCustomer(ctx *gin.Context) {
var customer Customer
if err := ctx.ShouldBindJSON(&customer); err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := c.service.CreateCustomer(customer); err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create customer"})
return
}
ctx.Status(http.StatusOK)
}
Customer object:
type Customer struct {
ID uint `gorm:"primarykey"`
FirstName string `gorm:"type:varchar(100);not null"`
LastName string `gorm:"type:varchar(100);not null"`
BirthDate time.Time `gorm:"not null"`
Gender string `gorm:"type:varchar(6);not null"`
Email string `gorm:"type:varchar(100);not null;unique"`
Address string `gorm:"type:varchar(200)"`
}
When I try to add new Customer I get Http Error 400 because HTML date type is not match to golang Time object.
And error body is {"error":"parsing time \"2014-05-05\" as \"2006-01-02T15:04:05Z07:00\": cannot parse \"\" as \"T\""}
How can I solve this problem?
Thanks in advance
答案1
得分: 2
我得到了Http错误400,因为HTML日期类型与golang的Time对象不匹配。
请避免这样思考问题。
真正的问题是:
- 在客户端,解析的
<input type="date">
元素的值始终以yyyy-mm-dd
的格式进行格式化(参见value of<input type="date">
)。 - 在服务器端,
ctx.ShouldBindJSON
使用encoding/json
包来解组请求,它使用(*Time).UnmarshalJSON
将时间解组为time.Time
对象。(*Time).UnmarshalJSON
要求时间必须是RFC 3339格式的带引号的字符串(即2006-01-02T15:04:05Z07:00
)(参见(*Time).UnmarshalJSON)。
格式为yyyy-mm-dd
的值不满足2006-01-02T15:04:05Z07:00
,所以失败了。
要解决这个问题,你可以在客户端将值转换为RFC 3339格式,或者在服务器端实现json.Unmarshaler接口以支持yyyy-mm-dd
。
有一个提案支持时间格式的结构标签,如果实现了这个提案,处理这种情况将变得容易。该提案还展示了目前的解决方法。
最后需要注意的是,在实际应用中,你应该定义BirthDate time.Time
的含义。例如,假设一个用户在时区+07:00
中表示他的出生日期是1990-05-21
,并且该值以1990-05-20T17:00:00Z
的形式存储到数据库中。稍后,另一个用户在时区-03:00
中加载该用户的个人资料。你会在页面上显示什么?
英文:
> I get Http Error 400 because HTML date type is not match to golang Time object.
Please avoid thinking the issue like this.
The real issue is that:
- On the client side, the parsed value of an
<input type="date">
element is always formatted asyyyy-mm-dd
(See value of<input type="date">
). - On the server side,
ctx.ShouldBindJSON
uses theencoding/json
package to unmarshal the request, which uses(*Time).UnmarshalJSON
to unmarshal a time into atime.Time
object.(*Time).UnmarshalJSON
requires that the time must be a quoted string in the RFC 3339 format (namely,2006-01-02T15:04:05Z07:00
) (See (*Time).UnmarshalJSON).
The value in the format yyyy-mm-dd
does not satisfy 2006-01-02T15:04:05Z07:00
, that's why it failed.
To address the issue, you can either transform the value into RFC 3339 format on the client side, or implement the json.Unmarshaler interface to support yyyy-mm-dd
on the server side.
There is a proposal to support struct tag for time.Format, which if implemented, would make it easy to handle this case. The proposal also shows how to workaround the issue as of now.
The last note is, in a real world application, you should define what BirthDate time.Time
means. For example, imaging a user in the time zone +07:00
said his birth date is 1990-05-21
, and the value is stored to the database as 1990-05-20T17:00:00Z
. Later another user loads this user's profile in time zone -03:00
. What will you display on the page?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论