Leia minha data de forma livre

10

Dada uma data escrita em qualquer (deve lidar com tudo no mesmo programa) dos seguintes formatos, analise-a em um válido yyyy/mm/dd date.

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

Regras

  • As datas às vezes serão inválidas, ou seja. dia incorreto do mês ou número de meses em um ano, você deve lidar com os dois casos. Ao errar ou retornar um valor consistente de falsey, você escolhe. (No entanto, eles seguirão os formatos de modelo acima)
  • Preenchimento por dias e meses menor que 10 deve ser usado para criar uma saída de dois dígitos.
  • Os nomes dos meses sempre serão o nome completo, não abreviados para os três caracteres correspondentes.
  • Você pode assumir que o ano sempre estará dentro do intervalo 0000-9999.
  • Números negativos não precisam ser manipulados.
  • Você pode criar um programa ou função completo para que a saída possa estar em qualquer formato, impressa no console ou retornada de uma função.
  • A entrada sempre será uma cadeia de caracteres, a saída sempre deve ser uma cadeia de caracteres, se torna mais curto aceitá-la como um argumento único em uma matriz, por exemplo. ["17th May 2012"]você pode fazê-lo e a saída pode ser a mesma["2012/05/17"]
  • Você pode assumir que a ortografia na entrada estará correta.

BÔNUS: porque quem aqui não gosta de desafios;)

Se você também pode permitir os formatos de entrada The Fourteenth of March, 2016ou March the Fourteenth, 2016retirar um extra de 20 bytes do seu código com qualquer contagem de bytes final menor que 1, resultando em 1.

Aqui estão os números escritos completos para cada um dos dias para evitar qualquer confusão quanto à ortografia.

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

Casos de teste

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
fonte
10
" porque aqui não gosta de desafios " - quando eles vêm na forma de um bônus, quase todos nós não gostamos ! E vaias para inserir validação.
Shaggy
3
@ Mr.Xcoder Eu acho que todo o desafio é suportar múltiplos formatos de entrada .. Coisas como 20 February 2014são padrão apoiado em um monte de data-analisadores, mas 17the Sunday, June 8, 2015são um pouco mais difíceis de analisar (dependendo do idioma).
Kevin Cruijssen
11
@ Mr.Xcoder Eu nunca disse que era um desafio divertido / chato, fácil / difícil, bom / ruim de código-golfe. Estou simplesmente afirmando que, com base no que li no desafio, o suporte a múltiplos formatos de entrada parece ser o principal objetivo do desafio. Concordo que provavelmente será um if-else para os cinco formatos de entrada ou algum tipo de regex para extrair o ano, o mês e o dia (que atualmente é a minha abordagem).
Kevin Cruijssen
3
O dia da semana está sempre correto? Seria Thursday, August 25, 2017válido? Vejo envios ignorando a DOW.
Benjamin Cuningham

Respostas:

4

Trilhos, 41 , 37 35 bytes

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

Não conheço um intérprete on-line para o Rails, mas aqui está uma captura de tela demonstrando esse processo

insira a descrição da imagem aqui

Suever
fonte
Link de intérprete online?
Jonathan Allan
11
Isso realmente funciona para todos os formatos em questão? :
totalmente
@totallyhuman Adicionada uma captura de tela mostrando os resultados. Infelizmente não conheço um intérprete on-line :(
Suever
8

PowerShell , 91 89 91 56 bytes

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

Experimente online!

Recebe a entrada como uma sequência. Usa a -replacepara se livrar do lixo eletrônico e usa o Get-Datecomando -finterno com o sinalizador ormat para especificar o yyyy/MM/ddformato necessário . Essa cadeia é deixada no pipeline e a saída é implícita.

Economizou dois bytes graças ao Sr. Xcoder. Economizou muito dinheiro graças ao golfe regular da TessellatingHeckler.

AdmBorkBork
fonte
11
Ei, olhe para o envio competitivo do PowerShell!
Erik the Outgolfer
@EriktheOutgolfer A manipulação de datas é um dos pontos fortes do PowerShell.
AdmBorkBork
@ Mr.Xcoder "todos aqueles" = 2. lol. Obrigado!
AdmBorkBork
Você pode remover o ''formato da data, para -2. Se você deseja manter sua abordagem, dada a "ortografia correta", pode substituí 'th|rd|st|(\b.*)day|,'-la e ela cai para 56 bytes e lida com os mesmos casos. Embora eu ache errado, porque se você deixar os dias de lado, não poderá pegar o Sunday, June8, 2015 | Invalidcaso porque era segunda-feira. Deve erro, mas analisa como válido. Não tenho certeza de qual será a decisão ou se outras pessoas a estão verificando.
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]);

Execute como pipe -nRou experimente online .

A verificação da data foi muito cara: tive que desmontar a data antes de usar um builtin e, em seguida, tentar um erro no nome do mês.

Titus
fonte
Eu acho que você tem que suportar todos os formatos e não apenas um deles?
Erik the Outgolfer
11
@EriktheOutgolfer faz. Mas não os formatos de bônus.
Titus
@EriktheOutgolfer Isso lida com todos os formatos.
Sr. Xcoder
11
Isso falha por datas inválidas. 30 February 2014retorna 2014/03/02. Ao errar ou retornar um valor consistente de falsey, você escolhe. (Eles vão no entanto ficar com os formatos de modelo acima)
Mr. Xcoder
@ Mr.Xcoder Isso bastante ruínas-lo ...
Tito
3

Biblioteca Python 3 + parsedatetime, 152 139 155 153 bytes

Guardado 13 bytes graças a Jonathan Allan

Adicionados 16 bytes para lidar com datas com dias de duração inválida

2 bytes salvos removendo a atribuição 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

Experimente online!

Não suporta datas de bônus

Noskcaj
fonte
Bem-vindo ao PPCG! Bom primeiro post. Salve 13 bytes usando: o valor de retorno falsey de None; import ...as; & a lambdareutilizando parsecomo 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")))

Experimente online!

Nota importante: era mais curto validar também o dia da semana em vez de abandoná-lo, para que a validação fosse incluída!

Não tentei SimpleDateFormatalém dos casos óbvios, que todos aceitavam datas como 30 de fevereiro. Então eu tive que abandoná-lo e usei o Java 8 DateTimeFormatter.

Explicação

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

Este formato significa:

  • dia da semana opcional seguido de vírgula e espaço [EEEE, ](acontece em Sunday, ...),
  • seguido de dia opcional com espaço [d ],
  • seguido por mês em letras MMMMe espaço completos ,
  • seguido de dia opcional com vírgula e espaço [d, ],
  • seguido pelo ano da era uuuupara informar ao analisador que estamos na era gregoriana.

Código:

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éditos

  • 2 bytes no regex graças a Neil.
Olivier Grégoire
fonte
11
Você precisa dos colchetes no replaceAllpadrão?
Neil
Parece que não. Obrigado, @ Neil!
Olivier Grégoire
1

JavaScript (ES6), 124 122 bytes

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
fonte
Retorna 2015/06/07para June 8, 2015(problema UTC? Estou no UTC + 2) e falsepara um Sunday, June 8, 2015ou outro Monday, June 8, 2015.
Olivier Grégoire
11
@ OlivierGrégoire Obrigado por apontar isso. Eu só tinha experimentado datas no Reino Unido fora do horário de verão, para que eles já estivessem usando o UTC, e não havia tentado os dias úteis terminando em nday.
26517 Neil