Przeczytaj moją dowolną datę

10

Biorąc pod uwagę datę zapisaną w dowolnym (musi obsłużyć wszystko w tym samym programie) następujących formatów, parsuj ją w poprawny yyyy/mm/dd date.

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

Zasady

  • Daty czasami są nieprawidłowe, tj. niepoprawny dzień miesiąca lub liczby miesięcy w roku, musisz obsłużyć oba przypadki. Albo przez pomyłkę, albo przez zwrócenie stałej wartości falsey, wybierasz. (Będą jednak trzymać się powyższych formatów szablonów)
  • Aby utworzyć dwucyfrowe wyjście, należy użyć wypełnienia dla dni i miesięcy krótszych niż 10.
  • Nazwy miesięcy zawsze będą pełnym imieniem, a nie skrótem do ich trzech postaci.
  • Możesz założyć, że rok będzie zawsze mieścić się w przedziale 0000-9999.
  • Liczb ujemnych nie trzeba traktować.
  • Możesz utworzyć pełny program lub funkcję, aby dane wyjściowe mogły być w dowolnym formacie, wydrukowane na konsoli lub zwrócone z funkcji.
  • Dane wejściowe zawsze będą ciągiem, dane wyjściowe zawsze muszą być ciągiem, jeśli skraca to przyjmowanie go jako pojedynczego argumentu w tablicy np. ["17th May 2012"]możesz to zrobić, a wynik może być taki sam["2012/05/17"]
  • Możesz założyć, że pisownia w danych wejściowych będzie poprawna.

BONUS: bo kto tu nie lubi wyzwania;)

Jeśli potrafisz również zezwolić na formaty wejściowe The Fourteenth of March, 2016lub March the Fourteenth, 2016możesz usunąć dodatkowe 20 bajtów z kodu, przy czym końcowy bajt będzie mniejszy niż 1, co da 1.

Oto pełne zapisane liczby dla każdego dnia, aby uniknąć pomyłek w pisowni.

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

Przypadki testowe

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
źródło
10
bo kto tutaj nie lubi wyzwania ” - kiedy przychodzą w formie premii, przeważnie wszyscy nie! I boo-urny do sprawdzania poprawności danych wejściowych.
Shaggy
3
@ Mr.Xcoder myślę cały wyzwaniem jest do obsługi wielu formatów wejściowych .. takie rzeczy jak 20 February 2014są domyślne obsługiwane w wielu Date-parserami, ale 17thi Sunday, June 8, 2015są nieco trudniejsze do analizy (w zależności od języka).
Kevin Cruijssen
1
@ Mr.Xcoder Nigdy nie powiedziałem, że to zabawne / nudne, łatwe / trudne, dobre / złe wyzwanie gry w golfa. Po prostu stwierdzam, że w oparciu o to, co przeczytałem w wyzwaniu, obsługa wielu formatów wejściowych wydaje się być głównym celem wyzwania. Zgadzam się, że najprawdopodobniej będzie to pięć innych formatów wejściowych lub jakieś wyrażenie regularne do wyodrębnienia roku, miesiąca i dnia (co jest obecnie moim podejściem).
Kevin Cruijssen,
3
Czy dzień tygodnia jest zawsze poprawny? Byłby Thursday, August 25, 2017ważny? Widzę zgłoszenia ignorujące DOW.
Benjamin Cuningham

Odpowiedzi:

4

Szyny, 41 , 37 35 bajtów

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

Nie znam internetowego tłumacza dla Railsów, ale oto zrzut ekranu pokazujący ten proces

wprowadź opis zdjęcia tutaj

Suever
źródło
Link do tłumacza online?
Jonathan Allan
1
Czy to naprawdę działa dla wszystkich omawianych formatów? : o
całkowicie ludzki,
@totallyhuman Dodano zrzut ekranu pokazujący wyniki. Niestety nie znam tłumacza internetowego :(
Suever
8

PowerShell , 91 89 91 56 bajtów

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

Wypróbuj online!

Pobiera dane wejściowe jako ciąg. Używa a, -replaceaby pozbyć się śmieci, a następnie używa wbudowanej Get-Datekomendy z -fflagą ormat, aby określić wymagany yyyy/MM/ddformat. Ten ciąg jest pozostawiony w potoku, a dane wyjściowe są niejawne.

Zaoszczędził dwa bajty dzięki Mr Xcoder. Oszczędność ogromnej części dzięki regexowi golfowemu TessellatingHeckler.

AdmBorkBork
źródło
1
Hej, spójrz na konkurencyjne przesłanie PowerShell!
Erik the Outgolfer
@EriktheOutgolfer Manipulowanie datami jest jedną z mocnych stron PowerShell.
AdmBorkBork
@ Mr.Xcoder „all the” = 2. lol. Dzięki!
AdmBorkBork
Możesz usunąć ''z formatu daty dla -2. Jeśli chcesz pozostać przy swoim podejściu, biorąc pod uwagę, że „pisownia jest poprawna”, możesz go zastąpić 'th|rd|st|(\b.*)day|,'i spada on do 56 bajtów i obsługuje te same przypadki. Chociaż myślę, że to źle, ponieważ jeśli upuścisz dni, nie możesz odebrać Sunday, June8, 2015 | Invalidsprawy, ponieważ był to poniedziałek. Powinien być błędny, ale analizowany jako poprawny. Nie jestem pewien, jakie będzie orzeczenie w tej sprawie ani czy inni to sprawdzają.
TessellatingHeckler
4

PHP, 73 164 + 1 bajty

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]);

Uruchom jako potok z -nRlub spróbuj online .

Sprawdzanie daty było naprawdę drogie: musiałem zdemontować datę przed użyciem wbudowanego, a następnie spróbować popełnić błąd w nazwie miesiąca.

Tytus
źródło
Myślę, że musisz obsługiwać wszystkie formaty, a nie tylko jeden?
Erik the Outgolfer
1
@EriktheOutgolfer robi. Ale nie formaty bonusowe.
Tytus
@EriktheOutgolfer Obsługuje wszystkie formaty.
Pan Xcoder,
1
Nie udaje się to w przypadku nieprawidłowych dat. 30 February 2014zwraca 2014/03/02. Albo przez pomyłkę, albo przez zwrócenie stałej wartości falsey, wybierasz. (Będą jednak trzymać się powyższych formatów szablonów)
Mr. Xcoder
@ Mr.Xcoder To całkiem rujnuje ...
Tytus
3

Python 3 + parsowana biblioteka czasu, 152 139 155 153 bajtów

Zaoszczędź 13 bajtów dzięki Jonathanowi Allanowi

Dodano 16 bajtów do obsługi dat z niepoprawną długością dni

Zaoszczędzono 2 bajty, usuwając przypisanie lambda

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

Wypróbuj online!

Nie obsługuje dat bonusowych

Noskcaj
źródło
Witamy w PPCG! Niezły pierwszy post. Zaoszczędź 13 bajtów , używając: zwracanej wartości falsey None; import ...as; i lambdaprzez ponowne użycie parsejako h.
Jonathan Allan,
1

Java (OpenJDK 8) , 190 + 26 = 216 bajtów

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")))

Wypróbuj online!

Ważna uwaga: krótsza była także walidacja dnia tygodnia niż porzucenie go, aby włączyć walidację!

Nie próbowałem SimpleDateFormatpoza oczywistymi przypadkami, które wszystkie zaakceptowały daty, takie jak 30 lutego. Więc musiałem to porzucić i użyłem Java 8 DateTimeFormatter.

Wyjaśnienie

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

Ten format oznacza:

  • opcjonalny dzień tygodnia, po którym następuje przecinek i spacja [EEEE, ](dzieje się zaSunday, ... ),
  • po którym następuje opcjonalny dzień ze spacją [d ],
  • a następnie miesiąc dużymi literami MMMMi spacją,
  • a następnie opcjonalny dzień z przecinkiem i spacją [d, ],
  • a następnie rok ery, uuuuaby poinformować parsera, że ​​jesteśmy w erze gregoriańskiej.

Kod:

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
       )
    )

Kredyty

  • 2 bajty w wyrażeniu regularnym dzięki Neilowi.
Olivier Grégoire
źródło
1
Czy potrzebujesz nawiasów we replaceAllwzorze?
Neil
Wygląda na to, że nie. Dzięki, @Neil!
Olivier Grégoire,
1

JavaScript (ES6), 124 122 bajtów

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>

Neil
źródło
Zwraca 2015/06/07za June 8, 2015(problem UTC? Jestem w UTC + 2) i falseza jeden Sunday, June 8, 2015lub dwa Monday, June 8, 2015.
Olivier Grégoire
1
@ OlivierGrégoire Dzięki za wskazanie tych. Próbowałem tylko w Wielkiej Brytanii poza czasem letnim, więc korzystały już z UTC i nie próbowałem dni tygodnia kończących się nday.
Neil