Вирішення спору щодо формату дати


17

Порядок форматування дат є одним із найскладніших та найрізноманітніших питань, з якими стикається світ сьогодні. Деякі з нас наполегливо стверджують, що місяць / день / рік є відповідним, вважаючи, що саме так ми кажемо дати вголос. Інші голосно проголошують, що день / місяць / рік найкращий, оскільки він розміщує умови у порядку зростання за тривалістю, яку вони представляють.

Досить значить досить. Комп'ютери можуть вирішити цю суперечку просто та справедливо. Ваш код, повна функція або програма, буде приймати рядок дати, розділену косою рисою, наприклад 12/1/2015. Зауважте, що це точний формат, без провідних нулів та з чотиризначним роком у кінці.

  • Якщо це безумовно місяць / день / рік, наприклад 10/31/1998, виведіть текстове подання цієї дати у такому точному форматі з повною назвою місяця, день та рік:October 31, 1998
  • Якщо це , безумовно , день / місяць / рік, наприклад 25/12/1989, вихід такого ж роду текстове представлення: December 25, 1989.
  • Якщо це неоднозначно, чи це місяць / день / рік чи день / місяць / рік, виведіть дату, яка вирішує двозначність, поєднуючи дві можливі дати наступним чином:
    1. Створіть назву нового місяця, взявши першу половину назви попереднього місяця та додайте другу половину пізнього місяця. За місяці з непарною тривалістю перша половина отримує додатковий лист. Для того, щоб бути явними, перші половинки місяців Janu, Febr, Mar, Apr, Ma, Ju, Ju, Aug, Septe, Octo, Nove, і , Deceа другі половинки, отже ary, uary, ch, il, y, ne, ly, ust, mber, ber, mber, і mber.
    2. Обчисліть день шляхом усереднення двох можливих днів, взявши підсумок, коли середнє значення не є цілим числом.
    3. Виведіть текстове подання цієї дати, наприклад, для 10/8/2011виводу Augber 9, 2011.

Якщо дата введення не може бути місяцем / днем ​​/ роком або днем ​​/ місяцем / роком (наприклад, 13/13/2013або навіть 2/30/2002), будь-яка поведінка є прийнятною. Цей код гольфу, найкоротший виграш коду!

Тестові приклади:

10/31/1998 дає October 31, 1998

25/12/1989 дає December 25, 1989

10/8/2011 дає Augber 9, 2011

8/5/1957 дає Maust 6, 1957

9/12/2012 (як не дивно) дає September 10, 2012

1/1/2000 дає January 1, 2000



20
Що варто, багато хто з тих, хто сперечається на день-місяць-рік, також кажуть дати в тому порядку. (Звичайно, реальні програмісти сперечаються на рік-місяць-день).
Пітер Тейлор

Просто для переконання: without leading zeroes and with a four-digit year at the endмається на увазіyear >= 1000
edc65

Це правильно.
Лука

1
+ ∞ за 10 вересня 2012 р.
ev3commander

Відповіді:


1

Pyth - 156 байт

Дійсно поганий код, і потрібно буде використовувати упаковані рядки, але це щось.

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

Тестовий сюїт .


3

Mathematica 341 304 298 288 293 байт

При цьому використовується чиста або анонімна функція, тобто функція без власного імені.

DateStringповертає повідомлення про помилку, якщо дата неоднозначна. Checkвиявляє неоднозначність і надсилає дату DateList, що порушує , що перетворює її у список із 3 цілих чисел (які, на її думку, є {year, month, day}). Цілі місяці та дні сортуються за розмірами та використовуються для визначення місяця та дня згідно інструкцій ОП.

Quiet замовчує помилку друку.

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 жовтня 1998 р.", "25 грудня 1989 р.", "9 серпня 2011 р.", "6 липня 1957 р.", "10 вересня 2012 р.", "1 січня 2012 р."}


Я особисто хотів би, щоб ви ліквідували ці 0, але я дозволяю, щоб голоси падали як можна.
Лука

Тепер він повертається "1 січня 2012 року" відповідно до запиту.
DavidC

3

Javascript (ES6), 311 295 282 274 246 238 байт

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

Редагувати: Використовує toLocaleStringдля створення назв місяців. Змініть локаль, щоб отримати результати, використовуючи назви місяців у різних мовах!

Редагувати 2: Тепер генерує два місячні імена замість усіх 12!

Безголовки:

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

Приклад:

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

Завдяки:
@ user81655 , 274 => 246 байт
@ edc65 , 246 => 238 байт


1
Я не дивився дуже ретельно , але ось кілька поліпшень ви могли б зробити: зміна Math.ceil(e[c].length/2)до (r=e[c].length/2)+r%1, Array(2).fill().map((_,f)=>...)щоб f=>...і кожен e[n]до e(n), i=+(g>h)щоб i=g>hі e[i]до e[+i], видалити непотрібні дужки в останньому потрійному операторі, Крім того , newDateмає бути new Date.
user81655

1
Уникайте Math.ceilвикористанняb=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)

Фрагмент тесту:

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 байт)

Схожий на відповідь Ешвіна Гупта, але скориставшись календарним модулем Python, щоб уникнути виписування всіх імен місяця.

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 повинен обрізати кілька байт цілим поділом і втратити дужки для print.


1

Пітона, 558 554 байт

Дійсно, справді, дуже жахливо приклад гольфу, як це зробити в пітоні. Вибачте, мені дуже погано в цьому гольф D:. Це працює, хоча. Я впевнений, що існує маса способів спростити це, тому повідомте мене в коментарях. Гольф:

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)

Безумовно

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)

Знімок екрана: введіть тут опис зображення


помістити S=" "у верхній частині, а потім замінити кожен екземпляр " "з S- що буде збрити кілька байт
кіт

є кілька зайвих пробілів після призначення ( e= int[..., o = o...). Крім того, може виявитися небажаним встановлювати часто використовувані дзвінки, як intоднолітерні великі регістри
кіт

1
Ось 447 байтів: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)
кіт

1
@sysreq Ок, мій розум офіційно підірваний. Я не знав, що ти можеш зберігати функції до змінної. Дякую. Я відредагую це. Також, чи можете ви зробити мені послугу і спробуйте запустити мій код (гольф) і побачити, чи працює він так, як слід, тому що Люк, здається, отримує інші результати, ніж я, тому я просто хочу побачити.
Ешвін Гупта

1
@sysreq так ідк. Чому для нього різне. У будь-якому випадку, ще раз дякую за поради, це справді допомагає не тільки для гри в гольф, але і взагалі, оскільки я все ще новачок у Python. Крім того, я щойно зрозумів, що можу видалити свої початкові завдання o і t і зберегти 4 байти, помістивши елемент масиву безпосередньо в мій сплітер. Всі ці зміни я внесу сьогодні вдень. Завдяки вам новий кількість байтів буде значно меншим!
Ешвін Гупта

0

PHP, 301 294 байт

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

Я думав, що можу змагатися з відповіддю Javascript. Що ж, добре.

Я думаю, що я міг би його зменшити і мені не подобається код, який я використовував для неоднозначних дат. Я думаю, що є кращий спосіб це зробити.

Безголовки:

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));
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.