2017-02-15 26 views
0

Я работаю над написанием помощника для синтаксического анализа строк даты, которые мне даны в CSV. Проблема в том, что они несовместимы в том, как они отформатированы. Есть три различных формата:Разбор строк с форматированными цифрами

  • "01021992" (%m%d%Y)
  • "19920201" ("%Y%m%d")
  • "PORSCHE" (или какой-либо другой случайное слово)

Ниже функция что я написал, чтобы помочь мне разобрать даты.

class DateTimeParser 
    require "date" 
    require 'active_support/all' 
    require 'byebug' 

    class Object 
    def blank? 
     return self == nil || self == "" 
    end 
    end 

    def parse_string_date 
    date_str = "01021992" 
    formats = ["%Y%m%d", "%m%d%Y"] 
    date = nil 

    formats.each do |form| 
     begin 
     date = DateTime.parse(date_str, form) 
     break 
     rescue => e 
     puts "ERROR: #{e}" 
     puts "Failed for #{date_str} with format #{form}" 
     end 
    end 

    #this should handle the case where the date is just a word (i.e. "PORSCHE") 
    if date.nil? 
     date = DateTime.parse("03141994", "%m%d%Y") 
    end 

    date = date.change(:offset => "+0500") 
    puts "Date : #{date}" 
    end 

    DateTimeParser.new().parse_string_date 
end 

Возможные материалы были представлены выше, если вы хотите запустить это и изменить значение date_str

ВЫВОД:

ERROR: invalid date 
Failed for 01021992 with format %Y%m%d 
ERROR: invalid date 
Failed for 01021992 with format %m%d%Y 

Я думаю, что моя беда в том, что я не могу показаться, определите, какие правильные форматы вы можете передать до parse.

+2

Вместо 'DateTime.parse (date_str, form)' Try' DateTime.strptime (date_str, form) ' –

+1

вам также нужно изменить логику в' format.each do .... ', поскольку один из двух 'formats' будет успешно проанализирован для одного' date_str'. Попробуйте изменить порядок «форматов», чтобы увидеть, что 'parse_string_date' действительно успешно разбирает' date_str', если '% m% d% Y' является первым элементом –

+0

@ImranAli Спасибо за вашу помощь. Похоже, что это сработает! –

ответ

0

Вместо случайно пытаются вещи, почему бы не установить некоторые закономерности и шаблоны:

FORMATS = { 
    /\A(19|20)\d{2}\d{2}\d{2}\z/ => '%Y%m%d', 
    /\A\d{2}\d{2}(19|20)\d{2}\z/ => '%m%d%Y' 
} 

Тогда вы можете попробовать декодирования таким образом:

format = FORMATS.find do |rx, _| 
    rx.match(date_str) 
end 

format and DateTime.parse(date_str, format[1]) 

Вы можете добавить другие форматы в том, что, плюс «независимо», когда вы сдаетесь и возвращаете строку как есть.