Lire ma date de forme libre

10

Étant donné une date écrite dans l'un (doit gérer tous dans le même programme) des formats suivants, l'analyser en un valide yyyy/mm/dd date.

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

Règles

  • Les dates seront parfois invalides, c.-à-d. jour incorrect pour le mois ou le nombre de mois dans une année, vous devez gérer les deux cas. Soit en faisant une erreur soit en renvoyant une valeur de falsey cohérente, vous choisissez. (Ils s'en tiendront toutefois aux formats de modèles ci-dessus)
  • Un remplissage pour les jours et les mois de moins de 10 doit être utilisé pour créer une sortie à deux chiffres.
  • Les noms de mois seront toujours le nom complet, pas raccourcis à leurs homologues à trois caractères.
  • Vous pouvez supposer que l'année sera toujours comprise dans la plage 0000-9999.
  • Les nombres négatifs ne doivent pas être traités.
  • Vous pouvez créer un programme ou une fonction complète afin que la sortie puisse être dans n'importe quel format, imprimée sur la console ou renvoyée par une fonction.
  • L'entrée sera toujours une chaîne, la sortie doit toujours être une chaîne, si elle est plus courte pour la prendre comme un seul argument dans un tableau par exemple. ["17th May 2012"]vous pouvez le faire et la sortie peut être la même["2012/05/17"]
  • Vous pouvez supposer que l'orthographe en entrée sera correcte.

BONUS: cos qui ici n'aime pas un défi;)

Si vous parvenez à autoriser également les formats d'entrée de The Fourteenth of March, 2016ou March the Fourteenth, 2016vous pouvez prendre 20 octets supplémentaires sur votre code avec tout octet final comptant moins de 1, ce qui donne 1.

Voici les numéros écrits complets pour chacun des jours afin d'éviter toute confusion sur l'orthographe.

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

Cas de test

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
la source
12
0/10, pas assez libre
Martin Ender
10
" cos qui ici n'aime pas un défi " - quand ils viennent sous forme de bonus, la plupart d'entre nous pas! Et boo-urns pour entrer la validation.
Shaggy
3
@ Mr.Xcoder Je pense que tout le défi consiste à prendre en charge plusieurs formats d'entrée. Des choses comme 20 February 2014sont par défaut prises en charge dans de nombreux analyseurs de date, mais 17thet Sunday, June 8, 2015sont un peu plus difficiles à analyser (selon la langue).
Kevin Cruijssen
1
@ Mr.Xcoder Je n'ai jamais dit que c'était un défi amusant / ennuyeux, facile / difficile, bon / mauvais. Je dis simplement que sur la base de ce que j'ai lu dans le défi, la prise en charge de plusieurs formats d'entrée semble être l'objectif principal du défi. Je suis d'accord que ce sera probablement un if-else pour les cinq formats d'entrée, ou une sorte de regex pour extraire l'année, le mois et le jour (ce qui est actuellement mon approche).
Kevin Cruijssen
3
Le jour de la semaine est-il toujours correct? Serait Thursday, August 25, 2017valide? Je vois des soumissions ignorant le DOW.
Benjamin Cuningham

Réponses:

4

Rails, 41 , 37 35 octets

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

Je ne connais pas d'interprète en ligne pour Rails, mais voici une capture d'écran illustrant ce processus

entrez la description de l'image ici

Suever
la source
Lien interprète en ligne?
Jonathan Allan
1
Est-ce que cela fonctionne vraiment pour tous les formats en question? : o
totalement humain
@totallyhuman Ajout d'une capture d'écran montrant les résultats. Malheureusement, je ne connais pas d'interprète en ligne :(
Suever
8

PowerShell , 91 89 91 56 octets

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

Essayez-le en ligne!

Prend l'entrée sous forme de chaîne. Utilise a -replacepour se débarrasser des fichiers indésirables, puis utilise la Get-Datecommande -fintégrée avec l' indicateur ormat pour spécifier le yyyy/MM/ddformat requis . Cette chaîne est laissée sur le pipeline et la sortie est implicite.

Enregistré deux octets grâce à Mr Xcoder. Économisé un gros morceau grâce au golf regex de TessellatingHeckler.

AdmBorkBork
la source
1
Hé, regardez la soumission PowerShell compétitive!
Erik the Outgolfer
@EriktheOutgolfer La manipulation de date est l'une des forces de PowerShell.
AdmBorkBork
@ Mr.Xcoder "tous ceux" = 2. lol. Merci!
AdmBorkBork
Vous pouvez supprimer le ''du format de date, pour -2. Si vous voulez vous en tenir à votre approche, étant donné que "l'orthographe est correcte", vous pouvez le remplacer 'th|rd|st|(\b.*)day|,'et il tombe à 56 octets et gère les mêmes cas. Bien que je pense que c'est faux parce que si vous laissez tomber les jours, vous ne pouvez pas ramasser l' Sunday, June8, 2015 | Invalidaffaire parce que c'était lundi. Il devrait y avoir une erreur, mais il est analysé comme valide. Je ne sais pas quelle sera la décision à ce sujet, ou si d'autres vérifient.
TessellatingHeckler
4

PHP, 73 164 + 1 octets

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

Exécuter en tant que pipe avec -nRou l' essayer en ligne .

La vérification de la date était vraiment chère: j'ai dû démonter la date avant d'utiliser une fonction intégrée, puis essayer de faire une erreur sur le nom du mois.

Titus
la source
Je pense que vous devez prendre en charge tous les formats, pas seulement l'un d'entre eux?
Erik the Outgolfer
1
@EriktheOutgolfer c'est le cas. Mais pas les formats bonus.
Titus
@EriktheOutgolfer Ceci gère tous les formats.
M. Xcoder
1
Cela échoue pour les dates non valides. 30 February 2014retourne 2014/03/02. Soit en faisant une erreur soit en renvoyant une valeur de falsey cohérente, vous choisissez. (Ils s'en tiendront toutefois aux formats de modèles ci-dessus)
M. Xcoder
@ Mr.Xcoder Cela le gâche tout à fait ...
Titus
3

Python 3 + bibliothèque de ParseDateTime, 152 139 155 153 octets

Enregistré 13 octets grâce à Jonathan Allan

Ajout de 16 octets pour gérer les dates avec des jours non valides

Enregistré 2 octets en supprimant l'affectation 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

Essayez-le en ligne!

Ne prend pas en charge les dates de bonus

Noskcaj
la source
Bienvenue chez PPCG! Bon premier post. Économisez 13 octets en utilisant: la valeur de retour falsey de None; import ...as; & a lambdaen réutilisant parsecomme h.
Jonathan Allan
1

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

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

Essayez-le en ligne!

Remarque importante: il était plus court de valider également le jour de la semaine au lieu de l'abandonner, afin que la validation soit incluse!

Je n'ai pas essayé au- SimpleDateFormatdelà des cas évidents qui ont tous accepté des dates comme le 30 février. J'ai donc dû l'abandonner et j'ai utilisé Java 8 DateTimeFormatter.

Explication

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

Ce format signifie:

  • jour de la semaine facultatif suivi de virgule et d'espace [EEEE, ](se produit dans Sunday, ...),
  • suivi d'une journée optionnelle avec espace [d ],
  • suivi du mois en lettres pleines MMMMet espace,
  • suivi d'une journée optionnelle avec virgule et espace [d, ],
  • suivi de l'année de l'ère uuuupour faire savoir à l'analyseur que nous sommes à l'ère grégorienne.

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

Crédits

  • 2 octets dans l'expression régulière grâce à Neil.
Olivier Grégoire
la source
1
Avez-vous besoin des supports dans le replaceAllmotif?
Neil
On dirait que non. Merci, @Neil!
Olivier Grégoire
1

JavaScript (ES6), 124 122 octets

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
la source
Renvoie 2015/06/07pour June 8, 2015(problème UTC? Je suis en UTC + 2) et falsepour Sunday, June 8, 2015ou Monday, June 8, 2015.
Olivier Grégoire
1
@ OlivierGrégoire Merci de les avoir signalés. Je n'avais essayé que des dates au Royaume-Uni en dehors de l'heure d'été, donc ils utilisaient déjà UTC, et je n'avais pas essayé les jours de la semaine se terminant nday.
Neil