如何使用Ruby在MongoDB中将字符串存储为Date类型? [英] How do you store a string in MongoDB as a Date type using Ruby?

查看:77
本文介绍了如何使用Ruby在MongoDB中将字符串存储为Date类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a string that I'm parsing out from log files that looks like the following:

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

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

什么是最好的方法(最好使用Ruby中的示例,因为我使用的是Mongo Ruby驱动程序)将其作为本机Date类型存储在MongoDB中?

What's the best way (examples in Ruby would be most appreciated, as I'm using the Mongo Ruby driver) to get that stashed into MongoDB as a native Date type?

推荐答案

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也是如此.
  • 如果您解析许多不同的日期格式,请查看 home_run gem.
  • 如果您做很多这样的事情(就像您在解析日志文件时经常做的那样),请考虑不使用正则表达式.使用String#index#[]#split提取所需的零件.
  • I assumed that the month names are the same as in the ABBR_MONTHNAMES list, otherwise, just make your own list.
  • Never ever use Date.parse to parse dates it is incredibly slow, the same goes for DateTime.parse, Time.parse, which use the same implementation.
  • If you parse a lot of different date formats check out the home_run gem.
  • If you do a lot of these (like you often do when parsing log files), consider not using a regex. Use String#index, #[] and #split to extract the parts you need.

如果您想尽快执行此操作,则以下内容可能更合适.它不使用正则表达式(有用,但速度不快):

If you want to do this as fast as possible, something like the following is probably more appropriate. It doesn't use regexes (which are useful, but not fast):

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)

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

It takes advantage of the fact that all fields have fixed width (at least I assume they do). So all you need to do is extract the substrings. It also calculates the timezone offset as a number instead of a string.

这篇关于如何使用Ruby在MongoDB中将字符串存储为Date类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆