pq:日期/时间字段值超出范围:"22/02/2022"



我有这个查询:

l.loyaltycard_number, l.recipt_no, 
l.totaltrans_amount, l.amount_paid, 
l.reward_points, l.redeemed_points,
cashier FROM loyalty l
JOIN warehouses w
ON l.machine_ip = w.machine_ip
WHERE l.machine_name = $1 
AND redeemed_points != $2
AND trasaction_time BETWEEN $3 AND  $4
ORDER BY trasaction_time DESC;

我有用于transaction_time的HTML日期选择器,其格式为dd/mm/yyyy。

每当我选择第一个数字大于12的日期范围时(2022年2月22日(。我得到了上面的错误。我怀疑格式有问题。

我在文档中找到了如何将postgresql日期样式设置为DMY。做了那个之后,我得到了同样的错误。

然而,当我在Postgrescli中运行相同的查询时,如下所示:

SELECT w.machine_name, l.trasaction_time,
l.loyaltycard_number, l.recipt_no, 
l.totaltrans_amount, l.amount_paid, 
l.reward_points, l.redeemed_points,
cashier FROM loyalty l
JOIN warehouses w
ON l.machine_ip = w.machine_ip
WHERE l.machine_name = 'HERMSERVER'
AND redeemed_points != 0
AND trasaction_time BETWEEN '14/11/21' AND  '22/02/22'
ORDER BY trasaction_time DESC;

我得到了预期的结果。我不知道我做错了什么。我想知道如何使数据库将日期选择器中的日期处理为dd/mm/yyyy,而不是mm/dd/yyyy。我正在使用谷歌cloudsqlPostgres

这是从日期选择器获取数据的处理程序的代码

err := r.ParseForm()
if err != nil {
app.clientError(w, http.StatusBadRequest)
}
startDate := r.PostForm.Get("startDate")
endDate := r.PostForm.Get("endDate")
outlet := r.PostForm.Get("outlet")
reportType := r.PostForm.Get("repoType")
if reportType == "0" {
rReport, err := app.models.Reports.GetRedeemedReport(startDate, endDate, outlet, reportType)
if err != nil {
app.serverError(w, err)
return
}
app.render(w, r, "tranxreport.page.tmpl", &templateData{
Reports: rReport,
})
} else if reportType == "1" {
rReport, err := app.models.Reports.GetAllReport(startDate, endDate, outlet)
if err != nil {
app.serverError(w, err)
return
}
app.render(w, r, "tranxreport.page.tmpl", &templateData{
Reports: rReport,
})
} else {
app.render(w, r, "tranxreport.page.tmpl", &templateData{})
}

根据评论,虽然应该可以更改DateStyle,但有一些问题:

  • SET datestyle命令更改当前会话的样式。由于SQL软件包使用连接池,因此其用途有限
  • 您可以使用";postgresql.conf配置文件中的DateStyle参数或服务器上的PGDATESTYLE环境变量";但在Postgres作为托管服务提供的情况下,这可能不可用。请注意,如果不设置参数,进行此更改也意味着您的软件将失败(当移动到新服务器时,这很容易完成(

一个相对简单的解决方案是编辑查询以使用TO_DATE,例如:

BETWEEN TO_DATE($3,'DD/MM/YYYY') AND TO_DATE($4,'DD/MM/YYYY')

然而,尽管这将起作用,但它使您的数据库代码依赖于发送到API的数据格式。这意味着,例如,引入新的日期选择器可能会以一种很容易被遗漏的方式破坏代码(月初的测试也可以(。

更好的解决方案可能是在API中使用标准的日期格式(例如ISO 8601(和/或将日期作为time.Time传递给数据库函数。然而,由于时区、夏令时等原因,这确实需要小心。

相关内容

  • 没有找到相关文章

最新更新