Прочитайте мою дату у вільній формі


10

З огляду на дату, записану в будь-якому (повинен обробляти всі в одній програмі) наступних форматів, розбери її на дійсний yyyy/mm/dd date.

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

Правила

  • Дати іноді будуть недійсними, тобто. неправильний день за місяць або кількість місяців у році, ви повинні вирішити обидва випадки. Або ви помилившись або повернувши послідовне значення фальси, ви виберете. (Однак вони будуть дотримуватися форматів шаблонів вище)
  • Прокладки для днів і місяців менше 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


10
"Тому, що тут не подобається виклик " - коли вони надходять у вигляді бонусу, в основному всі з нас цього не роблять! І бу-урни для введення перевірки.
Кудлатий

3
@ Mr.Xcoder Я думаю , що вся завдання полягає в тому, щоб підтримувати декілька форматів вхідних .. Такі речі , як 20 February 2014це по замовчуванням підтримується в багато фінікових анализаторах, але 17thі Sunday, June 8, 2015трохи більш важко розібрати ( в залежності від мови).
Kevin Cruijssen

1
@ Mr.Xcoder Я ніколи не говорив, що це весело / нудно, легко / важко, добре / погано виклик коду-гольфу. Я просто констатую, що на основі того, що я прочитав у виклику, підтримка декількох вхідних форматів, здається, є основною метою виклику. Я погоджуюсь, що, швидше за все, це буде інше для п'яти вхідних форматів, або якийсь регулярний вимір для вилучення року, місяця та дня (що зараз є моїм підходом).
Kevin Cruijssen

3
Чи завжди день тижня правильний? Чи Thursday, August 25, 2017було б дійсним? Я бачу матеріали, що ігнорують DOW.
Бенджамін Кунінгем

Відповіді:


4

Рейки, 41 , 37 35 байт

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

Я не знаю інтернет-перекладача для Rails, але ось скріншот, що демонструє цю процедуру

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


Інтернет-перекладач посилання?
Джонатан Аллан

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. Врятував величезний шматок завдяки грільфінгу TessellingHeckler.


1
Привіт, конкурентоспроможне подання PowerShell!
Erik the 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або спробуйте в Інтернеті .

Перевірка дати була дуже дорогою: мені довелося розбирати дату, перш ніж використовувати вбудований, а потім спробувати помилку на назві місяця.


Я думаю, ви повинні підтримувати всі формати, а не один з них?
Erik the Outgolfer

1
@EriktheOutgolfer це робить. Але не бонусні формати.
Тит

@EriktheOutgolfer Це обробляє всі формати.
Містер Xcoder

1
Це не вдається для недійсних дат. 30 February 2014повертає 2014/03/02. Або ви помилившись або повернувши послідовне значення фальси, ви виберете. (Однак вони будуть дотримуватися форматів шаблонів вище)
Містер 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

Спробуйте в Інтернеті!

Не підтримує дати бонусів


Ласкаво просимо до PPCG! Гарний перший пост. Збережіть 13 байт , використовуючи: повернене значення фальси None; import ...as; & a 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

Спробуйте в Інтернеті!

; -; pls пал


; -; pls 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.
Ніл
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.