Rozwiązywanie sporu dotyczącego formatu daty

17

Kolejność formatowania dat jest jedną z najbardziej złożonych i dzielących kwestii, przed którymi stoi dziś świat. Niektórzy z nas zdecydowanie twierdzą, że miesiąc / dzień / rok jest właściwy, biorąc pod uwagę, że tak mówimy na głos. Inni głośno ogłaszają, że dzień / miesiąc / rok jest najlepszy, ponieważ ustawia terminy w porządku rosnącym według czasu, który reprezentują.

Wystarczy. Komputery mogą rozwiązać ten spór w prosty i uczciwy sposób. Twój kod, pełna funkcja lub program, będzie zawierał ciąg daty oddzielony ukośnikami, np 12/1/2015. Uwaga: jest to dokładny format, bez zer wiodących i czterocyfrowego roku na końcu.

  • Jeśli jest to zdecydowanie Miesiąc / Dzień / Rok, np. 10/31/1998Wypisz tekstową reprezentację tej daty w dokładnie takim formacie, z pełną nazwą miesiąca, dniem i rokiem:October 31, 1998
  • Jeśli jest to zdecydowanie dzień / miesiąc / rok, na przykład 25/12/1989, wyjście tego samego rodzaju reprezentacji tekstu: December 25, 1989.
  • Jeśli nie jest jednoznaczne, czy jest to miesiąc / dzień / rok, czy dzień / miesiąc / rok, wpisz datę, która rozwiązuje niejednoznaczność, łącząc dwie możliwe daty w następujący sposób:
    1. Utwórz nową nazwę miesiąca, biorąc pierwszą połowę nazwy z poprzedniego miesiąca i dołącz drugą połowę późniejszego miesiąca. W przypadku miesięcy o nieparzystej długości pierwsza połowa otrzymuje dodatkową literę. Aby być jawne, pierwsze połówki miesiącach są Janu, Febr, Mar, Apr, Ma, Ju, Ju, Aug, Septe, Octo, Nove, i Dece, a drugie połówki są zatem ary, uary, ch, il, y, ne, ly, ust, mber, ber, mber, i mber.
    2. Oblicz dzień, uśredniając dwa możliwe dni, zabierając głos, gdy średnia nie jest liczbą całkowitą.
    3. Wydrukuj tekstową reprezentację tej daty, np. Dla 10/8/2011danych wyjściowych Augber 9, 2011.

Jeśli datą wejściową nie może być miesiąc / dzień / rok lub dzień / miesiąc / rok (np. 13/13/2013Lub nawet 2/30/2002), każde zachowanie jest dopuszczalne. Ten kod golf, najkrótszy kod wygrywa!

Przypadki testowe:

10/31/1998 daje October 31, 1998

25/12/1989 daje December 25, 1989

10/8/2011 daje Augber 9, 2011

8/5/1957 daje Maust 6, 1957

9/12/2012 (co dziwne) daje September 10, 2012

1/1/2000 daje January 1, 2000

Łukasz
źródło
20
Dla tego, co warto, wielu z tych, którzy spierają się o dzień-miesiąc-rok, również podaje daty w tej kolejności. (Oczywiście prawdziwi programiści kłócą się o dzień-miesiąc-dzień).
Peter Taylor,
Dla pewności: without leading zeroes and with a four-digit year at the endsugerujeyear >= 1000
edc65
To jest poprawne.
Łukasz
1
+ ∞ na 10 września 2012 r.
dowódca ev3,

Odpowiedzi:

1

Pyth - 156 bajtów

Naprawdę zły kod i trzeba będzie użyć spakowanych ciągów, ale to coś.

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

Pakiet testowy .

Maltysen
źródło
3

Mathematica 341 304 298 288 293 bajtów

Wykorzystuje funkcję czystą lub anonimową, to znaczy funkcję bez własnej nazwy.

DateStringzwraca komunikat o błędzie, jeśli data jest niejednoznaczna. Checkwyłapuje niejednoznaczność i przesyła datę przestępstwa na adresDateList , która przekształca ją w listę 3 liczb całkowitych (które według niego są {year, month, day}). Liczby całkowite miesiąca i dnia są sortowane według wielkości i używane do określenia miesiąca i dnia zgodnie z instrukcjami PO.

Quiet wycisza błąd drukowania.

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 października 1998 r.”, „25 grudnia 1989 r.”, „9 sierpnia 2011 r.”, „6 maja 1957 r.”, „10 września 2012 r.”, „1 stycznia 2012 r.”}

DavidC
źródło
Osobiście chciałbym zobaczyć, jak eliminujesz to 0, ale pozwolę, aby głosy spadły, jak mogą.
Łukasz
Zwraca teraz „1 stycznia 2012 r.” Zgodnie z żądaniem.
DavidC,
3

JavaScript (ES6), 311 295 282 274 246 238 bajtów

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

Edycja: służy toLocaleStringdo generowania nazw miesięcy. Zmień ustawienia regionalne, aby uzyskać wyniki przy użyciu nazw miesięcy w różnych lokalizacjach!

Edycja 2: Teraz generuje nazwy dwóch miesięcy zamiast wszystkich 12!

Nie golfowany:

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

Przykład:

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

Dzięki:
@ user81655 , 274 => 246 bajtów
@ edc65 , 246 => 238 bajtów

usandfriends
źródło
1
Nie przyjrzałem się dogłębnie, ale oto kilka ulepszeń, które możesz wprowadzić: zmień Math.ceil(e[c].length/2)na (r=e[c].length/2)+r%1, Array(2).fill().map((_,f)=>...)do f=>...i e[n]do e(n), i=+(g>h)do i=g>hi e[i]do e[+i], usuń niepotrzebne nawiasy w ostatnim operatorze trójskładnikowym, również newDatepowinno być new Date.
user81655,
1
Unikaj Math.ceilużywaniab=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)

Fragment testowy:

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
źródło
2

Python 3 (290 bajtów)

Podobne do odpowiedzi Ashwina Gupty, ale korzystając z modułu kalendarza Pythona, aby uniknąć zapisywania wszystkich nazw miesięcy.

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 powinien przyciąć kilka bajtów z dzieleniem liczb całkowitych i zgubieniem nawiasów print.

Jack Brounstein
źródło
1

Python, 558 554 bajtów

Naprawdę, naprawdę, naprawdę strasznie golfowy przykład tego, jak to zrobić w Pythonie. Przepraszam, jestem bardzo zła w tych sprawach golfowych D:. Ale to działa. Jestem pewien, że istnieje wiele sposobów na uproszczenie tego, więc daj mi znać w komentarzach. Gra w golfa:

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)

Bez golfa

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)

Zrzut ekranu: wprowadź opis zdjęcia tutaj

Ashwin Gupta
źródło
umieścić S=" "w górę, a następnie zastąpienie każde wystąpienie " "z S- które golić kilka bajtów
kot
po przypisaniach jest kilka niepotrzebnych spacji ( e= int[..., o = o...). może również okazać się ryzykowne wykonywanie często używanych połączeń, takich jak intwieloliterowe zmienne
cat
1
Oto 447 bajtów: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 mój umysł jest oficjalnie zdmuchnięty. Nie wiedziałem, że możesz przechowywać funkcje w zmiennej. Dziękuję Ci. Zredaguję to. Możesz też wyświadczyć mi przysługę i spróbować uruchomić mój kod (golfowy) i sprawdzić, czy działa tak, jak powinien, ponieważ Luke wydaje się uzyskiwać inne wyniki niż ja, więc chcę to zobaczyć.
Ashwin Gupta,
1
@sysreq yeah idk. Dlaczego dla niego jest inaczej. W każdym razie, jeszcze raz dziękuję za wskazówki, to naprawdę pomaga nie tylko w golfa, ale ogólnie, ponieważ wciąż jestem nowy w Pythonie. Właśnie zdałem sobie sprawę, że mogę usunąć moje początkowe przypisania o i t oraz zapisać 4 bajty, umieszczając element tablicy bezpośrednio w moim spliterze. Dokonam tych wszystkich zmian po południu. Dzięki tobie nowa liczba bajtów będzie znacznie mniejsza!
Ashwin Gupta,
0

PHP, 301 294 bajtów

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

Myślałem, że mogę konkurować z odpowiedzią JavaScript. No cóż.

Myślę, że mógłbym go zmniejszyć i nie podoba mi się kod użyty do dwuznacznych dat. Myślę, że jest na to lepszy sposób.

Nie golfowany:

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
źródło