Risoluzione della controversia sul formato della data


17

L'ordine di formattazione delle date è una delle questioni più complesse e di divisione che il mondo deve affrontare oggi. Alcuni di noi sostengono con veemenza che il mese / giorno / anno è appropriato, considerando che è così che diciamo ad alta voce. Altri proclamano a gran voce che il giorno / mese / anno è il migliore, perché mette i termini in ordine crescente della durata che rappresentano.

Quando è troppo è troppo. I computer possono risolvere questa controversia in modo semplice ed equo. Il tuo codice, una funzione o un programma completo, prenderà una stringa di data delimitata da barre, ad es 12/1/2015. Nota che questo è il formato esatto, senza zeri iniziali e con un anno di quattro cifre alla fine.

  • Se è sicuramente mese / giorno / anno, ad esempio 10/31/1998, genera una rappresentazione testuale di quella data in questo formato esatto, con il nome completo del mese, il giorno e l'anno:October 31, 1998
  • Se è sicuramente Giorno / mese / anno, per esempio 25/12/1989, in uscita lo stesso tipo di rappresentazione del testo: December 25, 1989.
  • Se è ambiguo che si tratti di Mese / Giorno / Anno o Giorno / Mese / Anno, genera una data che risolva l'ambiguità combinando le due possibili date come segue:
    1. Crea un nuovo nome di mese prendendo la prima metà del nome del mese precedente e aggiungi la seconda metà del mese successivo . Per mesi di durata dispari, la prima metà ottiene la lettera aggiuntiva. Essere esplicito, la prima metà dei mesi sono Janu, Febr, Mar, Apr, Ma, Ju, Ju, Aug, Septe, Octo, Nove, e Decee seconda metà sono quindi ary, uary, ch, il, y, ne, ly, ust, mber, ber, mber, e mber.
    2. Calcola il giorno facendo la media dei due giorni possibili, prendendo la parola quando la media non è un numero intero.
    3. Stampa la rappresentazione testuale di questa data, ad es. Per 10/8/2011output Augber 9, 2011.

Se la data di inserimento non può essere Mese / Giorno / Anno o Giorno / Mese / Anno (es. 13/13/2013O pari 2/30/2002), qualsiasi comportamento è accettabile. Questo codice golf, il codice più corto vince!

Casi test:

10/31/1998October 31, 1998

25/12/1989December 25, 1989

10/8/2011Augber 9, 2011

8/5/1957Maust 6, 1957

9/12/2012 (stranamente) dà September 10, 2012

1/1/2000January 1, 2000



20
Per quello che vale, molti di coloro che discutono per giorno-mese-anno dicono anche che le date in quell'ordine. (Certo, i veri programmatori discutono per anno-mese-giorno).
Peter Taylor,

Giusto per essere sicuri: without leading zeroes and with a four-digit year at the endimplicayear >= 1000
edc65,

È corretto.
Luca,

1
+ ∞ per il 10 settembre 2012
ev3commander il

Risposte:


1

Pyth - 156 byte

Codice davvero pessimo, e dovrà usare stringhe piene, ma è qualcosa.

Kc"January February March April May June July August September October November December"dJhM.g>k12=GsMcz\/?<eJ32++@KthJdtP`,eJeGss[@VCcL2KStMPGdPt`,s.OPGeG

Test Suite .


3

Mathematica 341 304 298 288 293 byte

Questo utilizza una funzione pura o anonima, ovvero una funzione senza il proprio nome.

DateStringrestituisce un messaggio di errore se la data è ambigua. Checkcattura l'ambiguità e invia la data offensiva a DateList, che la trasforma in un elenco di 3 numeri interi (che ritiene essere {year, month, day}). Gli interi di mese e giorno sono ordinati per dimensione e utilizzati per determinare il mese e il giorno secondo le istruzioni del PO.

Quiet stampa degli errori di silenzio.

t=StringSplit;v=ToString;x=t[#,"-"]&/@t["Janu-ary Febr-uary Mar-ch Apr-il Ma-y Ju-ne Ju-ly Aug-ust Septe-mber Octo-ber Nove-mber Dece-mber"];
Quiet@Check[#~DateString~{"MonthName"," ","DayShort",", ","Year"},
{m,n,o}=DateList@#;{p,q}=Sort@d[[2;;3]];x[[p,1]]<>x[[q,2]]<>" "<>v@Floor@Mean@{n,o}<>", "<>v@d[[1]]]&

t=StringSplit;v=ToString;x=t[#,"-"]&/@t["Janu-ary Febr-uary Mar-ch Apr-il Ma-y Ju-ne Ju-ly Aug-ust Septe-mber Octo-ber Nove-mber Dece-mber"];
Quiet@Check[#~DateString~{"MonthName"," ","DayShort",", ","Year"},
{m,n,o}=DateList@#;{p,q}=Sort@d[[2;;3]];x[[p,1]]<>x[[q,2]]<>" "<>v@Floor@Mean@{n,o}<>", "<>v@d[[1]]]& /@ 
{"10/31/1998","25/12/1989", "10/8/2011", "8/5/1957", "9/12/2012", "1/1/2012"}

{"31 ottobre 1998", "25 dicembre 1989", "9 agosto 2011", "Maust 6, 1957", "10 settembre 2012", "1 gennaio 2012"}


Personalmente mi piacerebbe vederti eliminare quello 0, ma lascerò cadere i voti come potrebbero.
Luca

Ora restituisce "1 gennaio 2012" come richiesto.
DavidC,

3

Javascript (ES6), 311 295 282 274 246 238 byte

a=>(a=a.split`/`,b=c=>e(c).length+1>>1,d=' ',e=f=>new Date(99,a[+f]-1).toLocaleString('en',{month:'long'}),g=+a[0],h=+a[1],i=g>h,j=g>12,k=h>12,(j&&!k?e(1)+d+g:k&&!j?e(0)+d+h:e(i).slice(0,b(i))+e(1-i).slice(b(1-i))+d+((g+h)>>1))+', '+a[2])

Modificare: utilizza toLocaleStringper generare i nomi dei mesi. Cambia la localizzazione per ottenere risultati usando i nomi dei mesi in diverse lingue!

Modifica 2: ora genera nomi di due mesi anziché tutti e 12!

Ungolfed:

func = inp => (
    inp = inp.split `/`,
    get = arg => months(arg).length + 1 >> 1,
    space = ' ',
    months = key => new Date(99, inp[+key] - 1).toLocaleString('en', { month: 'long' }),
    tmp1 = +inp[0],
    tmp2 = +inp[1],
    first = tmp1 > tmp2,
    t1greater = tmp1 > 12,
    t2greater = tmp2 > 12,
    (t1greater && !t2greater ?
        months(1) + space + tmp1
    :
        t2greater && !t1greater ?
            months(0) + space + tmp2
        :
            months(first).slice(0, get(first)) + months(1 - first).slice(get(1 - first)) + space + ((tmp1 + tmp2) >> 1)
    )
    + ', ' + inp[2]
)

Esempio:

console.log(
    func('10/31/1998') + '\n' +
    func('25/12/1989') + '\n' +
    func('10/8/2011') + '\n' +
    func('8/5/1957') + '\n' +
    func('9/12/2012') + '\n' +
    func('1/1/2000')
);

Grazie a:
@ user81655 , 274 => 246 byte
@ edc65 , 246 => 238 byte


1
Non ho guardato molto attentamente, ma ecco alcuni miglioramenti che potresti apportare: modifica Math.ceil(e[c].length/2)a (r=e[c].length/2)+r%1, Array(2).fill().map((_,f)=>...)a f=>...e tutti e[n]a e(n), i=+(g>h)a i=g>he e[i]a e[+i], rimuovere le parentesi non necessarie nell'ultimo operatore ternario, Inoltre, newDatedovrebbe essere new Date.
user81655,

1
Evita di Math.ceilusareb=c=>e(c).length+1>>1
edc65, il

2

JavaScript ES6, 204

x=>(s=x=>x.split`/`,[a,b,y]=s(x).sort((a,b)=>a-b),(c=b)>12?c=a:b=a- -b>>1,s('/Janu/Febr/Mar/Apr/Ma/Ju/Ju/Aug/Septe/Octo/Nove/Dece')[a]+s('/ary/uary/ch/il/y/ne/ly/ust/mber/ber/mber/mber')[c]+` ${b}, `+y)

Snippet di prova:

F=x=>(
  s=x=>x.split`/`,
  [a,b,y]=s(x).sort((a,b)=>a-b),
  (c=b)>12?c=a:b=a- -b>>1,
  s('/Janu/Febr/Mar/Apr/Ma/Ju/Ju/Aug/Septe/Octo/Nove/Dece')[a]
  +s('/ary/uary/ch/il/y/ne/ly/ust/mber/ber/mber/mber')[c]+` ${b}, `+y
)

console.log=x=>O.innerHTML+=x+'\n'

;['10/31/1998','25/12/1989','10/8/2011','8/5/1957','9/12/2012','1/1/2000']
.forEach(x=>console.log(x+' -> '+F(x)))
<pre id=O></pre>


2

Python 3 (290 byte)

Simile alla risposta di Ashwin Gupta, ma sfruttando il modulo calendario di Python per evitare di scrivere tutti i nomi dei mesi.

import calendar as C
M,I,P,S,L,A=C.month_name,int,print," ",len,", "
def d(i):
 w=i.split("/")
 f,s,y=I(w[0]),I(w[1]),w[2]
 if(f>12):P(M[s]+S+w[0]+A+y)
 elif(s>12):P(M[f]+S+w[1]+A+y)
 else:l,h=min(f,s),max(f,s);P(M[l][:I(L(M[l])/2+.5)]+M[h][I(L(M[h])/2+.5):]+S+str(I((f+s)/2))+A+y)

Python 2 dovrebbe tagliare alcuni byte con divisione di interi e perdere le parentesi per print.


1

Python, 558 554 byte

Un esempio davvero, davvero, davvero orribilmente golfato di come farlo in Python. Mi dispiace, sono super cattivo con questa roba da golf D:. Funziona però. Sono sicuro che ci sono molti modi per semplificare questo, quindi fatemi sapere nei commenti. golfed:

import math
def d(i):
 l=["","January","February","March","April","May","June","July","August","September","October","November","December"]
 w=i.split('/')
 f=int(w[0])
 s=int(w[1])
 S=" "
 y=w[2]
 if(f>12):
  e=int(w[1])
  print(l[e]+S+w[0]+", "+y)
  elif(f<=12 and s>12):
   e=int(w[0])
   print(l[e]+S+w[0]+", "+y)
   else:
    if(f<s):
     o=l[f]
     t=l[s]
    else:
     o=l[s]
     t=l[f]
    o=o[0:int(math.ceil(len(o)/2))]
    t=t[int(math.ceil(len(t)/2)):len(t)]
    print(o+t+S +  str(math.floor((f + s)/2)) + ", " + y)

Ungolfed

import math
def d(i):
    l = ["", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
    w = i.split('/')
    f = int(w[0])
    s = int(w[1])
    y = w[2]
    if(f > 12):
        e = int(w[1])
        print(l[e] + " " + w[0] + ", " + y)

    elif(f <= 12 and s > 12):
         e = int(w[0])
         print(l[e] + " " + w[0] + ", " + y)
    else:
         if(f < s):
            o=l[f]
            t=l[s]
         else:
            o=l[s]
            t=l[f]
         o = o[0:int(math.ceil(len(o)/2))]
         t = t[int(math.ceil(len(t)/2)):len(t)]
         print(o+t+" " +  str(math.floor((f + s)/2)) + ", " + y)

Immagine dello schermo: inserisci qui la descrizione dell'immagine


metti S=" "in alto, quindi sostituisci ogni istanza di " "con S- che si raddrizzerà di alcuni byte
cat

ci sono alcuni spazi non necessari dopo le assegnazioni ( e= int[..., o = o...). inoltre, potrebbe rivelarsi avventuroso impostare chiamate di uso frequente come intsu lettere maiuscole a lettera singola
cat

1
Ecco 447 byte:from math import* I=int S=" " C="," L=len P=print def d(i): l=["","January","February","March","April","May","June","July","August","September","October","November","December"];w=i.split('/');f=I(w[0]);s=I(w[1]);y=w[2] if f>12:e=I(w[1]);P(l[e]+S+w[0]+C+S+y) elif f<13and s>12:e=I(w[0]);P(l[e]+S+w[0]+C+S+y) else: if f<s:o=l[f];t=l[s] else:o=l[s];t=l[f];o=o[0:I(ceil(L(o)/2))];t=t[I(ceil(L(t)/2)):L(t)] P(o+t+S+str(floor((f+s)/2))+C+S+y)
cat

1
@sysreq ok la mia mente è ufficialmente soffiata. Non sapevo che potresti memorizzare le funzioni in una variabile. Grazie. Lo modificherò in. Inoltre, potresti farmi un favore e provare a eseguire il mio codice (uno a golf) e vedere se funziona come dovrebbe perché Luke sembra ottenere risultati diversi rispetto a me, quindi voglio solo vedere.
Ashwin Gupta,

1
@sysreq yeah idk. Perché è diverso per lui. Comunque, grazie ancora per i suggerimenti, aiuta davvero non solo per il golf, ma in generale dato che sono ancora nuovo su Python. Inoltre, ho appena realizzato che posso rimuovere le mie assegnazioni iniziali di o e t e salvare 4 byte inserendo l'elemento array direttamente nel mio splitter. Farò tutti questi cambiamenti questo pomeriggio. Grazie a te il nuovo numero di byte sarà significativamente inferiore!
Ashwin Gupta,

0

PHP, 301 294 byte

function r($t){$e='return date("F",mktime(0,0,0,$o));';list($a,$b,$c)=explode('/',$t);$o=min($a,$b);$m=eval($e);$o=max($a,$b);$n=eval($e);echo(($a|$b)<13)?substr($m,0,ceil(strlen($m)/2)).substr($n,ceil(strlen($n)/2))." ".floor(($a+$b)/2).", $c":date("F j, Y",strtotime(($a>12)?"$b/$a/$c":$t));}

Pensavo di poter competere con la risposta Javascript. Oh bene.

Penso che potrei ridurlo e non mi piace il codice che ho usato per le date ambigue. Penso che ci sia un modo migliore per farlo.

Ungolfed:

function r($t){
    // Eval'd code to reduce char count
    $e='return date("F",mktime(0,0,0,$o));';

    // Split the date
    list($a,$b,$c)=explode('/',$t);

    // Get the earliest month
    $o=min($a,$b);
    $m=eval($e);

    // Get the latest month
    $o=max($a,$b);
    $n=eval($e);

    // If ambiguous
    if ($a<13 && $b<13) {
        print substr($m,0,ceil(strlen($m)/2)).substr($n,ceil(strlen($n)/2))." ".floor(($a+$b)/2).", $c";
    }
    else {
        print date("F j, Y",strtotime(($a>12)?"$b/$a/$c":$t));
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.