Rails3/jQuery UI Datepicker - 月份和日期在保存时反转
Posted
技术标签:
【中文标题】Rails3/jQuery UI Datepicker - 月份和日期在保存时反转【英文标题】:Rails3/jQuery UI Datepicker - Month and day are reversed on save 【发布时间】:2012-04-19 14:47:25 【问题描述】:(我的问题与described in this question 几乎相同,只是那个答案在我的情况下不起作用。)
我在带有 Postgres 数据库的 Rails 应用程序中使用 jQuery UI Datepicker。默认实现使用 mm/dd/yy 日期格式来显示所选日期,这正是我想要的。但是,在我将记录保存到数据库后,月份和日期会反转 - 然后显示为 yy-dd-mm。因此,选择 3/11/2012 会尝试保存为 11 月 3 日而不是 3 月 11 日,并且像 3/31/2012 这样的日期根本不会保存,因为它不存在。
到目前为止,我已经尝试了 3 种不同的方法来解决这个问题:
1) 第一次尝试是重新格式化文本字段,使显示看起来像我想要的那样:
<%= f.text_field :foo, :value => (@model.foo.blank? ? '' : @model.foo.strftime('%m/%d/%Y')), class: "datepicker" %>
最初正确显示 2012 年 3 月 31 日,但保存时仍显示相反。
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 中的存储方式做些什么? (它们被指定为日期,而不是日期时间。)
【问题讨论】:
为了停止在这个问题上撞墙,我刚刚将我的字段切换为“文本”而不是“日期”。这并不理想,但确实可以相当简单地解决问题。 有时切换是一个很好的解决方案,无论它是否理想。但仍然出于好奇,您可能想知道问题所在,可能会在以后。 Rails 3.2.3、Postgresql 和 Ruby 1.9.3。我将 datepicker 格式设置为 mm-dd-yy 并且它工作了一段时间,但我正在进行重构,我可以毫不费力地保存一些日期,但特别是不再保存一个日期。所以我要重新格式化回 yy-mm-dd 看看会发生什么。 更新:我在 datepicker 调用中尝试了 yy-mm-dd 格式,但仍然得到“日期不能为空”。我很困惑,但是由于没有其他解决方案,我将运行迁移来更改日期的数据类型,也可以像您所做的那样更改文本……希望我或某人能找到解决方案。 我的经历几乎完全相同,结果也一样。在 Rails 3.0 中对我有用的是 Date::DATE_FORMATS[:default],但是,在升级到 Rails 3.2 后,这不再有效。就我而言,我认为问题归结为:"01/03/13".to_date.to_s --> "03/01/13"
这似乎很愚蠢
【参考方案1】:
这取决于您在数据库中存储数据的方式。
如果您碰巧使用 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
函数中使用所需的格式
请注意,我没有测试过上面的代码。如果有任何问题或遇到任何麻烦,请离开 cmets。
编辑:
您可以在 Rails 视图中使用Date.parse('2011-06-18')
,然后将数据插入数据库并在日期选择器中将formatDate
设置为'yy-mm-dd'
。
【讨论】:
我可能不明白你在说什么,但我尝试编写一个 before_save 方法来重新排列插入数据库之前的日期。这听起来像是可行的,但由于某种原因,我在尝试保存任何日期超过 12 的日期时仍然出错。我知道这一定是因为它试图切换日期和月份,但我不能找出发生在哪里。 在日志中查看由 rails 生成的查询(以及日期列的值)。以便知道,实际上是什么方面的问题【参考方案2】:如果您想为您的数据库集群全局更改默认日期格式,您还可以在postgresql.conf
中设置DateStyle GUC 并重新加载:
datestyle = 'iso, mdy'
(无论如何都应该是默认值。)
请注意,这不会影响日期在您的应用中的显示方式。 PostgreSQL 如何解释 Postgres 的模棱两可的输入和一些输出选项。
如果您在(显然)不同的连接中检查 psql 中的datestyle
设置,那并不能证明任何事情。您的应用程序可能正在设置与本地设置相关的不同 datestyle
。您必须检查实际连接中的设置(不是来自 psql)。
如果您的日期样式设置为'iso, mdy'
,那么它应该可以按照您的意愿工作:日期文字被解释为month-before-day。考虑这个演示(使用 PostgreSQL 9.1):
强调我的。
要了解您的应用实际设置了哪些选项,您可以设置
log_statement = all
在您的postgresql.conf
中并重新加载。然后启动您的应用程序并保存日期。每个命令都将被记录。之后不要忘记重置并重新加载(否则您的日志文件可能会变得很大):
log_statement = none
然后检查您的数据库日志文件,您的应用实际发送到数据库的内容。
您可能还对to_date()
命令感兴趣,该命令可让您以您喜欢的任何格式输入日期文字。但你不应该需要那个。
【讨论】:
我在 psql 中做了show datestyle;
并获得了 ISO、MDY,所以看起来这已经是正确的了。
在不同的连接中签入psql
几乎不能证明任何事情。我在答案中添加了更多信息。【参考方案3】:
我遇到了与原始海报相同的问题。由于我必须相互比较日期/时间,我不想将 DB 字段更改为字符串,因为这将需要额外的代码和稍后的转换。
我最终在我的模型中使用了 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'
【讨论】:
以上是关于Rails3/jQuery UI Datepicker - 月份和日期在保存时反转的主要内容,如果未能解决你的问题,请参考以下文章
未捕获的类型错误:$(...).datepick 不是 asp.net 中 jQuery datetime 中的函数
带有引导程序 ui-datepicker 的 Angularjs
使用 jQuery UI datepicker 选择日历更改 URL