解决日期格式纠纷


17

日期的格式顺序是当今世界面临的最复杂和分歧最大的问题之一。考虑到我们这么说,我们当中有些人激烈地认为“月/日/年”是适当的。其他人则大声疾呼说,“天/月/年”是最好的,因为它会将术语按其表示的持续时间升序排列。

适可而止。计算机可以简单,公平地解决此争议。您的代码(一个完整的函数或程序)将使用一个以斜杠分隔的日期字符串,例如12/1/2015。请注意,这是确切的格式,没有前导零,并且末尾有四位数的年份。

  • 如果绝对是月/日/年,例如10/31/1998,则以该确切格式输出该日期的文本表示,并带有完整的月份名称,日期和年份:October 31, 1998
  • 例如,如果绝对是日/月/年25/12/1989,则输出相同类型的文本表示形式:December 25, 1989
  • 如果是月/日/年还是日/月/年的模棱两可,请通过组合以下两个可能的日期来输出可解决歧义的日期:
    1. 通过取的名字上半年创建一个新的月份名称前面月份和下半年追加一个月。对于长度不固定的月份,前半部分会收到多余的字母。要明确,月份的第一半部JanuFebrMarAprMaJuJuAugSepteOctoNove,和Dece因此第二半部aryuarychilynelyustmberbermber,和mber
    2. 通过将两个可能的天数取平均值来计算天数,当平均值不是整数时取下限。
    3. 输出该日期的文本表示形式,例如对于10/8/2011output Augber 9, 2011

如果输入日期不能是月/日/年或日/月/年(例如13/13/2013甚至2/30/2002),则任何行为都是可以接受的。此代码高尔夫,最短的代码获胜!

测试用例:

10/31/1998October 31, 1998

25/12/1989December 25, 1989

10/8/2011Augber 9, 2011

8/5/1957Maust 6, 1957

9/12/2012 (足够)给 September 10, 2012

1/1/2000January 1, 2000



20
出于价值考虑,许多主张日月年的人也按该顺序说日期。(当然,Real Programmers会争论年月日)。
彼得·泰勒

只需确定:就without leading zeroes and with a four-digit year at the end意味着year >= 1000
edc65

没错
路加福音

Answers:


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

数学341 304 298 288 293字节

它使用纯函数或匿名函数,即没有自己名称的函数。

DateString如果日期不明确,则返回错误消息。Check捕获歧义并将错误日期发送到DateList,将其转换为3个整数(据信是{year, month, day})的列表。月和日整数按大小排序,并根据OP的说明确定月和日。

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"}

{“ 1998年10月31日”,“ 1989年12月25日”,“ 2011年8月9日”,“ 1957年6月6日”,“ 2012年9月10日”,“ 2012年1月1日”}


我个人很希望看到您消除那个0,但我会让票数尽可能减少。
路加福音

现在,它按要求返回“ 2012年1月1日”。
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')
);

感谢:
@ user81655274 => 246字节
@ edc65246 => 238个字节


1
我还没有看得很透彻,但这里的一些改进,你可以做:变化Math.ceil(e[c].length/2)(r=e[c].length/2)+r%1Array(2).fill().map((_,f)=>...)f=>...,每e[n]e(n)i=+(g>h)i=g>he[i]e[+i],除去最后的三元运营商不必要的括号,而且,newDate应该是new Date
user81655 2015年

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字节)

与Ashwin Gupta的答案类似,但要利用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,558554字节

关于如何在python中执行此操作的一个非常非常非常糟糕的例子。抱歉,我对这种打高尔夫球的东西非常不满意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单字母大写var 这样的常用调用可能是冒险的
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)
cat

1
@sysreq好的,我的想法正式被炸了。我不知道您可以将函数存储到变量中。谢谢。我将对其进行编辑。此外,您能帮我一个忙,然后尝试运行我的代码(查询的代码),看看它是否按预期工作,因为Luke似乎得到的结果与我不同,所以我只想看看。
阿什温·古普塔

1
@sysreq是的idk。为什么对他来说有所不同。无论如何,再次感谢您的提示,它不仅对打高尔夫球很有帮助,而且总的来说,因为我还是Python的新手。另外,我刚刚意识到我可以删除o和t的初始分配,并通过将他的数组元素直接放入拆分器中来节省4个字节。我将在今天下午进行所有这些更改。多亏了您,新的字节数才会大大减少!
Ashwin Gupta

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));
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.