如何使用Ruby将MongoDB中的字符串存储为Date类型?

我有一个字符串,我正在从日志文件中解析出来,如下所示:

“[22 / May / 2011:23:02:21 +0000]”

什么是最好的方法(Ruby中的例子最受欢迎,因为我正在使用Mongo Ruby驱动程序)将MongoDB作为本机日期类型存储起来?

require 'date' # this is just to get the ABBR_MONTHNAMES list input = "[22/May/2011:23:02:21 +0000]" # this regex captures the numbers and month name pattern = %r{^\[(\d{2})/(\w+)/(\d{4}):(\d{2}):(\d{2}):(\d{2}) ([+-]\d{4})\]$} match = input.match(pattern) # MatchData can be splatted, which is very convenient _, date, month_name, year, hour, minute, second, tz_offset = *match # ABBR_MONTHNAMES contains "Jan", "Feb", etc. month = Date::ABBR_MONTHNAMES.index(month_name) # we need to insert a colon in the tz offset, because Time.new expects it tz = tz_offset[0,3] + ':' + tz_offset[3,5] # this is your time object, put it into Mongo and it will be saved as a Date Time.new(year.to_i, month, date.to_i, hour.to_i, minute.to_i, second.to_i, tz) 

有几点需要注意:

  • 我假设月份名称与ABBR_MONTHNAMES列表中的名称相同,否则,只需创建自己的列表。
  • 永远不要使用Date.parse来解析它非常慢的DateTime.parseTime.parse使用相同实现的DateTime.parseTime.parse也是如此。
  • 如果你解析了很多不同的日期格式,请查看home_run gem。
  • 如果您执行了很多这些操作(就像解析日志文件时经常那样),请考虑不使用正则表达式。 使用String#index#[]#split来提取所需的部分。

如果您想尽快做到这一点,以下内容可能更合适。 它不使用正则表达式(这是有用的,但不是很快):

 date = input[1, 2].to_i month_name = input[4, 3] month = Date::ABBR_MONTHNAMES.index(month_name) year = input[8, 4].to_i hour = input[13, 2].to_i minute = input[16, 2].to_i second = input[19, 2].to_i tz_offset = input[22, 3].to_i * 60 * 60 + input[25, 2].to_i * 60 Time.new(year, month, date, hour, minute, second, tz_offset) 

它利用了所有字段都具有固定宽度的事实(至少我认为它们确实如此)。 所以你需要做的就是提取子串。 它还将时区偏移量计算为数字而不是字符串。