Прочитайте мою дату в свободной форме

10

Учитывая дату, записанную в любом (должен обрабатывать все в одной и той же программе) из следующих форматов, проанализируйте ее в действительном yyyy/mm/dd date.

17th May 2012
March 14th, 2016
20 February 2014
September 14, 2017
Sunday, June 8, 2015

правила

  • Даты иногда будут недействительными, т.е. неправильный день для месяца или количество месяцев в году, вы должны обработать оба случая. Выбираете ли вы ошибку или возвращаете постоянное значение Falsey. (Однако они будут придерживаться шаблонов форматов выше)
  • Заполнение для дней и месяцев менее 10 должно использоваться для создания двузначного вывода.
  • Названия месяцев всегда будут полными, а не сокращенными до трехзначных.
  • Вы можете предположить, что год всегда будет в диапазоне 0000-9999.
  • Отрицательные числа не должны быть обработаны.
  • Вы можете создать полную программу или функцию, чтобы вывод мог быть в любом формате, распечатан на консоль или возвращен из функции.
  • Ввод всегда будет строкой, выход всегда должен быть строкой, если это делает его короче, чтобы он воспринимался как один аргумент в массиве, например. ["17th May 2012"]Вы можете сделать это, и результат может быть таким же["2012/05/17"]
  • Вы можете предположить, что правописание при вводе будет правильным.

БОНУС: потому что, кто здесь не любит вызов;)

Если вам удастся также разрешить входные форматы The Fourteenth of March, 2016или March the Fourteenth, 2016вы можете удалить из своего кода дополнительные 20 байтов с любым конечным числом байтов, меньшим 1, что приведет к 1.

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

First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Nineth, Tenth, Eleventh, Twelfth, Thirteenth, Fourteenth, Fifteenth, Sixteenth, Seventeenth, Eighteenth, Nineteenth, Twentieth, Twenty First, Twenty Second, Twenty Third, Twenty Fourth, Twenty Fifth, Twenty Sixth, Twenty Seventh, Twenty Eighth, Twenty Nineth, Thirtieth, Thirty First

Тестовые случаи

INPUT                           | Output
17th May 2012                   | 2012/05/17
March 14th, 2016                | 2016/03/14
20 February 2014                | 2014/02/20
September 14, 2017              | 2017/09/14
Sunday, June 8, 2015            | 2015/06/08
1st January 1918                | 1918/01/01

The Fourteenth of March, 2016   | 2016/03/14
March the Fourteenth, 2016      | 2016/03/14
November the Seventeenth, 2019  | 2019/11/17
The Thirtieth of April, 2016    | 2016/04/30

30 February 2014                | Invalid
September 99, 2017              | Invalid
Sunday, June8, 2015             | Invalid

The Thirty First of April, 2016 | Invalid
MysticVagabond
источник
10
« потому что здесь не нравится испытание » - когда они приходят в виде бонуса, в основном все мы не делаем! И бу-урны для проверки ввода.
Лохматый
3
@ Mr.Xcoder Я думаю , что вся задача состоит в том, чтобы поддерживать несколько форматов входных .. Такие вещи , как 20 February 2014это по умолчанию поддерживается в много финиковых анализаторах, но 17thи Sunday, June 8, 2015немного более трудно разобрать ( в зависимости от языка).
Кевин Круйссен
1
@ Mr.Xcoder Я никогда не говорил, что это было весело / скучно, легко / сложно, хорошо / плохо - игра в гольф. Я просто констатирую, что, исходя из того, что я прочитал в задании, поддержка множественного формата ввода является основной целью задания. Я согласен, что, скорее всего, это будет if-else для пяти входных форматов или какое-то регулярное выражение для извлечения года, месяца и дня (что в настоящее время является моим подходом).
Кевин Круйссен
3
Всегда ли правильный день недели? Будет Thursday, August 25, 2017действительным? Я вижу представления, игнорирующие DOW.
Бенджамин

Ответы:

4

Рельсы, 41 , 37 35 байт

->x{x.to_date.strftime('%Y/%m/%d')}

Я не знаю онлайн-переводчика для Rails, но вот скриншот, демонстрирующий этот процесс

введите описание изображения здесь

Suever
источник
Ссылка онлайн переводчика?
Джонатан Аллан
1
Это действительно работает для всех рассматриваемых форматов? : o
полностью человек
@totallyhuman Добавлен скриншот с результатами. К сожалению, я не знаю онлайн-переводчика :(
Suever
8

PowerShell , 91 89 91 56 байт

date("$args"-replace'th|rd|st|(\b.*)day|,')-f yyyy/MM/dd

Попробуйте онлайн!

Принимает ввод в виде строки. Использует a, -replaceчтобы избавиться от мусора, затем использует встроенную Get-Dateкоманду с -fфлагом ormat, чтобы указать требуемый yyyy/MM/ddформат. Эта строка остается в конвейере и вывод неявный.

Сохранено два байта благодаря мистеру Xcoder. Сохранение огромного куска благодаря регулярному игре в гольф TessellatingHeckler.

AdmBorkBork
источник
1
Эй, посмотрите конкурентоспособную подачу PowerShell!
Эрик Outgolfer
@EriktheOutgolfer Манипулирование датами - одна из сильных сторон PowerShell.
AdmBorkBork
@ Mr.Xcoder "все те" = 2. LOL. Спасибо!
AdmBorkBork
Вы можете удалить ''из формата даты, для -2. Если вы хотите придерживаться своего подхода, учитывая «правильное написание», то вы можете заменить 'th|rd|st|(\b.*)day|,'его, и оно уменьшается до 56 байт и обрабатывает те же случаи. Хотя я думаю, что это неправильно, потому что, если вы отбросите дни, вы не сможете взять Sunday, June8, 2015 | Invalidдело, потому что это был понедельник. Должно появиться сообщение об ошибке, но оно анализируется как действительное. Не уверен, какое решение будет принято, или если другие проверяют это.
TessellatingHeckler
4

PHP, 73 164 + 1 байт

for(preg_match("#(\d+)[^\d]+(\d+)#",$d=$argn,$r);$m++<12;)strpos(_.$d,date(F,strtotime($r[2].-$m)))&&printf(checkdate($m,$r[1],$r[2])?"$r[2]/%02d/%02d":E,$m,$r[1]);

Запустите как трубу с -nRили попробуйте онлайн .

Проверка даты была действительно дорогой: мне пришлось разобрать дату перед использованием встроенной функции, затем попытаться с ошибкой в ​​названии месяца.

Titus
источник
Я думаю, что вы должны поддерживать все форматы, а не только один из них?
Эрик Outgolfer
1
@EriktheOutgolfer это делает. Но не бонусные форматы.
Тит
@EriktheOutgolfer Это обрабатывает все форматы.
Мистер Кскодер
1
Это не подходит для недействительных дат. 30 February 2014возвращается 2014/03/02. Выбираете ли вы ошибку или возвращаете постоянное значение Falsey. (Однако они будут придерживаться шаблонов форматов выше)
Mr. Xcoder
@ Mr.Xcoder Это все разрушает ...
Тит
3

Библиотека Python 3 + parsedatetime, 152 139 155 153 байта

Сохранено 13 байтов благодаря Джонатану Аллану

Добавлено 16 байтов для обработки дат с недопустимыми днями

Сохранено 2 байта путем удаления лямбда-присваивания

lambda s:re.search(f'(^| ){str(h(s)[0].tm_mday)[:2]}[^\d]',s)and time.strftime('%Y/%m/%d',h(s)[0])
import parsedatetime as p,time,re
h=p.Calendar().parse

Попробуйте онлайн!

Не поддерживает бонусные даты

Noskcaj
источник
Добро пожаловать в PPCG! Хороший первый пост. Сохраните 13 байтов , используя: возвращаемое значение Falsey None; import ...as; & lambda, повторно используя parseкак h.
Джонатан Аллан
1

Python 2 , 193 байта

lambda s:time.strftime('%Y/%m/%d',time.strptime(re.sub(r'^(\w+) (\d+)',r'\2 \1',re.sub('^ ','',re.sub('(th|rd|st)|(Sun|Mon|Tues|Wednes|Thurs|Fri|Satur)day|,','',s))),'%d %B %Y'))
import re,time

Попробуйте онлайн!

; -; пожалуйста Halp

totallyhuman
источник
; -; пожалуйста halp - 192 байт , объявляя time.
г-н Xcoder
1

Java (OpenJDK 8) , 190 + 26 = 216 байт

import java.time.format.*;

s->DateTimeFormatter.ofPattern("uuuu/MM/dd").format(DateTimeFormatter.ofPattern("[EEEE, ][d ]MMMM [d, ]uuuu").withResolverStyle(ResolverStyle.STRICT).parse(s.replaceAll("(\\d)[a-z].","$1")))

Попробуйте онлайн!

Важное примечание: было короче также проверять день недели, а не исключать его, так что проверка включена!

Я не пробовал, SimpleDateFormatкроме очевидных случаев, когда все принимаемые даты, как 30 февраля. Поэтому мне пришлось отказаться от него, и я использовал Java 8 DateTimeFormatter.

объяснение

"[EEEE, ][d ]MMMM [d, ]uuuu"

Этот формат означает:

  • необязательный день недели, за которым следуют запятая и пробел [EEEE, ](происходит в Sunday, ...),
  • затем дополнительный день с пробелом [d ],
  • с последующим месяцем полными буквами MMMMи пробелом,
  • затем необязательный день с запятой и пробелом [d, ],
  • затем год эры, uuuuчтобы дать парсеру понять, что мы находимся в григорианской эре.

Код:

import java.time.format.*;                                     // Required for DateTimeFormatter, *and* ResolverStyle

s->DateTimeFormatter.ofPattern("uuuu/MM/dd")                   // Output format
  .format(
    DateTimeFormatter.ofPattern("[EEEE, ][d ]MMMM [d, ]uuuu")  // Input format
      .withResolverStyle(ResolverStyle.STRICT)                 // Invalidates xxxx-02-30 instead of transforming it into xxxx-02-28
      .parse(
        s.replaceAll("(\\d)[a-z].","$1")                       // remove st, nd, rd, th
       )
    )

кредиты

  • 2 байта в регулярном выражении благодаря Нейлу.
Оливье Грегуар
источник
1
Вам нужны скобки в replaceAllшаблоне?
Нил
Похоже, я не. Спасибо, @Neil!
Оливье Грегуар
1

JavaScript (ES6), 124 122 байта

f=
s=>(d=new Date(s.replace(/.[dht]\b/,'')+' +0')).getDate()==s.match(/\d\d?/)&&d.toISOString().replace(/-(..)(T.*)?/g,'/$1')
<input oninput=o.textContent=f(this.value)><pre id=o>

Нил
источник
Возвращает 2015/06/07для June 8, 2015(UTC проблема? Я в UTC + 2) и falseдля либо Sunday, June 8, 2015или Monday, June 8, 2015.
Оливье Грегуар
1
@ OlivierGrégoire Спасибо, что указали на это. Я пробовал свидания только в Великобритании вне летнего времени, поэтому они уже использовали UTC, и я не пробовал дни недели, заканчивающиеся на nday.
Нил