【问题标题】:Figure date format from string in rubyruby中字符串的数字日期格式
【发布时间】:2014-07-26 15:43:24
【问题描述】:

我正在为文本文件编写一个简单的数据加载器,并希望添加一个功能以将日期正确加载到表中。我遇到的问题是我事先不知道日期格式,并且它不会是我的脚本进行插入 - 它必须生成插入语句以供以后使用。

Date.parse 几乎是我所需要的。如果有办法以一种我可以用来生成to_date(...)(Oracle 标准)的方式获取它在字符串上标识的格式,那将是完美的。

一个例子:

我的输入文件:

user_name;birth_date
Sue;20130427
Amy;31/4/1984

应该生成:

insert into my_table values ('Sue', to_date('20130427','yyyymmdd'));
insert into my_table values ('Amy', to_date('31/4/1984','dd/mm/yyyy'));

请注意,原始字符串保持不变很重要 - 所以我无法将其解析为插入中使用的标准格式(这是一项要求)。

目前我只是在测试一堆正则表达式并进行一些验证,但我想知道是否有更强大的方法。

【问题讨论】:

  • 有趣的问题,说得好。
  • 如何使用Date#strptime:遍历可能的格式字符串范围,直到返回日期对象?当然,您必须 rescue 例外。
  • 这是不可能的。给定3/7/1984,你怎么知道这是 1984 年 3 月 7 日还是 1984 年 7 月 3 日?给定050601,您怎么知道这是 2001 年 5 月 6 日、2001 年 6 月 5 日还是 2005 年 6 月 1 日等?
  • @sawa,除非它总是一个或另一个,遵循一个规则,考虑到它来自输入文件,我认为这很可能。菲利普?
  • @sawa 我的文件会有很多样本,我总是可以假设我至少有一个明确的日期可以使用。除了文件中的日期格式保持不变之外(尽管它可能会因文件而异)

标签: ruby oracle datetime-format


【解决方案1】:

假设(例如使用String#scan),您从单个文件中提取了一个日期字符串数组。可能是这样的:

strings = ["20130427", "20130102", ...]

提前准备你能想到的所有格式的数组。可能是这样的:

Formats = ["%Y%m%d", "%y%m%d", "%y/%m/%d", "%m/%d/%y", "%d/%m/%y", ...]

然后检查所有可以解析所有字符串的格式:

require "date"
formats =
Formats.select{|format| strings.all?{|s| Date.strptime(s, format) rescue nil}}

如果这个数组formats 只包含一个元素,那么这意味着字符串被明确地解析为该格式。使用该格式,您可以返回字符串并使用该格式解析它们。

否则,要么您未能在 Formats 中提供适当的格式,要么字符串仍然不明确。

【讨论】:

  • 注意OP示例的第一行;没有匹配可能没问题。由于文件中的所有记录都具有相同的日期格式,我认为您可以通过读取记录直到日期字符串完全匹配一种格式(可能是第一条记录)来提高效率。如果第一条记录匹配(比如说)两种格式,而随后的记录不匹配这两种格式,那么您遇到了数据问题。如果所有记录都匹配相同(例如)两种日期格式,则歧义仍然存在。是否要检查文件以确保日期格式的一致性是一个单独的问题。
  • 从 OP 的 cmets 中,我了解到每个文件都保证了一致性。
  • 我还是不明白你为什么需要strings.all?。以下不是更有效吗? formats = Formats.select {|f| <strings.first match f> }。如果formats.size 为零或一,你就完成了;否则str = strings[1..-1].find { |s| <s matches zero or one of the formats in formats> }。在最后一种情况下,如果strnil,则存在歧义,否则fmt = formats.select {|f| <str match f> } 和格式为fmt.first,如果fmt.size 为1,则数据存在问题。
  • @sawa 很酷。尽管它几乎在测试一堆格式(就像我目前正在做的那样),但它看起来更好并且可以处理 mm/dd|dd/mm 问题。已经比我的好。谢谢!
【解决方案2】:

我会使用Chronic gem。它将提取大多数格式的日期。

它具有解决 xx/xx/xxxx 格式的歧义的选项,但您必须指定在任一匹配时首选哪个。

【讨论】:

  • 您必须指定要使用的 [格式]——OP 正在询问如何自动执行此操作。这就是问题的全部意义所在。
  • 我认为它回答了他的问题,但他的后续 cmets 表明他需要根据每个文件确定首选哪种格式,这就是您的答案所涵盖的内容。结合我的答案和你的答案会给他一个 100% 的解决方案。
  • 马克,问题是filippo需要一个日期字符串对应的格式字符串,我不认为那个gem提供了。
  • 确实,这是一个奇怪的要求。我会挑战对它的需求。为什么不创建规范化的 SQL 插入字符串?如果在输出中需要,可以在 cmets 中包含原始字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-09
  • 1970-01-01
  • 2015-07-23
  • 2014-04-26
  • 2016-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多