COBOL Y2K redux
R, 126 bytes
function(x,a=x%/%100^(2:0)%%100,d=as.Date)'if'(a[2]<13,d(paste(19e6+x),'%Y%m%d'),d(a[3]+100*((a[2]-13)+87*a[1]),'2000-01-01'))
Try it online!
- -5 bytes thanks to @Giuseppe suggestion to take a numeric input instead of string
T-SQL, 99 98 bytes
SELECT CONVERT(DATE,IIF(ISDATE(i)=1,'19'+i,
DATEADD(d,8700*LEFT(i,2)+RIGHT(i,4)-935,'1999')))FROM t
Line break is for readability only. Thank goodness for implicit casting.
Input is via a pre-existing table t with CHAR
column i, per our IO rules.
Goes through the following steps:
- Initial check is via the SQL function
ISDATE()
. (The behavior of this function changes based on language settings, it works as expected on myenglish-us
server). Note this this is just a check for validity, if we tried to parse it directly, it would map250101
as 2025-01-01, not 1925-01-01. - If the string parses correctly as a date, tack
19
on the front (rather than change the server-level year cutoff setting). Final date conversion will come at the end. - If the string does not parse as a date, convert it to a number instead. The shortest math I could find was
8700*PP + QQRR - 1300
, which avoids the (very long) SQLSUBSTRING()
function. This math checks out for the provided samples, I'm pretty sure it is right. - Use
DATEADD
to add that many days to2000-01-01
, which can be shorted to2000
. - Take that final result (either a string from step 2, or a DATETIME from step 4), and
CONVERT()
it to a pureDATE
.
I thought at one point that I found a problematic date: 000229
. This is the only date which parses differently for 19xx vs 20xx (since 2000 was a leap year, but 1900 was not, due to weird leap-year exceptions). Because of that, though, 000229
isn't even a valid input (since, as mentioned, 1900 was not a leap year), so doesn't have to be accounted for.
JavaScript (SpiderMonkey), 103 bytes
s=>new Date(...([a,b,c]=s.match(/../g),b>12?[2e3,0,(b-13+a*87)*100-~c]:[a,b-1,c])).toJSON().split`T`[0]
Try it online!
.toJSON
will failed on a UTC+X timezone. This code works, but longer (+11bytes):
s=>Intl.DateTimeFormat`ii`.format(new Date(...([a,b,c]=s.match(/../g),b>12?[2e3,0,(b-13+a*87)*100-~c]:[a,b-1,c])))