Herausforderung
Finden Sie die kürzeste Regex, die
- validiert, dh stimmt mit jedem möglichen Datum im proleptischen Gregorianischen Kalender überein (der auch für alle Daten vor seiner ersten Annahme im Jahr 1582 gilt) und
- stimmt mit keinem ungültigen Datum überein.
Ausgabe
Die Ausgabe ist daher wahr oder falsch.
Eingang
Die Eingabe erfolgt in einem der drei erweiterten ISO 8601- Datumsformate - ohne Zeitangabe.
Die ersten beiden sind ±YYYY-MM-DD
(Jahr, Monat, Tag) und ±YYYY-DDD
(Jahr, Tag). Beide benötigen eine spezielle Hülle für den Schalttag. Sie werden naiv getrennt von diesen erweiterten RXs abgeglichen:
(?<year>[+-]?\d{4,})-(?<month>\d\d)-(?<day>\d\d)
(?<year>[+-]?\d{4,})-(?<doy>\d{3})
Das dritte Eingabeformat ist ±YYYY-wWW-D
(Jahr, Woche, Tag). Es ist das komplizierte wegen des komplexen Schaltwochenmusters.
(?<year>-?\d{4,})-W(?<week>\d\d)-(?<dow>\d)
Eine grundlegende, aber unzureichende Gültigkeitsprüfung für alle drei zusammen würde ungefähr so aussehen:
[+-]?\d{4,}-((0\d|1[0-2])-([0-2]\d|3[01]) ↩
|([0-2]\d\d|3[0-5]\d|36[0-6]) ↩
|(W([0-4]\d|5[0-3])-[1-7]))
Bedingungen
Ein Schaltjahr im proleptischen Gregorianischen Kalender enthält den Schalttag …-02-29
und ist somit 366 Tage lang, …-366
existiert also. Dies geschieht in jedem Jahr, dessen Ordnungszahl durch 4 teilbar ist, jedoch nicht durch 100, es sei denn, es ist auch durch 400 teilbar. Das
Jahr Null ist in diesem Kalender vorhanden und es handelt sich um ein Schaltjahr.
Ein langes Jahr im ISO-Wochenkalender enthält eine 53. Woche, die man als Schaltwoche bezeichnen könnte. Dies geschieht in allen Jahren, in denen der 1. Januar ein Donnerstag ist, und zusätzlich in allen Schaltjahren, in denen es ein Mittwoch ist. Es stellt sich heraus, dass es normalerweise alle 5 oder 6 Jahre in einem scheinbar unregelmäßigen Muster auftritt.
Ein Jahr hat mindestens 4 Ziffern. Jahre mit mehr als 10 Ziffern müssen nicht unterstützt werden, da dies dem Alter des Universums (ca. 14 Milliarden Jahre) nahe kommt. Das führende Pluszeichen ist optional, obwohl der tatsächliche Standard vorsieht, dass es für Jahre mit mehr als 4 Stellen erforderlich sein sollte.
Teilweise oder verkürzte Daten, dh mit weniger als Tagesgenauigkeit, dürfen nicht akzeptiert werden.
Die Teile der Datumsnotation, z. B. der Monat, müssen nicht mit einer Gruppe übereinstimmen, auf die verwiesen werden könnte.
Regeln
Das ist Code-Golf. Der kürzeste reguläre Ausdruck ohne ausgeführten Code gewinnt. Update: Sie können Funktionen wie Rekursion und ausgeglichene Gruppen verwenden, werden jedoch mit dem Faktor 10 bestraft, mit dem die Anzahl der Zeichen dann multipliziert wird! Dies unterscheidet sich nun von den Regeln im Hardcode-Golf: Regex für die Teilbarkeit durch 7 . Frühere Antwort gewinnt ein Unentschieden.
Testfälle
Gültige Tests
2015-08-10
2015-10-08
12015-08-10
-2015-08-10
+2015-08-10
0015-08-10
1582-10-10
2015-02-28
2016-02-29
2000-02-29
0000-02-29
-2000-02-29
-2016-02-29
200000-02-29
2016-366
2000-366
0000-366
-2016-366
-2000-366
2015-081
2015-W33-1
2015-W53-7
2015-08-10
Das letzte ist optional gültig, dh führende und nachfolgende Leerzeichen in Eingabezeichenfolgen können abgeschnitten werden.
Ungültige Formate
-0000-08-10 # that's an arbitrary decision
15-08-10 # year is at least 4 digits long
2015-8-10 # month (and day) is exactly two digits long, i.e. leading zero is required
015-08-10 # year is at least 4 digits long
20150810 # though a valid ISO format, we require separators; could also be interpreted as a 8-digit year
2015 08 10 # separator must be hyphen-minus
2015.08.10 # separator must be hyphen-minus
2015–08–10 # separator must be hyphen-minus
2015-0810
201508-10 # could be October in the year 201508
2015 - 08 - 10 # no internal spaces allowed
2015-w33-1 # letter ‘W’ must be uppercase
2015W33-1 # it would be unambiguous to omit the separator in front of a letter, but not in the standard
2015W331 # though a valid ISO format we require separators
2015-W331
2015-W33 # a valid ISO date, but we require day-precision
2015W33
Ungültige Daten
2015 # a valid ISO format, but we require day-precision
2015-08 # a valid ISO format, but we require day-precision
2015-00-10 # month range is 1–12
2015-13-10 # month range is 1–12
2015-08-00 # day range is 1–28 through 31
2015-08-32 # max. day range is 1–31
2015-04-31 # day range for April is 1–30
2015-02-30 # day range for February is 1–28 or 29
2015-02-29 # day range for common February is 1–28
2100-02-29 # most century years are non-leap
-2100-02-29 # most century years are non-leap
2015-000 # day range is 1–365 or 366
2015-366 # day range is 1–365 in common years
2016-367 # day range is 1–366 in leap years
2100-366 # most century years are non-leap
-2100-366 # most century years are non-leap
2015-W00-1 # week range is 1–52 or 53
2015-W54-1 # week range is 1–53 in long years
2016-W53-1 # week range is 1–52 in short years
2015-W33-0 # day range is 1–7
2015-W33-8 # day range is 1–7