영어 긴 날짜로 짧은 날짜


14

짧은 날짜 형식을 가능한 한 적은 바이트로 영어 긴 날짜로 변환하십시오.

입력

입력은 yyyy-mm-dd모든 값에 대해 선택 사항 인 0으로 채워진 형식의 문자열 형식 입니다. 이것이 구문 상으로는 정확하지만 반드시 유효한 날짜는 아니라고 가정 할 수 있습니다. 음수 값은 지원하지 않아도됩니다.

산출

날짜를 영어 긴 날짜 형식으로 변환해야합니다 (예 :) 14th February 2017. 여기에 제로 패딩은 허용되지 않습니다.

날짜가 유효하지 않은 경우 (예 :) 2011-02-29어떤 방식 으로든 인식해야합니다. 예외를 던질 수 있습니다.

더 많은 예는 아래에서 볼 수 있습니다.

테스트 사례

"1980-05-12" -> 12th May 1980
"2005-12-3"  -> 3rd December 2005
"150-4-21"   -> 21st April 150
"2011-2-29"  -> (error/invalid)
"1999-10-35" -> (error/invalid)

5
제로 패딩이 허용됩니까? 03rd대신 일명3rd
— Value Ink

@ValueInk 이전 주석을 읽으면 무시하십시오. 나는 그 질문을 오해했다. 출력에서 제로 패딩은 허용되지 않습니다.
— GarethPW

연도를 4 자 이상 (예 : 10987-01-01)으로 고려해야합니까?
— mdahmoune 2016 년

@mdahmoune 더 쉬운 방법이 아니라면 이것을 지원할 필요가 없습니다.
— GarethPW

무엇에 대해 2016-2-29?
— Olivier Grégoire

답변:


5

PostgreSQL, 61 자

prepare f(date)as select to_char($1,'fmDDth fmMonth fmYYYY');

준비된 명령문은 매개 변수로 입력을받습니다.

샘플 실행 :

Tuples only is on.
Output format is unaligned.
psql (9.6.3, server 9.4.8)
Type "help" for help.

psql=# prepare f(date)as select to_char($1,'fmDDth fmMonth fmYYYY');
PREPARE

psql=# execute f('1980-05-12');
12th May 1980

psql=# execute f('2005-12-3');
3rd December 2005

psql=# execute f('150-4-21');
21st April 150

psql=# execute f('2011-2-29');
ERROR:  date/time field value out of range: "2011-2-29"
LINE 1: execute f('2011-2-29');
                  ^
psql=# execute f('1999-10-35');
ERROR:  date/time field value out of range: "1999-10-35"
LINE 1: execute f('1999-10-35');
                  ^
HINT:  Perhaps you need a different "datestyle" setting.

MS-SQL이 "th"형식 스타일을 인식했으면 좋겠습니다.
— BradC

가장 적은 바이트로 작업을 올바르게 완료했다고 생각하면 솔루션이 승자라고 생각합니다!
— GarethPW

와. 감사. 완전히 예상치 못한 일입니다. 지금까지 전용 골프 언어가 없다는 것을 알지 못했습니다. 그러나 하루 만에 해결책을 받아들이는 것은 약간의 시간입니다.
— manatwork 2016 년

@manatwork 나는 그것이 조금 이른 지 궁금했다. 그러나 어쨌든 필요할 경우 변경할 수 있습니다.
— GarethPW 2016 년

7

Python 3.6, 137129 바이트

from datetime import*
def f(k):g=[*map(int,k.split('-'))];n=g[2];return f"{date(*g):%-d{'tsnrhtdd'[n%5*(n^15>4>n%10)::4]} %B %Y}"

온라인으로 사용해보십시오!


3
%-d의 패딩 없음 버전은 %d대신 문자열 형식으로 사용할 수 있습니다 {g[2]}. 또한, 12이되어야 12th하지, 12nd(10-19에서 숫자 9와 20 개 이상의 같은 규칙을 따르지 않는)
— 값 잉크

1
+1. 에 대해 알고하지 않았다 f문자열
— 펠리페 나르디 바티스타에게

@ValueInk 감사합니다! 또한 서수 문제를 해결했습니다
— Uriel

5

자바 스크립트 (ES6) 142 140 바이트

NaNth Invalid Date유효하지 않은 날짜를 출력 합니다.

서수 코드 는이 답변에서 수정되었습니다 .

d=>`${s=(D=new Date(d)).getDate()+''}${[,'st','nd','rd'][s.match`1?.$`]||'th'} `+D.toLocaleDateString('en-GB',{month:'long',year:'numeric'})


1
Chrome에서 2011 년 2 월 29 일에 "2011 년 3 월 1 일"을 제공합니다. 그것은 힘든 수정 일 수 있습니다.
— Rick Hitchcock

5

파이썬 3.6 , 154 바이트

from datetime import*
s=[*map(int,input().split('-'))]
b=s[2]
print(date(*s).strftime(f"%-d{'th'if(3<b<21)+(23<b<31)else('st','nd','rd')[b%10-1]} %B %Y"))

온라인으로 사용해보십시오! (입력 스트림을 설정 한 후 실행하십시오.)

아래의 의견 작성자의 좋은 제안 덕분에.


목록 comp 사이 int(x)와 공백을 제거하여 바이트를 저장할 수 있습니다 for.
— Christian Dean

@ChristianDean 감사합니다!
— Luke Sawczak 2016 년

(('st','nd','rd')[b%10-1]if b<4 or 20<b<24 else'th')-3 바이트에 대한 현재 조건 대신.
— Value Ink

@ValueInk 슬프게도, 31 번째를 생산할 것입니다. 내가 그것을 깰 생각하는 또 다른 방법은 0 <b % 10 <4 또는 10 <b <14가 아니라면 'th'였지만 바이트를 저장하지 않았습니다.
— Luke Sawczak

이 경우 남용 유형 강제. (3<b<21)+(23<b<31)-1 바이트 온라인으로 사용해보십시오!
— Value Ink

5

PHP, 87 바이트

<?=checkdate(($a=explode("-",$argn))[1],$a[2],$a[0])?date("jS F Y",strtotime($argn)):E;

파이프로 실행 -F하거나 온라인으로 테스트하십시오 . 항상 4 자리 연도를 인쇄합니다. > 9999 년 동안 실패합니다.

유효성 검사 없음, 35 바이트 :

<?=date("jS F Y",strtotime($argn));

5

배쉬 + 코어 유틸리티, 115 78

  • @manatwork 덕분에 2 바이트가 절약되었습니다.
d="date -d$1 +%-e"
t=`$d`
f=thstndrd
$d"${f:t/10-1?t%10<4?t%10*2:0:0:2} %B %Y"

온라인으로 사용해보십시오 .


1
배열 대신 문자열을 사용하면 약간 도움이 될 것 같습니다 f=thstndrd; $d"${f:t/10-1?t%10<4?t%10*2:0:0:2} %B %Y".
— manatwork

1
BTW, 개정 1 은 Bash 팁에 영감을주었습니다 . ;)
— manatwork

@manatwork yes-그 재미-나는 그것을 시도하는 것을 고려했지만 그것이 도움이 될 것이라고 생각하지 않았습니다. 너지 주셔서 감사합니다.
— 디지털 외상

4

C #, 147143 바이트

s=>{var t=System.DateTime.Parse(s);int d=t.Day,o=d%10;return d+((d/10)%10==1?"th":o==1?"st":o==2?"nd":o==3?"rd":"th")+t.ToString(" MMMM yyy");}

@The_Lone_Devil 덕분에 4 바이트를 절약했습니다.


4 바이트 절약 t.Day을 d위해 초 를 대체 할 수 없습니까?
— The_Lone_Devil 12

@The_Lone_Devil 물론 감사합니다. 어떻게 그리웠는지 모르겠습니다.
— TheLethalCoder

4

mIRC 버전 7.49 (197 바이트)

//tokenize 45 2-2-2 | say $iif($3 isnum 1- $iif($2 = 2,$iif(4 // $1 && 25 \\ $1||16//$1,29,28),$iif($or($2,6) isin 615,30,31))&&$2 isnum1-12&&1//$1,$asctime($ctime($+($1,-,$2,-,$3)date), doo mmmm yyyy))

3

루비 , 104 (103) 102 + 8 = 112 111 110 바이트

용도 -rdate -p프로그램 플래그를 합니다.

manatwork에서 -1 바이트

sub(/.*-(\d*)/){Date.parse($&).strftime"%-d#{d=eval$1;(d<4||d>20)&&"..stndrd"[d%10*2,2]||:th} %B %-Y"}

온라인으로 사용해보십시오!


삼항 연산자를 사용하지 않은 이유가 누락 되었습니까? d<4||d>20?"..stndrd"[d%10*2,2]:"th"
— manatwork 2016 년

@manatwork 같은 숫자 가 범위를 벗어난 조회 문자열의 26인덱스 12..13에 액세스하려고 시도하여 를 반환합니다 nil. 따라서 삼항을 사용하면 d<4||d>20?"..stndrd"[d%10*2,2]||"th":"th"2 바이트 더 길어집니다.
— Value Ink

아, 알겠습니다 그런 다음 @ValueInk 트릭을 시원하게하십시오.
— manatwork 2016 년

거의 잊어 버렸습니다, 작은 변화 : "th"→ :th.
— manatwork 2016 년

2

C # (.NET 코어) , 167 (197) 바이트

s=>s.Equals(DateTime.MinValue)?"":s.Day+((s.Day%10==1&s.Day!=11)?"st":(s.Day%10==2&s.Day!=12)?"nd":(s.Day%10==3&s.Day!=13)?"rd":"th")+" "+s.ToString("MMMM")+" "+s.Year

온라인으로 사용해보십시오!

+30 바이트

using System;

DateTime.Parse()


!-1 바이트를 제거하기 위해 3 진 검사를 취소 할 수 있습니다 . 그리고 -3 바이트 &&를 &위해를 변경할 수 있습니다 . 당신이 사용하기 때문에 또한, s.Day7 번 그것을 위해 임시 값을 만들기 위해 몇 바이트를 저장합니다s=>{var t=s.Day;return s.Equals(DateTime.MinValue)?"":t+((t%10==1&t!=11)?"st":(t%10==2&t!=12)?"nd":(t%10==3&t!=13)?"rd":"th")+" "+s.ToString("MMMM")+" "+s.Year;}
— 케빈 Cruijssen

@KevinCruijssen 감사합니다!
— kakkarot

또한 객체 를 포함 using System;하거나 완전히 규정해야 DateTime합니다.
— TheLethalCoder

또한 DateTime.MinValue입니다 1-1-1당신이 그 수표를 필요가 있다고 생각하지 않도록. 또한 이전의 요점을 무의미하게 만듭니다.
— TheLethalCoder

1
DateTime메소드 외부 에서 입력을 가져와 메소드 외부에서 구문 분석 하는 것은 허용되지 않습니다. 메소드 내부의 모든 작업을 수행해야합니다. 또는 다른 방법으로 작업을 분리하십시오.
— TheLethalCoder

2

Excel, 212 바이트

=ABS(RIGHT(A1,2))&IF(ABS(ABS(RIGHT(A1,2))-12)<2,"th",SWITCH(RIGHT(A1,1),"1","st","2","nd","3","rd","th"))&TEXT(MID(A1,FIND("-",A1)+1,FIND("-",REPLACE(A1,1,FIND("-",A1),""))-1)*30," mmmm ")&LEFT(A1,FIND("-",A1)-1)

모든 앰퍼샌드에서 덩어리로 나누면 다음과 같은 조각이 나타납니다.

  • ABS()문자열의 마지막 두 문자에서 요일 번호를 가져옵니다. 하이픈이 포함될 수 있으므로 하이픈 ABS을 양수로 변환합니다.
  • IF((ABS-12)<2,"th",SWITCH())서수를 추가합니다. -1211, 12, 13는 일반 규칙을 따르지 않는 그들은 모두 얻을 수 있기 때문에 비트는 th대신 st, nd하고 rd. 이 문제가 해결되었습니다.
    • 참고 :이 SWITCH기능은 Excel 2016 이상에서만 사용할 수 있습니다. ( Source ) CHOOSE일치하지 않는 경우 값을 반환 할 수 있지만 CHOOSE숫자 입력이 필요하고 가능한 각 값에 해당하는 반환 값이 있어야하므로이 경우 보다 짧습니다 .
  • TEXT(MID()*30," mmmm ")월 이름을 추출합니다. MID()월 숫자를 문자열로 가져오고 30을 곱하면 숫자가 반환됩니다. Excel에서 날짜로 그 숫자를보고 (1900년 1월 30일, 1900년 2월 29일, 1900년 3월 30일 등) 및 TEXT()양쪽에 공간이 한 달에 이름과 형식을. 28과 29도 작동하지만 30은 "더욱 깔끔해 보인다".
  • LEFT() 연도 번호를 추출합니다.

이제 모든 경우에 테스트 사례가 Excel에서 실제 날짜로 처리 할 수있는 날짜 범위 (1900-01-01 ~ 9999-12-31)에 있으면 훨씬 쉬웠을 것입니다. 가장 큰 장점은 전체 날짜가 한 번에 형식화된다는 것입니다. 그 해결책은 133 바이트입니다 .

=TEXT(DATEVALUE(A1),"d""" & IF(ABS(ABS(RIGHT(A1,2))-12)<2,"th",SWITCH(RIGHT(A1,1),"1","st","2","nd","3","rd","th")) & """ mmmm yyyy")

다른 큰 장애물은 서수를 포함해야했습니다. 그것 없이는 해결책은 단지 34 바이트입니다 .

=TEXT(DATEVALUE(A1),"d mmmm yyyy")

1

스위프트 3 : 298 바이트

let d=DateFormatter()
d.dateFormat="yyyy-MM-dd"
if let m=d.date(from:"1999-10-3"){let n=NumberFormatter()
n.numberStyle = .ordinal
let s=n.string(from:NSNumber(value:Calendar.current.component(.day, from:m)))
d.dateFormat="MMMM YYY"
print("\(s!) \(d.string(from:m))")}else{print("(error/invalid)")}

온라인으로 사용해보십시오!


8
사이트에 오신 것을 환영합니다! 여기서 목표는 코드를 가능한 한 짧게 만드는 것입니다. 변수 이름이 길고 공백이 많음을 볼 수 있습니다. 짧게 제거하여 많은 바이트를 절약 할 수 있습니다. 또한 일반적으로 답변 맨 위에 머리글을 형식으로 포함 # Language, N bytes합니다. 당신도 하나를 추가 할 수 있다면 좋을 것입니다.
— TheLethalCoder 2016 년

1

T-SQL, 194 바이트

DECLARE @ DATE;SELECT @=PARSE('00'+i AS DATE)FROM t;PRINT DATENAME(d,@)+CASE WHEN DAY(@)IN(1,21,31)THEN'st'WHEN DAY(@)IN(2,22)THEN'nd'WHEN DAY(@)IN(3,23)THEN'rd'ELSE'th'END+FORMAT(@,' MMMM yyy')

입력 텍스트 열 경유 나는 기존의 테이블에 t , 우리의 IO의 기준에 따라 .

0001 년 1 월 1 일부터 9999 년 12 월 31 일까지의 날짜에 적용됩니다. 연도는 최소 3 자리 (150AD 예당)로 출력됩니다.

날짜가 잘못되면 다음과 같은 추악한 오류가 발생합니다.

Error converting string value 'foo' into data type date using culture ''.

기본 언어 / 문화 설정이 다르면이 동작이 변경 될 수 있습니다. 약간 더 우아한 오류 출력 (NULL)을 원하면로 변경 PARSE()하여 4 바이트를 추가하십시오 TRY_PARSE().

형식과 설명 :

DECLARE @ DATE;
SELECT @=PARSE('00'+i AS DATE)FROM t;
PRINT DATENAME(d,@) + 
    CASE WHEN DAY(@) IN (1,21,31) THEN 'st'
         WHEN DAY(@) IN (2,22)    THEN 'nd'
         WHEN DAY(@) IN (3,23)    THEN 'rd'
         ELSE 'th' END
    + FORMAT(@, ' MMMM yyy')

DATESQL 2008에서 도입 된 데이터 형식보다 훨씬 넓은 범위를 허용 DATETIME년 1 월 1 일 0001 년 12 월까지 9999.

매우 이른 날짜는 미국 지역 설정 ( "01-02-03"이 "Jan 2 2003"이 됨)으로 잘못 구문 분석 될 수 있으므로 몇 개의 0을 추가하여 첫 번째 값이 연도임을 알 수 있습니다.

그 후, CASE서수에 접미사를 추가하는 것은 지저분한 말입니다 . 귀찮게도 SQL FORMAT명령은 자동으로 수행 할 수있는 방법이 없습니다.


1

q / kdb + 210 바이트, 비경쟁

해결책:

f:{a:"I"$"-"vs x;if[(12<a 1)|31<d:a 2;:0];" "sv(raze($)d,$[d in 1 21 31;`st;d in 2 22;`nd;d in 3 23;`rd;`th];$:[``January`February`March`April`May`June`July`August`September`October`November`December]a 1;($)a 0)};

예 :

q)f "2017-08-03"
"3rd August 2017"
q)f "1980-05-12"
"12th May 1980"
q)f "2005-12-3"
"3rd December 2005"
q)f "150-4-21" 
"21st April 150"
q)f "2011-2-29"       / yes it's wrong :(
"29th February 2011"
q)f "1999-10-35"
0

설명:

날짜 형식이 없기 때문에 끔찍한 도전이므로 서 픽스를 생성 할뿐만 아니라 처음부터 몇 달 (95 바이트)을 만들어야합니다.

Ungolfed 솔루션은 다음과 같습니다. 기본적으로 입력 문자열을 분할 한 다음 접미사를 추가하고 월을 전환 한 후 다시 연결하십시오.

f:{
   // split input on "-", cast to integers, save as variable a
   a:"I"$ "-" vs x;
   // if a[1] (month) > 12 or a[2] (day) > 31 return 0; note: save day in variable d for later
   if[(12<a 1) | 31<d:a 2;
     :0];
   // joins the list on " " (like " ".join(...) in python)
   " " sv (
           // the day with suffix
           raze string d,$[d in 1 21 31;`st;d in 2 22;`nd;d in 3 23;`rd;`th];
           // index into a of months, start with 0 as null, to mimic 1-indexing
           string[``January`February`March`April`May`June`July`August`September`October`November`December]a 1;
           // the year cast back to a string (removes any leading zeroes)
           string a 0)
  };

노트:

q의 날짜는 ~ 1709로 돌아가서 날짜를 확인하는 사소한 방법이 없으므로 경쟁이 아닌 항목입니다 ... 내가 할 수있는 최선의 일은 하루가> 31 또는 월인지 확인하는 것입니다. > 12이고 0을 반환합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.