อ่านวันที่ฟรีฟอร์มของฉัน


10

ป.ร. ให้ไว้ ณ วันที่เขียนในใด ๆ (ต้องจัดการทั้งหมดในโปรแกรมเดียวกัน) yyyy/mm/dd dateรูปแบบต่อไปแยกมันกลายเป็นที่ถูกต้อง

17th May 2012
March 14th, 2016
20 February 2014
September 14, 2017
Sunday, June 8, 2015

กฎระเบียบ

  • บางครั้งวันที่จะไม่ถูกต้องเช่น วันที่ไม่ถูกต้องสำหรับเดือนหรือจำนวนเดือนในหนึ่งปีคุณต้องจัดการทั้งสองกรณี ไม่ว่าคุณจะเลือกข้อผิดพลาดหรือคืนค่าเท็จที่สอดคล้องกัน (อย่างไรก็ตามจะยึดกับรูปแบบเทมเพลตด้านบน)
  • การเติมเต็มสำหรับวันและเดือนที่น้อยกว่า 10 ต้องใช้เพื่อสร้างเอาต์พุตสองหลัก
  • ชื่อเดือนจะเป็นชื่อเต็มเสมอไม่ใช่ย่อมาจากตัวละครทั้งสาม
  • คุณสามารถสมมติว่าปีจะอยู่ในช่วง 0000-9999
  • ไม่จำเป็นต้องจัดการกับจำนวนลบ
  • คุณสามารถสร้างโปรแกรมหรือฟังก์ชั่นเต็มรูปแบบเพื่อให้เอาต์พุตสามารถอยู่ในรูปแบบใด ๆ พิมพ์ไปยังคอนโซลหรือส่งคืนจากฟังก์ชัน
  • อินพุตจะเป็นสตริงเสมอเอาต์พุตจะต้องเป็นสตริงเสมอหากทำให้สั้นลงเพื่อใช้เป็นอาร์กิวเมนต์เดี่ยวในอาร์เรย์เช่น ["17th May 2012"]คุณสามารถทำได้และผลลัพธ์ก็เหมือนกัน["2012/05/17"]
  • คุณสามารถสมมติว่าการสะกดคำในอินพุตจะถูกต้อง

โบนัส:เพราะใครที่นี่ไม่ชอบความท้าทาย;)

หากคุณสามารถจัดการเพื่ออนุญาตรูปแบบการป้อนข้อมูลของคุณThe Fourteenth of March, 2016หรือMarch the Fourteenth, 2016คุณอาจใช้รหัสพิเศษของคุณเกิน20 ไบต์ด้วยจำนวนไบต์สุดท้ายใด ๆ ที่น้อยกว่า 1 ทำให้เกิด 1

นี่คือตัวเลขที่เขียนอย่างสมบูรณ์สำหรับแต่ละวันเพื่อหลีกเลี่ยงความสับสนในการสะกดคำ

First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Nineth, Tenth, Eleventh, Twelfth, Thirteenth, Fourteenth, Fifteenth, Sixteenth, Seventeenth, Eighteenth, Nineteenth, Twentieth, Twenty First, Twenty Second, Twenty Third, Twenty Fourth, Twenty Fifth, Twenty Sixth, Twenty Seventh, Twenty Eighth, Twenty Nineth, Thirtieth, Thirty First

กรณีทดสอบ

INPUT                           | Output
17th May 2012                   | 2012/05/17
March 14th, 2016                | 2016/03/14
20 February 2014                | 2014/02/20
September 14, 2017              | 2017/09/14
Sunday, June 8, 2015            | 2015/06/08
1st January 1918                | 1918/01/01

The Fourteenth of March, 2016   | 2016/03/14
March the Fourteenth, 2016      | 2016/03/14
November the Seventeenth, 2019  | 2019/11/17
The Thirtieth of April, 2016    | 2016/04/30

30 February 2014                | Invalid
September 99, 2017              | Invalid
Sunday, June8, 2015             | Invalid

The Thirty First of April, 2016 | Invalid


10
" เพราะใครที่นี่ไม่ชอบความท้าทาย " - เมื่อพวกเขามาในรูปของโบนัสส่วนใหญ่พวกเราทุกคนไม่ได้! และ boo-urns เพื่อตรวจสอบอินพุต
Shaggy

3
@ Mr.Xcoder ฉันคิดว่าความท้าทายทั้งหมดคือการสนับสนุนรูปแบบอินพุตที่หลากหลาย .. สิ่งต่าง ๆ เช่น20 February 2014การสนับสนุนเริ่มต้นในตัวแยกวิเคราะห์วันที่จำนวนมาก แต่17thและSunday, June 8, 2015ค่อนข้างยากที่จะแยกวิเคราะห์ (ขึ้นกับภาษา)
Kevin Cruijssen

1
@ Mr.Xcoder ฉันไม่เคยบอกว่ามันเป็นความสนุก / น่าเบื่อง่าย / ยากดี / ไม่ดี - ท้าทายรหัสกอล์ฟ ฉันเพียงแค่ระบุว่าตามสิ่งที่ฉันอ่านในความท้าทายการรองรับรูปแบบอินพุตหลายรูปแบบดูเหมือนจะเป็นเป้าหมายหลักของความท้าทาย ฉันยอมรับว่าน่าจะเป็น if-else สำหรับรูปแบบอินพุตห้ารูปแบบหรือ regex บางประเภทเพื่อแยกปีเดือนและวัน (ซึ่งปัจจุบันเป็นแนวทางของฉัน)
Kevin Cruijssen

3
วันในสัปดาห์ถูกต้องหรือไม่? จะThursday, August 25, 2017ถูกต้องไหม ฉันเห็นการส่งข้อมูลไม่สนใจ DOW
Benjamin Cuningham

คำตอบ:


4

Rails, 41 , 37 35 bytes

->x{x.to_date.strftime('%Y/%m/%d')}

ฉันไม่รู้ล่ามออนไลน์สำหรับ Rails แต่นี่เป็นภาพหน้าจอที่แสดงให้เห็นถึงกระบวนการนี้

ป้อนคำอธิบายรูปภาพที่นี่


ลิงค์ล่ามออนไลน์?
Jonathan Allan

1
สิ่งนี้ใช้ได้กับทุกรูปแบบที่เป็นปัญหาหรือไม่ : o
มนุษย์

@totallyhuman เพิ่มภาพหน้าจอที่แสดงผลลัพธ์ น่าเสียดายที่ฉันไม่รู้จักล่ามออนไลน์ :(
Suever

8

PowerShell , 91 89 91 56 ไบต์

date("$args"-replace'th|rd|st|(\b.*)day|,')-f yyyy/MM/dd

ลองออนไลน์!

รับอินพุตเป็นสตริง ใช้ a -replaceเพื่อกำจัดขยะจากนั้นใช้Get-Dateคำสั่งในตัวพร้อมกับ-fธง ormat เพื่อระบุyyyy/MM/ddรูปแบบที่ต้องการ สตริงนั้นจะถูกทิ้งไว้บนไปป์ไลน์และเอาท์พุทนั้นเป็นนัย

บันทึกสองไบต์ต้องขอบคุณ Mr Xcoder บันทึกก้อนใหญ่ด้วยการเล่นกอล์ฟ Regex ของ TessellatingHeckler


1
เฮ้ดูการส่ง PowerShell ที่แข่งขันได้!
Erik the Outgolfer

@EriktheOutgolfer Date การจัดการเป็นหนึ่งในจุดแข็งของ PowerShell
AdmBorkBork


@ Mr.Xcoder "ทั้งหมดเหล่านั้น" = 2 lol ขอบคุณ!
AdmBorkBork

คุณสามารถลบออก''จากรูปแบบวันที่สำหรับ -2 หากคุณต้องการยึดแนวทางของคุณให้ "การสะกดถูกต้อง" จากนั้นคุณสามารถแทนที่'th|rd|st|(\b.*)day|,'และมันลดลงถึง 56 ไบต์และจัดการกรณีเดียวกัน แม้ว่าฉันคิดว่ามันผิดเพราะถ้าคุณปล่อยวันคุณไม่สามารถรับ Sunday, June8, 2015 | Invalidคดีเพราะมันเป็นวันจันทร์ ควรมีข้อผิดพลาด แต่แยกวิเคราะห์ว่าถูกต้อง ไม่แน่ใจว่าการพิจารณาคดีนั้นจะเป็นเช่นไรหรือหากผู้อื่นตรวจสอบ
TessellatingHeckler

4

PHP, 73 164 + 1 ไบต์

for(preg_match("#(\d+)[^\d]+(\d+)#",$d=$argn,$r);$m++<12;)strpos(_.$d,date(F,strtotime($r[2].-$m)))&&printf(checkdate($m,$r[1],$r[2])?"$r[2]/%02d/%02d":E,$m,$r[1]);

ทำงานเป็นท่อที่มี-nRหรือลองออนไลน์

การตรวจสอบวันที่มีราคาแพงจริง ๆ : ฉันต้องแยกวันที่ก่อนที่จะใช้บิวอินแล้วลองและข้อผิดพลาดในชื่อเดือน


ฉันคิดว่าคุณต้องสนับสนุนทุกรูปแบบไม่ใช่แค่หนึ่งในนั้นเหรอ?
Erik the Outgolfer

1
@EriktheOutgolfer แต่ไม่ใช่รูปแบบโบนัส
ติตัส

@EriktheOutgolfer สิ่งนี้จัดการกับทุกรูปแบบ
Mr. Xcoder

1
สิ่งนี้ล้มเหลวเนื่องจากวันที่ไม่ถูกต้อง ผลตอบแทน30 February 2014 ไม่ว่าคุณจะเลือกข้อผิดพลาดหรือคืนค่าเท็จที่สอดคล้องกัน (อย่างไรก็ตามจะยึดตามรูปแบบเทมเพลตด้านบน)2014/03/02
Mr. Xcoder

@ Mr.Xcoder มันค่อนข้างจะทำลาย ...
ติตัส

3

Python 3 + ไลบรารี parsedatetime, 152 139 155 153 bytes

บันทึกแล้ว 13 ไบต์ขอบคุณ Jonathan Allan

เพิ่ม 16 ไบต์เพื่อจัดการวันที่ที่มีระยะเวลาไม่ถูกต้อง

บันทึก 2 ไบต์โดยลบการมอบหมายแลมบ์ดา

lambda s:re.search(f'(^| ){str(h(s)[0].tm_mday)[:2]}[^\d]',s)and time.strftime('%Y/%m/%d',h(s)[0])
import parsedatetime as p,time,re
h=p.Calendar().parse

ลองออนไลน์!

ไม่รองรับวันโบนัส


ยินดีต้อนรับสู่ PPCG! โพสต์แรกที่ดี บันทึก13 ไบต์โดยใช้: falsey return value of None; import ...as; & A lambdaโดยการนำเป็นparse h
Jonathan Allan

1

Python 2 , 193 ไบต์

lambda s:time.strftime('%Y/%m/%d',time.strptime(re.sub(r'^(\w+) (\d+)',r'\2 \1',re.sub('^ ','',re.sub('(th|rd|st)|(Sun|Mon|Tues|Wednes|Thurs|Fri|Satur)day|,','',s))),'%d %B %Y'))
import re,time

ลองออนไลน์!

; -; กรุณา halp


; -; กรุณา halp - 192 ไบต์timeด้วยการประกาศ
Mr. Xcoder


1

Java (OpenJDK 8) , 190 + 26 = 216 ไบต์

import java.time.format.*;

s->DateTimeFormatter.ofPattern("uuuu/MM/dd").format(DateTimeFormatter.ofPattern("[EEEE, ][d ]MMMM [d, ]uuuu").withResolverStyle(ResolverStyle.STRICT).parse(s.replaceAll("(\\d)[a-z].","$1")))

ลองออนไลน์!

หมายเหตุสำคัญ:มันสั้นกว่าในการตรวจสอบความถูกต้องของวันในสัปดาห์แทนที่จะทิ้งไว้ดังนั้นการตรวจสอบจึงรวมอยู่ด้วย!

ฉันไม่ได้ลองเลยSimpleDateFormatกว่ากรณีที่ชัดเจนซึ่งทุกวันที่ยอมรับเช่น 30 กุมภาพันธ์ ดังนั้นผมจึงต้องทิ้งมันและฉันใช้ Java DateTimeFormatter8

คำอธิบาย

"[EEEE, ][d ]MMMM [d, ]uuuu"

รูปแบบนี้หมายถึง:

  • เลือกวันในสัปดาห์ตามด้วยเครื่องหมายจุลภาคและเว้นวรรค[EEEE, ](เกิดขึ้นในSunday, ...)
  • ตามด้วยวันที่เป็นตัวเลือกที่มีพื้นที่[d ],
  • ตามด้วยเดือนในตัวอักษรเต็มMMMMและช่องว่าง
  • ตามด้วยวันที่เป็นตัวเลือกด้วยเครื่องหมายจุลภาคและพื้นที่[d, ],
  • ตามด้วยปีแห่งยุคuuuuเพื่อให้ parser รู้ว่าเราอยู่ในยุคเกรโกเรียน

รหัส:

import java.time.format.*;                                     // Required for DateTimeFormatter, *and* ResolverStyle

s->DateTimeFormatter.ofPattern("uuuu/MM/dd")                   // Output format
  .format(
    DateTimeFormatter.ofPattern("[EEEE, ][d ]MMMM [d, ]uuuu")  // Input format
      .withResolverStyle(ResolverStyle.STRICT)                 // Invalidates xxxx-02-30 instead of transforming it into xxxx-02-28
      .parse(
        s.replaceAll("(\\d)[a-z].","$1")                       // remove st, nd, rd, th
       )
    )

เครดิต

  • 2 ไบต์ใน regex ต้องขอบคุณ Neil

1
คุณต้องการวงเล็บในreplaceAllรูปแบบหรือไม่?
Neil

ดูเหมือนว่าฉันจะทำไม่ได้ ขอบคุณ @Neil!
Olivier Grégoire

1

JavaScript (ES6), 124 122 ไบต์

f=
s=>(d=new Date(s.replace(/.[dht]\b/,'')+' +0')).getDate()==s.match(/\d\d?/)&&d.toISOString().replace(/-(..)(T.*)?/g,'/$1')
<input oninput=o.textContent=f(this.value)><pre id=o>


ผลตอบแทน2015/06/07สำหรับJune 8, 2015(UTC ปัญหา? ผมอยู่ใน UTC + 2) และfalseสำหรับการอย่างใดอย่างหนึ่งหรือSunday, June 8, 2015 Monday, June 8, 2015
Olivier Grégoire

1
@ OlivierGrégoireขอบคุณที่ชี้ให้เห็น ฉันพยายามเพียงวันที่ในสหราชอาณาจักรนอกเวลาฤดูร้อนเพื่อให้พวกเขามีอยู่แล้วโดยใช้เวลา UTC ndayและฉันไม่ได้พยายามจะสิ้นสุดในวันธรรมดา
Neil
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.