การแก้ไขข้อพิพาทรูปแบบวันที่


17

ลำดับการจัดรูปแบบของวันที่เป็นหนึ่งในปัญหาที่ซับซ้อนและแตกแยกที่สุดที่โลกเผชิญอยู่ทุกวันนี้ พวกเราบางคนแย้งว่าเดือน / วัน / ปีมีความเหมาะสมพิจารณาว่าเป็นวิธีที่เราพูดออกมาดัง ๆ คนอื่น ๆ ดังประกาศว่าวัน / เดือน / ปีที่ดีที่สุดเพราะมันทำให้เงื่อนไขในลำดับที่มากขึ้นของระยะเวลาที่พวกเขาเป็นตัวแทน

พอคือพอ. คอมพิวเตอร์สามารถแก้ไขข้อพิพาทนี้ได้อย่างเรียบง่ายและยุติธรรม 12/1/2015รหัสของคุณฟังก์ชั่นที่สมบูรณ์หรือโปรแกรมจะใช้สตริงวันที่คั่นด้วยเครื่องหมายทับเช่น โปรดทราบว่านี่เป็นรูปแบบที่แน่นอนโดยไม่มีเลขศูนย์นำหน้าและมีปีสี่หลักในตอนท้าย

  • ถ้ามันแน่นอนเดือน / วัน / ปีเช่น10/31/1998การส่งออกการแสดงข้อความของวันนั้นในรูปแบบตรงนี้มีชื่อเต็มเดือนวันและปี:October 31, 1998
  • ถ้ามันแน่นอนวัน / เดือน / ปีเช่นการส่งออกในประเภทเดียวกันของการแสดงข้อความ:25/12/1989December 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, และmbermber
    2. คำนวณวันโดยหาค่าเฉลี่ยของสองวันที่เป็นไปได้โดยเริ่มจากพื้นเมื่อค่าเฉลี่ยไม่ใช่จำนวนเต็ม
    3. เอาท์พุทการแสดงข้อความของวันนี้เช่นสำหรับการส่งออก10/8/2011Augber 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
สำหรับสิ่งที่คุ้มค่าผู้ที่ถกเถียงกันในวันเดือนปีก็พูดตามลำดับ (แน่นอนโปรแกรมเมอร์จริงเถียงสำหรับปีเดือนวัน)
Peter Taylor

เพียงเพื่อให้แน่ใจว่า: without leading zeroes and with a four-digit year at the endนัยyear >= 1000
edc65

ถูกต้อง.
ลุค

1
+ ∞สำหรับ 10 กันยายน 2555
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

Test Suite


3

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

{"31 ตุลาคม 2541", "25 ธันวาคม 1989", "9 สิงหาคม 2554", "Maust 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 ไบต์)

คล้ายกับคำตอบของ 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)

งูหลาม 2 printควรตัดกี่ไบต์ที่มีการแบ่งจำนวนเต็มและการสูญเสียวงเล็บ


1

Python, 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)

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- ที่จะลบล้างบางไบต์
cat

มีช่องว่างที่ไม่จำเป็นเล็กน้อยหลังจากการมอบหมาย ( e= int[..., o = o...) นอกจากนี้ยังอาจพิสูจน์ได้ว่าการตั้งค่าการโทรที่ใช้งานบ่อยเช่นintvars ตัวพิมพ์ใหญ่ตัวอักษร
cat

1
นี่คือ 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 ตกลงใจของฉันถูกระเบิดอย่างเป็นทางการ ฉันไม่รู้ว่าคุณสามารถจัดเก็บฟังก์ชันไว้ที่ตัวแปรได้ ขอขอบคุณ. ฉันจะแก้ไขสิ่งต่อไปนี้นอกจากนี้คุณช่วยฉันหน่อยได้ไหมและลองใช้รหัสของฉัน (เล่นกอล์ฟ) และดูว่ามันทำงานได้ดีหรือไม่เพราะลุคดูเหมือนจะได้ผลลัพธ์ที่แตกต่างจากฉันดังนั้นฉันแค่ต้องการเห็น
Ashwin Gupta

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 ได้ โอ้ดี

ฉันคิดว่าฉันสามารถทำให้มันเล็กลงและฉันไม่ชอบรหัสที่ฉันใช้สำหรับวันที่ไม่ชัดเจน ฉันคิดว่ามีวิธีที่ดีกว่าที่จะทำ

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));
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.