如何在Rails中设置日期时间格式

Mar*_*ser 3 activerecord datetime ruby-on-rails

我正在使用js日历将字符串插入文本字段以提交为日期时间值.不确定它是否重要但我现在正在使用SQLite.

我将格式设置如下(在初始化程序中):

Time::DATE_FORMATS[:default] = '%m/%d/%Y %H:%M'
Time::DATE_FORMATS[:db] = '%m/%d/%Y %H:%M'
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为Rails显然使用不同的格式验证日期.

例如,如果我按如下方式设置它:

myobject.my_datetime = '06/30/2012 00:00'
Run Code Online (Sandbox Code Playgroud)

它最终为null(ActiveRecord生成的SQL查询本身将其设置为NULL).如果我将它设置为小于或等于12的日期,则日期部分结束正确(但生成的SQL查询仍显示月份前一天的字符串,即在上面的示例中,SQL查询的字符串为'30/06/2012 05:00:000000').

正如你所看到的那样,即使我将config.time_zone设置为东部时间,它似乎也为UTC(?)增加了5个小时.

行为是从控制台或通过表单提交相同.

关于我缺少什么的任何建议?

更新:

当我遵循jdoe的建议并执行此操作时:

myobject.my_datetime = Time.strptime('06/30/2012 08:00','%m /%d /%Y%H:%M')

生成的查询现在看起来正确(忽略4小时的差异):

UPDATE "myjoin_table" SET "my_datetime" = '06/30/2012 04:00.000000' .....
Run Code Online (Sandbox Code Playgroud)

它以这种方式在数据库中结束.

但是当我重新加载对象时,AR对象中的值被初始化为nil.

我想我只是在我的控制器动作中逐个解析字符串并手动将参数设置为update_attributes.这比应该的更难.

jdo*_*doe 6

ActiveRecord以UTC + 00:00存储日期/时间.如果您居住在+5区域,ActiveRecord将自动分配5个小时.因此,您当前的时区只是说明您需要在当地时间加/减多少小时.

关于解析.你试过以下吗?

myobject.my_datetime = Time.strptime('06/30/2012 00:00', '%m/%d/%Y %H:%M')
Run Code Online (Sandbox Code Playgroud)

Rails时间/日期设置用于显示,而不是用于分配.从用户那里获取字符串并将它们分配给您的日期/时间属性并不是一个好主意.你最好在分配中使用适当的时间对象而不是叮咬.如果某个用户试图成为黑客,该strptime方法将提高ArgumentError.你record.date_time='string'无声地失败了.


UPD:用法示例

p = Product.first
p.last_visited = Time.strptime('06/30/2012 00:00', '%m/%d/%Y %H:%M')
p.save # leads to UPDATE "products" SET "last_visited" = '2012-06-29 21:00:00.000000'
Product.last_visited.localtime.strftime('%m/%d/%Y %H:%M') # => "06/30/2012 00:00"
Run Code Online (Sandbox Code Playgroud)

如您所见,存储和检索时间没有任何问题.

UPD 2:I18n

找到你的config/locales/en.yml.添加以下内容:

en:
  time:
    formats:
      default: '%m/%d/%Y %H:%M'
Run Code Online (Sandbox Code Playgroud)

解析你的时间使用t(或translate)帮助:

@time = Time.strptime('06/30/2012 00:00', t('time.formats.default'))
Run Code Online (Sandbox Code Playgroud)

使用l(或localize)帮助器以您的格式显示时间:

= l @time
Run Code Online (Sandbox Code Playgroud)