Вы (и, возможно, другие) можете найти следующий метод полезным.Я сделал следующие предположения:
- годы должны быть четырьмя цифрами;
- недопустимые запятые могут игнорироваться и удаляться (например, «Jan, 3 2019»);и
- день недели можно игнорировать и удалять, даже если он недействителен для даты.
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
Я бы посоветовал читателям указать любые другие предположения, которые я не упомянул.Это, конечно, может быть изменено по мере необходимости.Одним из изменений, которое можно было бы сделать довольно легко, было бы подтвердить, что день недели, если он присутствует, является правильным для данной даты.