Разрешение спора о формате даты


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!

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

Пример:

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

Python, 558 554 байта

Действительно, действительно, действительно ужасный пример того, как сделать это в Python. Извините, я очень плох в этом деле D:. Это работает, хотя. Я уверен, что есть много способов упростить это, поэтому дайте мне знать в комментариях. 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)

Скриншот: введите описание изображения здесь


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

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

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, да, idk. Почему он отличается от него. В любом случае, еще раз спасибо за советы, это действительно помогает не только для игры в гольф, но и в целом, так как я все еще новичок в 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. Ну что ж.

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

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));
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.