Как избежать хранения объектов даты в массиве в Ruby? - PullRequest
0 голосов
/ 02 ноября 2018

Рассмотрим код ниже:

dates = ["20th OCT 1232", "6th JUN 2019", "23th AUG 2017", "9th JAN 2015"]

def reformateDate(dates)
    ans = []
    dates.length.times do |i|
        ans << (DateTime.parse(dates[i], '%d %b %Y').to_date)
    end
    ans
end

Эта функция возвращает массив в следующем формате:

[#<Date: 1232-10-20 ((2171339j,0s,0n),+0s,2299161j)>, #<Date: 2019-06-06 ((2458641j,0s,0n),+0s,2299161j)>, #<Date: 2017-08-23 ((2457989j,0s,0n),+0s,2299161j)>, #<Date: 2015-01-09 ((2457032j,0s,0n),+0s,2299161j)>]

Но я хочу, чтобы он возвращал массив в следующем формате:

["1232-10-20","2019-06-06","2017-08-23","2015-01-09"]

Так как я могу это сделать?

Ответы [ 3 ]

0 голосов
/ 02 ноября 2018

Я бы сделал что-то вроде этого:

require 'date'

def reformat_date(dates)
  dates.map { |date| Date.parse(date).to_s }
end

dates = ["20th OCT 1232", "6th JUN 2019", "23th AUG 2017", "9th JAN 2015"]
reformat_date(dates)
#=> ["1232-10-20", "2019-06-06", "2017-08-23", "2015-01-09"]
0 голосов
/ 02 ноября 2018

Ну, вы на самом деле храните объекты Date, когда пишете:

ans << (DateTime.parse(dates[i], '%d %b %Y').to_date)

Есть несколько проблем с этим: во-первых, скобки ничего не делают, поэтому вы можете удалить их. Во-вторых, вы анализируете строку в объект DateTime, а затем конвертируете ее в объект Date. Не совсем уверен, зачем ты это сделал, но я считаю, что это ошибка. Если вы хотите преобразовать это в строку, временно используя объекты DateTime, рассмотрите возможность использования strftime, которая возьмет объект DateTime и превратит его в строку с определенным форматом. Это будет выглядеть так:

ans << DateTime.parse(dates[i], '%d %b %Y').strftime('%Y-%m-%d')

0 голосов
/ 02 ноября 2018
dates.map { |e| Date.parse(e).strftime('%Y-%m-%d') }
#=> ["1232-10-20", "2019-06-06", "2017-08-23", "2015-01-09"]

Измените шаблон '%Y-%m-%d' в соответствии с вашими потребностями, см. Это для справки: Дата # strftime .


Принятие мудрого предложения от Кэри Свовеланд.

Вместо Date.parse(e) вы можете использовать Date.strptime(e, '%dth %b %Y'), который работает более или менее наоборот strftime. См. Date # strptime . Он следует шаблону ('%dth %b %Y') для интерпретации исходной строки как даты. Добавление th к шаблону после %d (дня) приводит к правильному преобразованию текущего формата в объект даты:

Date.strptime("20th OCT 1232", '%dth %b %Y') #=> #<Date: 1232-10-20 ((2171339j,0s,0n),+0s,2299161j)>

Но что, если дата будет '1st OCT 2018' или '23rd OCT 2018'? Шаблон не соответствует, потому что он ожидает найти th, а не st или rd.

Чтобы быть порядковым суффиксом , приходит в руки метод String # sub :

"20th OCT 1232".sub(/(?<=\d)\p{Alpha}+/, '') #=> "20 OCT 1232"

Итак, смешивая все вместе, лучшее решение для безопасности должно быть:

dates.map { |e| Date.strptime(e.sub(/(?<=\d)\p{Alpha}+/, ''), '%d %b %Y').strftime('%Y-%m-%d') }
...