Beilegung des Datumsformatstreits

17

Die Formatierungsreihenfolge von Datumsangaben ist eines der komplexesten und umstrittensten Probleme, mit denen die Welt heute konfrontiert ist. Einige von uns argumentieren vehement, dass Monat / Tag / Jahr angemessen ist, wenn man bedenkt, wie wir sagen, dass Daten laut sind. Andere proklamieren lautstark, dass Tag / Monat / Jahr am besten ist, da die Begriffe in aufsteigender Reihenfolge der Dauer aufgeführt werden, die sie darstellen.

Genug ist genug. Computer können diesen Streit einfach und fair lösen. Ihr Code, eine vollständige Funktion oder ein Programm, enthält eine durch Schrägstriche begrenzte Datumszeichenfolge, z 12/1/2015. Beachten Sie, dass dies das genaue Format ist, ohne führende Nullen und mit einem vierstelligen Jahr am Ende.

  • Wenn es sich definitiv um Monat / Tag / Jahr handelt, geben Sie beispielsweise 10/31/1998eine Textdarstellung dieses Datums in genau diesem Format mit dem vollständigen Monatsnamen, Tag und Jahr aus:October 31, 1998
  • Wenn es definitiv Tag / Monat / Jahr, zum Beispiel 25/12/1989, Ausgabe der gleiche Art von Textdarstellung: December 25, 1989.
  • Wenn es nicht eindeutig ist, ob es sich um Monat / Tag / Jahr oder Tag / Monat / Jahr handelt, geben Sie ein Datum aus, mit dem die Mehrdeutigkeit behoben wird, indem Sie die beiden möglichen Daten wie folgt kombinieren:
    1. Erstellen Sie einen neuen Monatsnamen, indem Sie die erste Hälfte des Namens des vorherigen Monats übernehmen und die zweite Hälfte des späteren Monats anhängen . Für Monate mit ungerader Länge erhält die erste Hälfte den zusätzlichen Buchstaben. Um explizit, sind die ersten Hälften der Monate Janu, Febr, Mar, Apr, Ma, Ju, Ju, Aug, Septe, Octo, Nove, und Deceund die zweiten Hälften sind daher ary, uary, ch, il, y, ne, ly, ust, mber, ber, mber, und mber.
    2. Berechnen Sie den Tag, indem Sie den Durchschnitt der zwei möglichen Tage bilden und dabei das Wort ergreifen, wenn der Durchschnitt keine ganze Zahl ist.
    3. Die Textdarstellung dieses Datums 10/8/2011ausgeben , zB für Ausgabe Augber 9, 2011.

Wenn das Eingabedatum nicht Monat / Tag / Jahr oder Tag / Monat / Jahr sein kann (z. B. 13/13/2013oder sogar 2/30/2002), ist jedes Verhalten akzeptabel. Dieser Code Golf, der kürzeste Code gewinnt!

Testfälle:

10/31/1998 gibt October 31, 1998

25/12/1989 gibt December 25, 1989

10/8/2011 gibt Augber 9, 2011

8/5/1957 gibt Maust 6, 1957

9/12/2012 (seltsamerweise) gibt September 10, 2012

1/1/2000 gibt January 1, 2000

Luke
quelle
20
Für das, was es wert ist, sagen viele, die sich für Tag-Monat-Jahr aussprechen, auch Daten in dieser Reihenfolge. (Natürlich argumentieren echte Programmierer für Jahr-Monat-Tag).
Peter Taylor
Nur um sicher zu gehen: without leading zeroes and with a four-digit year at the endimpliziertyear >= 1000
edc65
Das ist richtig.
Luke
1
+ ∞ für den 10. September 2012
ev3commander

Antworten:

1

Pyth - 156 Bytes

Wirklich schlechter Code, und muss gepackte Zeichenfolgen verwenden, aber es ist etwas.

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 .

Maltysen
quelle
3

Mathematica 341 304 298 288 293 Bytes

Hierbei wird eine reine oder anonyme Funktion verwendet, dh eine Funktion ohne eigenen Namen.

DateStringGibt eine Fehlermeldung zurück, wenn das Datum nicht eindeutig ist. CheckFängt die Mehrdeutigkeit ab und sendet das beleidigende Datum an DateList, wodurch es in eine Liste von 3 ganzen Zahlen umgewandelt wird (von denen es glaubt, dass sie es sind {year, month, day}). Die Ganzzahlen für Monat und Tag werden nach Größe sortiert und zur Bestimmung von Monat und Tag gemäß den Anweisungen des OP verwendet.

Quiet Bringt den Fehler beim Drucken zum Schweigen.

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. Oktober 1998", "25. Dezember 1989", "9. August 2011", "Maust 6, 1957", "10. September 2012", "1. Januar 2012"}

DavidC
quelle
Ich persönlich würde gerne sehen, wie Sie diese 0 eliminieren, aber ich lasse die Stimmen fallen, wie sie mögen.
Luke
Es wird nun wie angefordert "1. Januar 2012" zurückgegeben.
DavidC
3

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

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

Bearbeiten: Verwendet toLocaleString, um Monatsnamen zu generieren. Ändern Sie das Gebietsschema, um Ergebnisse mit Monatsnamen in verschiedenen Gebietsschemas zu erhalten!

Edit 2: Generiert jetzt zwei Monatsnamen anstatt aller 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]
)

Beispiel:

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

Dank an:
@ user81655 , 274 => 246 Bytes
@ edc65 , 246 => 238 Bytes

usandfriends
quelle
1
Ich habe nicht sehr gründlich gesucht , aber hier ein paar Verbesserungen , die Sie machen können: Änderung Math.ceil(e[c].length/2)zu (r=e[c].length/2)+r%1, Array(2).fill().map((_,f)=>...)zu f=>...und jeden e[n]zu e(n), i=+(g>h)zu i=g>hund e[i]zu e[+i], entfernen Sie die unnötigen Klammern in dem letzten ternären Operator, auch newDatesollte new Date.
user81655
1
Vermeiden Sie Math.ceilmitb=c=>e(c).length+1>>1
edc65
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)

Testschnipsel:

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>

edc65
quelle
2

Python 3 (290 Bytes)

Ähnlich wie die Antwort von Ashwin Gupta, jedoch unter Ausnutzung von Pythons Kalendermodul, um nicht alle Monatsnamen auszuschreiben.

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 sollte ein paar Bytes mit einer Ganzzahldivision abschneiden und die Klammern für verlieren print.

Jack Brounstein
quelle
1

Python, 558 554 Bytes

Ein wirklich, wirklich, wirklich schrecklich gelungenes Beispiel, wie man das in Python macht. Entschuldigung, ich bin super schlecht in diesem Golfspielzeug D:. Es funktioniert aber. Ich bin mir sicher, dass es viele Möglichkeiten gibt, dies zu vereinfachen. Lassen Sie es mich in den Kommentaren wissen. Golf gespielt:

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)

Bildschirmfoto: Bildbeschreibung hier eingeben

Ashwin Gupta
quelle
setze S=" "oben drauf und ersetze dann jede Instanz von " "mit S- das spart ein paar Bytes
cat
Nach Zuweisungen ( e= int[..., o = o...) stehen einige unnötige Leerzeichen . Es könnte sich auch als abenteuerlich erweisen, häufig verwendete Anrufe intauf Großbuchstaben zu setzen
cat
1
Hier sind 447 Bytes: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, mein Verstand ist offiziell durchgebrannt. Ich wusste nicht, dass Sie Funktionen in einer Variablen speichern können. Vielen Dank. Ich werde das nachbearbeiten. Könnten Sie mir auch einen Gefallen tun und versuchen, meinen Code (einen mit Golf) auszuführen und zu prüfen, ob er so funktioniert, wie er sollte, weil Luke offenbar andere Ergebnisse erzielt als ich, also möchte ich nur sehen.
Ashwin Gupta
1
@ Sysreq ja Idk. Warum ist es anders für ihn. Trotzdem, nochmals vielen Dank für die Tipps, es hilft nicht nur beim Golfen, sondern generell, da ich noch neu in Python bin. Außerdem wurde mir gerade klar, dass ich meine anfänglichen Zuweisungen von o und t entfernen und 4 Bytes sparen kann, indem ich das Array-Element direkt in meinen Splitter lege. Ich werde all diese Änderungen heute Nachmittag vornehmen. Dank Ihnen wird die Anzahl der neuen Bytes deutlich geringer sein!
Ashwin Gupta
0

PHP, 301 294 Bytes

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

Ich dachte, ich könnte mit der Javascript-Antwort mithalten. Naja.

Ich glaube, ich könnte es verkleinern und ich mag den Code, den ich für die mehrdeutigen Daten verwendet habe, nicht. Ich denke, es gibt einen besseren Weg, dies zu tun.

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));
    }
}
Kodos Johnson
quelle