En la década de 1990, los ingenieros informáticos de COBOL descubrieron una forma de ampliar los campos de fecha de seis dígitos al convertirlos a YYYDDD
dónde YYY
es year - 1900
y DDD
es el día del año [001 to 366]
. Este esquema podría extender la fecha máxima a 2899-12-31
.
En el año 2898, los ingenieros comenzaron a entrar en pánico porque sus bases de código de 900 años iban a fallar. Siendo del año 2898, simplemente usaron su máquina del tiempo para enviar un Codeinator solitario al año 1998 con este algoritmo y la tarea de implementarlo lo más ampliamente posible:
Utilice un esquema
PPQQRR
en el que si01 ≤ QQ ≤ 12
es unaYYMMDD
fecha estándar en el siglo XX, pero siQQ > 12
representa los días posteriores2000-01-01
en la base 100 paraPP
y laRR
base 87 paraQQ - 13
.
Este esquema se extiende mucho más allá del año 2899 y también es compatible con las fechas estándar, por lo que no se requieren modificaciones de los archivos existentes.
Algunos ejemplos:
PPQQRR YYYY-MM-DD
000101 1900-01-01 -- minimum conventional date suggested by J. Allen
010101 1901-01-01 -- edge case suggested by J. Allen
681231 1968-12-31 -- as above
991231 1999-12-31 -- maximum conventional date
001300 2000-01-01 -- zero days after 2000-01-01
008059 2018-07-04 -- current date
378118 2899-12-31 -- maximum date using YYYDDD scheme
999999 4381-12-23 -- maximum date using PPQQRR scheme
Su desafío es escribir un programa o función para aceptar la entrada PPQQRR
y la salida como una fecha ISO YYYY-MM-DD
. El método de entrada puede ser parámetro, consola o línea de comando, lo que sea más fácil.
Para su diversión, aquí hay una solución no competitiva en COBOL-85:
IDENTIFICATION DIVISION.
PROGRAM-ID. DATE-CONVERSION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 T PIC 9(8).
01 U PIC 9(8).
01 D VALUE '999999'.
05 P PIC 9(2).
05 Q PIC 9(2).
05 R PIC 9(2).
01 F.
05 Y PIC 9(4).
05 M PIC 9(2).
05 D PIC 9(2).
PROCEDURE DIVISION.
IF Q OF D > 12 THEN
MOVE FUNCTION INTEGER-OF-DATE(20000101) TO T
COMPUTE U = R OF D + 100 * ((Q OF D - 13) + 87 * P OF D) + T
MOVE FUNCTION DATE-OF-INTEGER(U) TO F
DISPLAY "Date: " Y OF F "-" M OF F "-" D OF F
ELSE
DISPLAY "Date: 19" P OF D "-" Q OF D "-" R OF D
END-IF.
STOP RUN.
yymmdd
no funciona durante años>=2000
, ese es el objetivo de la debacle de Y2K.yyyy-mm-dd
formato ISO .001300
.Respuestas:
T-SQL,
9998 bytesEl salto de línea es solo para legibilidad. Gracias a Dios por el casting implícito.
La entrada es a través de una tabla t preexistente con la
CHAR
columna i , según nuestras reglas de IO .Sigue los siguientes pasos:
ISDATE()
. (El comportamiento de esta función cambia según la configuración del idioma, funciona como se esperaba en mienglish-us
servidor). Tenga en cuenta que esto es solo una verificación de validez, si intentamos analizarlo directamente, se mapearía250101
asignaría como 2025-01-01, no como 1925-01-01.19
el frente (en lugar de cambiar la configuración de corte de año a nivel del servidor). La conversión de la fecha final llegará al final.8700*PP + QQRR - 1300
, lo que evita el SQL (muy largo)SUBSTRING()
función . Esta matemática verifica las muestras proporcionadas, estoy bastante seguro de que es correcto.DATEADD
para agregar tantos días a2000-01-01
, que se pueden acortar a2000
.CONVERT()
póngalo a un nivel puroDATE
.Pensé en un momento que me encontré con una fecha problemática:
000229
. Esta es la única fecha que se analiza de manera diferente para 19xx frente a 20xx (ya que 2000 fue un año bisiesto, pero 1900 no lo fue, debido a las extrañas excepciones del año bisiesto ). Sin embargo, debido a eso,000229
ni siquiera es una entrada válida (ya que, como se mencionó, 1900 no fue un año bisiesto), por lo que no tiene que tenerse en cuenta.fuente
ISDATE
que no devuelva un valor booleano, o que los enteros no se puedan convertir implícitamente a un valor booleano; de loIIF
contrario, podría guardar dos bytes.LEFT()
yRIGHT()
función tiene como resultado a enteros antes de multiplicar ellos, que realmente habría perdió mi cuenta de bytes-1300,'2000'
con-935,'1999'
.R , 126 bytes
Pruébalo en línea!
fuente
000101
o681231
)JavaScript (SpiderMonkey) , 103 bytes
Pruébalo en línea!
.toJSON
fallará en una zona horaria UTC + X. Este código funciona, pero más tiempo (+ 11bytes):fuente
.toJSON()
.Python 2, 159 bytes
Try it online!
fuente
... and ... or ...
instead of... if ... else ...
.ABAP,
173171 bytesSaved 2 bytes by further optimizing the output
According to the legends, an SAP customer in the early 21st century once said:
Él estaba en lo correcto. Hoy, en 2980, no hay más C ++, no más COBOL. Después de la guerra, todos tuvieron que reescribir su código en SAP ABAP. Para proporcionar compatibilidad con las sobras de los programas COBOL del 2800, nuestros científicos lo reconstruyeron como una subrutina en ABAP.
Puede ser llamado por un programa como este:
Explicación de mi código:
El tipo de fecha de ABAP tiene la propiedad impar para formatearse como DDMMYYYY cuando se usa
WRITE
, puede ser dependiente de la configuración regional, a pesar de que el formato interno sea AAAAMMDD. Pero cuando usamos un selector de subcadena comod(4)
si selecciona los primeros 4 caracteres del formato interno , por lo tanto, nos da AAAA.Actualización : el formato de salida en la explicación ahora está desactualizado, lo optimicé en 2 bytes en la versión de golf:
fuente
MUMPS
and we'll survive anything!Kotlin, 222 bytes
Hard coded Calendar field names constants to save 49 bytes.
Try it online!
fuente