标题几乎说明了一切。我正在尝试评估CSV导入日期的有效性,但如果有人选择电话号码列作为出生日期,则日期解析仍会通过
答案 0 :(得分:6)
如何:Date.parse(“ 123 456 789”)== 2019年5月3日,星期五?
Date._parse
(带有下划线)返回原始数据:
Date._parse('123 456 789')
#=> {:yday=>123}
Ruby将123
视为一年中的某一天,而当年的第123天是5月3日。
答案 1 :(得分:4)
Date#parse
上的文档明确指出:
此方法不能用作验证器。
这意味着该方法是杂项的,它将根据任何输入产生一个日期。您需要改用Date#iso8601
:
main > Date.iso8601("2019-03-19")
#⇒ #<Date: 2019-03-19 ((2458562j,0s,0n),+0s,2299161j)>
main > Date.iso8601("123 456 789")
#⇒ ArgumentError: invalid date
答案 2 :(得分:0)
您(可能还有其他人)可能会发现以下方法很有用。我做了以下假设:
MON_NAMES = Date::MONTHNAMES.drop(1).concat(Date::ABBR_MONTHNAMES.drop(1))
#=> ["January", "February", "March", "April", "May", "June",
# "July", "August", "September", "October", "November", "December",
# "Jan", "Feb", "Mar", "Apr", "May", "Jun",
# "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
MON_REGEX = /\b#{Regexp.union(MON_NAMES)}\b(?!\A)/
# => /\b(?-mix:January|February|...|December|Jan|Feb|...|Dec)\b(?!\A)/
MONTH_STR_TO_NBR = MON_NAMES.each_with_index.map { |mon,i| [mon, " #{1 + (i%12)} "] }.to_h
#=> {"January"=>" 1 ", "February"=>" 2 ", ... , "December"=>" 12 ",
# "Jan"=>" 1 ", "Feb"=>" 2 ", ... , "Dec"=>" 12 "}
DAY_REGEX = /\b#{Regexp.union(Date::DAYNAMES + Date::ABBR_DAYNAMES)}\b,?/
#=> /\b(?-mix:Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sun|Mon|Tue|Wed|Thu|Fri|Sat)\b,?/
def my_parse(date_str, locale = :US)
a = date_str.gsub(MON_REGEX, MONTH_STR_TO_NBR).
gsub(DAY_REGEX, '').
gsub(/(?<!\p{Alpha})(?:st|rd|th|,)(?!\p{Alpha})/, '').
gsub(/[-\/]/, ' ').
strip.
split
return nil if a.size != 3 || a.any? { |s| s.match?(/\D/) }
yr_idx = a.index { |s| s.size == 4 }
return nil if yr_idx.nil? || yr_idx == 1
yr = a.delete_at(yr_idx)
return nil unless a.all? { |s| [1,2].include? s.size }
if yr_idx == 0
mon, day = a
else
mon, day = locale == :US ? a : a.reverse
end
begin
Date.strptime("%s %s %s" % [mon, day, yr], '%m %d %Y')
rescue ArgumentError
nil
end
end
my_parse("Tue, 12th January 2019") #=> #<Date: 2019-01-12 (...)>
my_parse("Tue, 12th January 2019", :UK) #=> #<Date: 2019-12-01 (...)>
my_parse("12/4/2019", :US) #=> #<Date: 2019-04-12 (...)>
my_parse("12/4/2019", :UK) #=> #<Date: 2019-12-04 (...)>
my_parse("Jan 12, 2019") #=> #<Date: 2019-12-01 (...)>
my_parse("2019 Jan 23rd") #=> #<Date: 2019-01-23 (...)>
my_parse("Jan 2019 4") #=> nil
my_parse("1/2019/4") #=> nil
my_parse("1/2019/4") #=> nil
my_parse("Jen 12, 2019") #=> nil
my_parse("3 Jan 12, 2019") #=> nil
我鼓励读者找出我没有提到的其他假设。当然可以根据需要进行修改。可以很容易地进行一项更改,就是确认星期几(如果存在)对于给定日期是正确的。