Lesen Sie mein Freiformdatum


10

Wenn ein Datum in einem der folgenden Formate geschrieben ist (muss alle im selben Programm verarbeiten), analysieren Sie es in ein gültiges yyyy/mm/dd date.

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

Regeln

  • Daten sind manchmal ungültig, dh. Falscher Tag für den Monat oder die Anzahl der Monate in einem Jahr, müssen Sie beide Fälle behandeln. Entweder indem Sie einen Fehler machen oder einen konsistenten Falsey-Wert zurückgeben, wählen Sie. (Sie bleiben jedoch bei den obigen Vorlagenformaten)
  • Für eine zweistellige Ausgabe muss eine Auffüllung für Tage und Monate unter 10 verwendet werden.
  • Monatsnamen sind immer der vollständige Name und werden nicht auf die drei Zeichen gekürzt.
  • Sie können davon ausgehen, dass das Jahr immer im Bereich von 0000-9999 liegt.
  • Negative Zahlen müssen nicht behandelt werden.
  • Sie können ein vollständiges Programm oder eine vollständige Funktion erstellen, sodass die Ausgabe in einem beliebigen Format erfolgen, auf die Konsole gedruckt oder von einer Funktion zurückgegeben werden kann.
  • Die Eingabe ist immer eine Zeichenfolge, die Ausgabe muss immer eine Zeichenfolge sein, wenn es kürzer wird, sie als einzelnes Argument in einem Array zu verwenden, z. ["17th May 2012"]Sie können dies tun und die Ausgabe kann dieselbe sein["2012/05/17"]
  • Sie können davon ausgehen, dass die Schreibweise in der Eingabe korrekt ist.

BONUS: weil wer hier keine Herausforderung mag;)

Wenn Sie es schaffen, auch die Eingabeformate von zuzulassen, The Fourteenth of March, 2016oder March the Fourteenth, 2016wenn Sie Ihrem Code zusätzliche 20 Bytes entziehen, wobei die Anzahl der endgültigen Bytes weniger als 1 beträgt, was zu 1 führt.

Hier finden Sie die vollständigen Zahlen für jeden Tag, um Verwechslungen bei der Rechtschreibung zu vermeiden.

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

Testfälle

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
" Weil wer hier keine Herausforderung mag " - wenn sie in Form eines Bonus kommen, tun es meistens wir alle nicht! Und Boo-Urnen zur Eingabevalidierung.
Shaggy

3
@ Mr.Xcoder ich die ganze Herausforderung denken ist , mehrere Input - Formate zu unterstützen .. Solche Dinge 20 February 2014sind Standard in vielen datum Parser unterstützt, aber 17thund Sunday, June 8, 2015sind ein bisschen schwieriger zu analysieren (abhängig von der Sprache).
Kevin Cruijssen

1
@ Mr.Xcoder Ich habe nie gesagt, dass es eine lustige / langweilige, einfache / harte, gute / schlechte Code-Golf-Herausforderung ist. Ich sage nur, dass basierend auf dem, was ich in der Herausforderung gelesen habe, die Unterstützung mehrerer Eingabeformate das Hauptziel der Herausforderung zu sein scheint. Ich bin damit einverstanden, dass es höchstwahrscheinlich ein Wenn-Andernfalls für die fünf Eingabeformate oder eine Art Regex sein wird, um das Jahr, den Monat und den Tag zu extrahieren (was derzeit mein Ansatz ist).
Kevin Cruijssen

3
Ist der Wochentag immer korrekt? Wäre Thursday, August 25, 2017gültig? Ich sehe Einsendungen, die den DOW ignorieren.
Benjamin Cuningham

Antworten:


4

Schienen, 41 , 37 35 Bytes

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

Ich kenne keinen Online-Interpreter für Rails, aber hier ist ein Screenshot, der diesen Prozess demonstriert

Geben Sie hier die Bildbeschreibung ein


Online-Dolmetscher-Link?
Jonathan Allan

1
Funktioniert das wirklich für alle fraglichen Formate? : o
totalhuman

@totallyhuman Ein Screenshot mit den Ergebnissen wurde hinzugefügt. Leider kenne ich keinen Online-Dolmetscher :(
Suever

8

PowerShell , 91 89 91 56 Byte

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

Probieren Sie es online aus!

Nimmt die Eingabe als Zeichenfolge auf. Verwendet a -replace, um Junk zu entfernen , und verwendet dann den integrierten Get-DateBefehl mit dem -format-Flag, um das erforderliche yyyy/MM/ddFormat anzugeben . Diese Zeichenfolge verbleibt in der Pipeline und die Ausgabe ist implizit.

Dank Mr Xcoder wurden zwei Bytes gespeichert. Dank des Regex-Golfspiels von TessellatingHeckler wurde ein großer Teil gespart.


1
Hey, sehen Sie wettbewerbsfähig PowerShell Einreichung!
Erik der Outgolfer

@EriktheOutgolfer Datumsmanipulation ist eine der Stärken von PowerShell.
AdmBorkBork


@ Mr.Xcoder "all diese" = 2. lol. Vielen Dank!
AdmBorkBork

Sie können das ''für -2 aus dem Datumsformat entfernen . Wenn Sie an Ihrem Ansatz festhalten möchten, können Sie ihn ersetzen, da die Rechtschreibung korrekt ist. 'th|rd|st|(\b.*)day|,'Er fällt auf 56 Byte ab und behandelt dieselben Fälle. Obwohl ich denke, dass es falsch ist, denn wenn Sie die Tage fallen lassen, können Sie den Sunday, June8, 2015 | InvalidFall nicht abholen, weil es Montag war. Es sollte ein Fehler sein, aber es wird als gültig analysiert. Ich bin mir nicht sicher, wie das Urteil darüber aussehen wird oder ob andere es überprüfen.
TessellatingHeckler

4

PHP, 73 164 + 1 Bytes

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

Laufen Sie als Pipe mit -nRoder probieren Sie es online aus .

Die Datumsüberprüfung war sehr teuer: Ich musste das Datum zerlegen, bevor ich eine integrierte Funktion verwendete, und dann versuchen, den Monatsnamen zu überprüfen.


Ich denke, Sie müssen alle Formate unterstützen, nicht nur eines davon?
Erik der Outgolfer

1
@EriktheOutgolfer tut es. Aber nicht die Bonusformate.
Titus

@EriktheOutgolfer Dies behandelt alle Formate.
Mr. Xcoder

1
Dies schlägt bei ungültigen Daten fehl. 30 February 2014kehrt zurück 2014/03/02. Entweder indem Sie einen Fehler machen oder einen konsistenten Falsey-Wert zurückgeben, wählen Sie. (Sie werden sich jedoch an die obigen Vorlagenformate halten)
Mr. Xcoder

@ Mr.Xcoder Das ruiniert es ziemlich ...
Titus

3

Python 3 + parsedatetime Bibliothek, 152 139 155 153 Bytes

Dank Jonathan Allan wurden 13 Bytes gespeichert

16 Bytes hinzugefügt, um Daten mit ungültigen Tagen zu verarbeiten

2 Bytes durch Entfernen der Lambda-Zuweisung gespeichert

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

Probieren Sie es online aus!

Unterstützt keine Bonusdaten


Willkommen bei PPCG! Schöner erster Beitrag. Speichern Sie 13 Bytes mit: dem Falsey-Rückgabewert von None; import ...as;; & a lambdadurch Wiederverwendung parseals h.
Jonathan Allan


1

Java (OpenJDK 8) , 190 + 26 = 216 Bytes

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

Probieren Sie es online aus!

Wichtiger Hinweis: Es war kürzer , auch den Wochentag zu validieren, anstatt ihn fallen zu lassen, sodass die Validierung eingeschlossen ist!

Ich habe es nicht mit SimpleDateFormatden offensichtlichen Fällen versucht, bei denen alle Daten wie der 30. Februar akzeptiert wurden. Also musste ich es fallen lassen und habe Java 8's verwendet DateTimeFormatter.

Erläuterung

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

Dieses Format bedeutet:

  • optionaler Wochentag, gefolgt von Komma und Leerzeichen [EEEE, ](geschieht in Sunday, ...),
  • gefolgt von einem optionalen Tag mit Platz [d ],
  • gefolgt von einem Monat in vollen Buchstaben MMMMund Leerzeichen,
  • gefolgt von einem optionalen Tag mit Komma und Leerzeichen [d, ],
  • gefolgt von einem Jahr der Ära uuuu, um den Parser wissen zu lassen, dass wir uns in der Gregorianischen Ära befinden.

Code:

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

Credits

  • 2 Bytes im regulären Ausdruck dank Neil.

1
Benötigen Sie die Klammern im replaceAllMuster?
Neil

Sieht so aus, als ob ich es nicht tue. Danke, @Neil!
Olivier Grégoire

1

JavaScript (ES6), 124 122 Byte

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>


Rückgabe 2015/06/07für June 8, 2015(UTC-Problem? Ich bin in UTC + 2) und falsefür entweder Sunday, June 8, 2015oder Monday, June 8, 2015.
Olivier Grégoire

1
@ OlivierGrégoire Danke, dass du darauf hingewiesen hast. Ich hatte nur Termine in Großbritannien außerhalb der Sommerzeit ausprobiert, sodass sie bereits UTC verwendeten, und ich hatte keine Wochentage ausprobiert, die mit endeten nday.
Neil
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.