pq:date/time 字段值超出范围:“22/02/2022”

pq: date/time field value out of range: "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 =  
    AND redeemed_points != 
    AND trasaction_time BETWEEN  AND  
    ORDER BY trasaction_time DESC;

我有 HTML 格式的 transaction_time 日期选择器 dd/mm/yyyy.

任何时候我 select 第一个数字大于 12 的日期范围,(22/02/2022)。 我收到上述错误。 我怀疑是格式问题。

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

但是,当我 运行 在 Postgres cli 中执行相同的查询时:

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。我正在使用 google cloudsql Postgres

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

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 command changes the style for the current session。由于 SQL 包使用连接池,因此用途有限。
  • may be able to use“postgresql.conf 配置文件中的 DateStyle 参数,或服务器上的 PGDATESTYLE 环境变量”,但这在 Postgres 作为托管服务提供时可能不可用。请注意,进行此更改还意味着如果未设置该参数,您的软件将失败(这在移动到新服务器时很容易完成)。

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

BETWEEN TO_DATE(,'DD/MM/YYYY') AND TO_DATE(,'DD/MM/YYYY')

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

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