Rails3 / jQuery UI Datepicker - 保存时反转月和日

时间:2012-04-05 20:47:15

标签: ruby-on-rails-3 postgresql date format jquery-ui-datepicker

(我的问题与described in this question几乎相同,只有答案在我的情况下不起作用。)


我在一个带有Postgres数据库的Rails应用程序中使用jQuery UI Datepicker。默认实现使用 mm / dd / yy 日期格式来显示所选日期,这正是我想要的。但是,在将记录保存到数据库后,月份和日期相反 - 然后显示为 yy-dd-mm 。所以选择3/11/2012会尝试保存为11月3日而不是3月11日,并且根本不保存像2012年3月31日这样的日期,因为它不存在。

到目前为止,我已经尝试了三种不同的途径来解决这个问题:

1)首次尝试重新格式化文本字段,以便显示我的想法:

<%= f.text_field :foo, :value => (@model.foo.blank? ? '' : @model.foo.strftime('%m/%d/%Y')), class: "datepicker" %>

最初正确显示03/31/2012,但在保存时仍然相反。

2)接下来我尝试更改存储日期的默认方式,认为可以解决问题。正如this question的答案中所述,我在 config / locales / en.yml 中添加了以下内容:

# config/locales/en.yml
en:
  date:
    formats:
      default: "%m/%d/%Y"

这根本没有任何区别。接下来我找到this question并尝试使用以下行创建 config / initializers / date_formats.rb

Date::DATE_FORMATS[:default]="%m/%d/%Y"
Time::DATE_FORMATS[:default]="%m/%d/%Y %H:%M"

与上述相同,没有区别。

3)在玩了很多组合之后,我发现DID工作的一件事是在我调用datepicker插件时指定yyyy-mm-dd格式 - 它与我想要的相反,但至少是日期可以成功保存。所以datepicker调用如下所示:

$( ".datepicker" ).datepicker({ dateFormat: 'yy-mm-dd' });

从日历中选择3月31日将使用2012-03-31填充该字段,并在保存后仍显示为2012-03-31。

但是我怎样才能让日期选择器以mm / dd / yy格式工作?我无法想象这是一件困难的事情,但我错过了什么?我是否必须对Postgres中的日期存储方式做些什么? (它们被指定为日期,而不是日期时间。)

3 个答案:

答案 0 :(得分:3)

这取决于您在数据库中存储数据的方式。 如果您碰巧使用 RAW sql查询,则可以在插入查询中使用to_date('31 Mar 2012', 'DD Mon YYYY')

Postgres'to_date reference

现在,在您的客户端,您可以使用

在jquery日期选择器中
$.datepicker.formatDate('dd-M-yy', Yourdate);

我使用了DD Mon YYYY,因为它看起来更清晰。您可以根据需要使用mm/dd/yy格式或其他格式。在这些情况下,请在postgre的to_date函数中使用必需的 格式

请注意,我还没有测试过上面的代码。如果有任何问题或您遇到任何麻烦,请留下评论。

编辑:

您可以在rails视图中使用Date.parse('2011-06-18'),然后再将数据插入数据库,并在datepicker中将formatDate设置为'yy-mm-dd'

答案 1 :(得分:0)

如果要全局更改数据库群集的默认日期格式,还可以在postgresql.conf中设置DateStyle GUC并重新加载:

datestyle = 'iso, mdy'

(无论如何,这应该是默认值。)

请注意,这不会影响日期在应用中的显示方式。 PostgreSQL如何解释Postgres的模糊输入和一些输出选项。


如果您在(显然)不同的连接中检查psql中的datestyle设置,则不能证明任何内容。您的应用可能正在设置与本地设置相关的其他datestyle。您必须检查实际连接内的设置(而不是psql)。

如果您的日期风格设置为'iso, mdy',那么它应该按照您的意愿运行:日期文字被解释为一个月前的。考虑一下这个演示(使用PostgreSQL 9.1):

db=# set datestyle = 'ISO, MDY';
SET
db=# select '1.12.2012'::date;
    date
------------
 2012-01-12
(1 row)

db=# set datestyle = 'ISO, DMY';
SET
db=# select '1.12.2012'::date;
    date
------------
 2012-12-01
(1 row)

强调我的。

要了解您的应用实际设置了哪些选项,您可以设置

log_statement = all

postgresql.conf并重新加载。然后启动您的应用并保存日期。将记录每个命令。不要忘记之后重置和重新加载(或者您的日志文件可能会变得很大):

log_statement = none

然后检查您的数据库日志文件您的应用实际发送到数据库的内容。


您可能还对to_date()命令感兴趣,该命令可让您以任何您喜欢的格式输入日期文字。但你不应该那样。

答案 2 :(得分:0)

我遇到了与原始海报相同的问题。由于我必须相互比较日期/时间,所以我不想将数据库字段更改为字符串,因为这将需要额外的代码和转换。

我最终在我的模型中使用了before_save和attr_accessor,如下所示:

before_save    :format_date
attr_accessor  :unformatted_date

def format_date
  self.inquiry_date = Date.strptime(self.unformatted_date, "%m/%d/%Y").to_time(:utc)
end

我视图中的这一行如下所示:

f.text_field  :unformatted_date, :value => (@foo.inquiry_date.blank? ? '' : @foo.inquiry_date.strftime('%m/%d/%Y)), :id => 'datepicker'