Đọc ngày tự do của tôi


10

Cho một ngày được viết bằng bất kỳ (phải xử lý tất cả trong cùng một chương trình) của các định dạng sau, phân tích nó thành hợp lệ yyyy/mm/dd date.

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

Quy tắc

  • Ngày đôi khi sẽ không hợp lệ, tức là. ngày không chính xác trong tháng hoặc số tháng trong một năm, bạn phải xử lý cả hai trường hợp. Hoặc bằng cách lỗi hoặc trả về một giá trị falsey nhất quán, bạn chọn. (Tuy nhiên, chúng sẽ bám vào các định dạng mẫu ở trên)
  • Đệm cho ngày và tháng dưới 10 phải được sử dụng để tạo đầu ra hai chữ số.
  • Tên tháng sẽ luôn là tên đầy đủ, không được rút ngắn thành ba ký tự của chúng.
  • Bạn có thể giả sử năm sẽ luôn nằm trong phạm vi 0000-9999.
  • Số âm không cần phải xử lý.
  • Bạn có thể tạo một chương trình hoặc chức năng đầy đủ để đầu ra có thể ở bất kỳ định dạng nào, được in ra bàn điều khiển hoặc được trả về từ một chức năng.
  • Đầu vào sẽ luôn là một chuỗi, đầu ra phải luôn là một chuỗi, nếu nó làm cho nó ngắn hơn để lấy nó làm một đối số trong một mảng, ví dụ. ["17th May 2012"]bạn có thể làm như vậy và đầu ra có thể giống nhau["2012/05/17"]
  • Bạn có thể giả sử chính tả trong đầu vào sẽ chính xác.

THƯỞNG: cos người ở đây không thích một thử thách;)

Nếu bạn có thể quản lý để cho phép các định dạng đầu vào The Fourteenth of March, 2016hoặc March the Fourteenth, 2016bạn có thể mất thêm 20 byte mã của mình với bất kỳ số byte cuối cùng nào có ít hơn 1 kết quả là 1.

Dưới đây là các số được viết đầy đủ cho mỗi ngày để tránh bất kỳ sự nhầm lẫn nào về chính tả.

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

Các trường hợp thử nghiệm

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
" cos người ở đây không thích thử thách " - khi họ đến dưới dạng tiền thưởng, hầu hết tất cả chúng ta đều không! Và boo-urns để xác nhận đầu vào.
Xù xì

3
@ Mr.Xcoder Tôi nghĩ rằng toàn bộ Thách thức là để hỗ trợ nhiều định dạng đầu vào .. Những điều thích 20 February 2014là mặc định hỗ trợ trong nhiều ngày-parsers, nhưng 17thSunday, June 8, 2015là khó khăn hơn một chút để phân tích cú pháp (tùy thuộc vào ngôn ngữ).
Kevin Cruijssen

1
@ Mr.Xcoder Tôi chưa bao giờ nói đó là một thử thách chơi gôn vui / nhàm chán, dễ / khó, tốt / xấu. Tôi chỉ đơn giản nói rằng dựa trên những gì tôi đọc được trong thử thách, việc hỗ trợ nhiều định dạng đầu vào dường như là mục tiêu chính của thử thách. Tôi đồng ý rằng nó rất có thể sẽ là một if-other cho năm định dạng đầu vào, hoặc một loại regex nào đó để trích xuất năm, tháng và ngày (hiện là cách tiếp cận của tôi).
Kevin Cruijssen

3
Là ngày trong tuần luôn đúng? Sẽ Thursday, August 25, 2017hợp lệ? Tôi thấy đệ trình bỏ qua DOW.
Benjamin Cuningham

Câu trả lời:


4

Rails, 41 , 37 35 byte

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

Tôi không biết về một thông dịch viên trực tuyến cho Rails, nhưng đây là một ảnh chụp màn hình chứng minh điều này

nhập mô tả hình ảnh ở đây


Liên kết phiên dịch trực tuyến?
Jonathan Allan

1
Điều này thực sự làm việc cho tất cả các định dạng trong câu hỏi? : o
hoàn toàn là

@totallyhuman Đã thêm ảnh chụp màn hình hiển thị kết quả. Thật không may, tôi không biết về một thông dịch viên trực tuyến :(
Suever

8

PowerShell , 91 89 91 56 byte

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

Hãy thử trực tuyến!

Đưa đầu vào dưới dạng một chuỗi. Sử dụng -replaceđể loại bỏ rác, sau đó sử dụng Get-Datelệnh tích hợp với -fcờ ormat để chỉ yyyy/MM/ddđịnh định dạng được yêu cầu . Chuỗi đó được để lại trên đường ống và đầu ra là ẩn.

Đã lưu hai byte nhờ Mr Xcoder. Tiết kiệm được một khoản lớn nhờ chơi golf regex của TessellatingHeckler.


1
Hey nhìn cạnh tranh nộp PowerShell!
Erik the Outgolfer

@EriktheOutgolfer Thao tác ngày là một trong những thế mạnh của PowerShell.
admBorkBork


@ Mr.Xcoder "tất cả những người đó" = 2. lol. Cảm ơn!
admBorkBork

Bạn có thể xóa ''định dạng ngày, cho -2. Nếu bạn muốn tuân theo cách tiếp cận của mình, với "chính tả là chính xác" thì bạn có thể thay thế 'th|rd|st|(\b.*)day|,'và nó giảm xuống 56 byte và xử lý các trường hợp tương tự. Mặc dù tôi nghĩ đó là sai bởi vì nếu bạn bỏ ngày, bạn không thể nhận Sunday, June8, 2015 | Invalidvụ án vì đó là thứ Hai. Nó sẽ báo lỗi, nhưng nó phân tích cú pháp là hợp lệ. Không chắc phán quyết về điều đó sẽ là gì, hoặc nếu người khác đang kiểm tra nó.
TessellatingHeckler

4

PHP, 73 164 + 1 byte

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

Chạy như ống với -nRhoặc thử trực tuyến .

Việc kiểm tra ngày thực sự tốn kém: Tôi phải tháo rời ngày trước khi sử dụng nội dung, sau đó thử và lỗi tên tháng.


Tôi nghĩ rằng bạn phải hỗ trợ tất cả các định dạng không chỉ một trong số họ?
Erik the Outgolfer

1
@EriktheOutgolfer nó làm. Nhưng không phải là các định dạng tiền thưởng.
Tít

@EriktheOutgolfer Điều này không xử lý tất cả các định dạng.
Ông Xcoder

1
Điều này không thành công cho ngày không hợp lệ. 30 February 2014trả lại 2014/03/02. Hoặc bằng cách lỗi hoặc trả về một giá trị falsey nhất quán, bạn chọn. (Tuy nhiên, họ sẽ tuân theo các định dạng mẫu ở trên)
Ông Xcoder

@ Mr.Xcoder Điều đó khá làm hỏng nó ...
Tít

3

Thư viện Python 3 + Parsedatetime, 152 139 155 153 byte

Đã lưu 13 byte nhờ Jonathan Allan

Đã thêm 16 byte để xử lý ngày có ngày dài không hợp lệ

Đã lưu 2 byte bằng cách xóa gán lambda

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

Hãy thử trực tuyến!

Không hỗ trợ ngày thưởng


Chào mừng đến với PPCG! Đẹp bài đầu tiên. Lưu 13 byte bằng cách sử dụng: giá trị trả về falsey của None; import ...as; & a lambdabằng cách tái sử dụng parsenhư h.
Jonathan Allan


1

Java (OpenJDK 8) , 190 + 26 = 216 byte

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

Hãy thử trực tuyến!

Lưu ý quan trọng: nó cũng ngắn hơn để xác nhận ngày trong tuần thay vì bỏ nó, để xác nhận được bao gồm!

Tôi đã không cố gắng SimpleDateFormatvượt quá các trường hợp rõ ràng mà tất cả các ngày được chấp nhận như ngày 30 tháng 2. Vì vậy, tôi đã phải bỏ nó và tôi đã sử dụng Java 8 DateTimeFormatter.

Giải trình

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

Định dạng này có nghĩa là:

  • ngày tùy chọn theo sau là dấu phẩy và dấu cách [EEEE, ](xảy ra trong Sunday, ...),
  • tiếp theo là ngày tùy chọn với không gian [d ],
  • theo sau là tháng đầy đủ chữ MMMMvà không gian,
  • tiếp theo là ngày tùy chọn với dấu phẩy và dấu cách [d, ],
  • tiếp theo là năm của thời đại uuuuđể cho trình phân tích cú pháp biết chúng ta đang ở thời đại Gregorian.

Mã số:

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

Tín dụng

  • 2 byte trong regex nhờ Neil.

1
Bạn có cần dấu ngoặc trong replaceAllmẫu không?
Neil

Hình như tôi không có. Cảm ơn, @Neil!
Olivier Grégoire

1

JavaScript (ES6), 124 122 byte

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>


Trả về 2015/06/07cho June 8, 2015(vấn đề UTC? Tôi đang ở UTC + 2) và falsecho một trong hai Sunday, June 8, 2015hoặc Monday, June 8, 2015.
Olivier Grégoire

1
@ OlivierGrégoire Cảm ơn bạn đã chỉ ra. Tôi chỉ thử các ngày ở Vương quốc Anh ngoài Giờ mùa hè nên họ đã sử dụng UTC và tôi không thử các ngày trong tuần kết thúc nday.
Neil
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.