Dans les années 1990, les ingénieurs informatiques COBOL ont travaillé un moyen d'étendre les champs de date à six chiffres en les convertissant YYYDDD
où YYY
est le year - 1900
et DDD
est le jour de l'année [001 to 366]
. Ce schéma pourrait prolonger la date maximum à 2899-12-31
.
En 2898, les ingénieurs ont commencé à paniquer parce que leurs bases de code vieilles de 900 ans allaient échouer. À partir de l'année 2898, ils utilisaient simplement leur machine à voyager le temps pour envoyer un codinateur isolé à l'année 1998 avec cet algorithme et la tâche de le mettre en œuvre aussi largement que possible:
Utilisez un schéma
PPQQRR
où01 ≤ QQ ≤ 12
il s'agit d'uneYYMMDD
date standard dans les années 1900, mais siQQ > 12
elle représente les jours suivants2000-01-01
en base 100 pourPP
et laRR
base 87 pourQQ - 13
.
Ce système s'étend bien au-delà de l'année 2899 et est également rétrocompatible avec les dates standard. Aucune modification des archives existantes n'est donc nécessaire.
Quelques exemples:
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
Votre défi consiste à écrire un programme ou une fonction pour accepter les entrées PPQQRR
et sorties en tant que date ISO YYYY-MM-DD
. La méthode de saisie peut être un paramètre, une console ou une ligne de commande, le plus simple.
Pour votre amusement, voici une solution non compétitive dans 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
cela ne fonctionne pas pendant des années>=2000
, c'est tout l'intérêt de la débâcle de l'an 2000.yyyy-mm-dd
format doit être au format ISO .001300
.Réponses:
T-SQL,
9998 octetsLe saut de ligne est pour la lisibilité seulement. Dieu merci pour le casting implicite.
La saisie s'effectue via une table préexistante t avec la
CHAR
colonne i , conformément à nos règles IO .Passe par les étapes suivantes:
ISDATE()
. (Le comportement de cette fonction change en fonction des paramètres de langue, il fonctionne comme prévu sur monenglish-us
serveur). Notez que ceci n’est qu’une vérification de validité. Si nous essayions de l’analyser directement, la carte correspondrait250101
au 2025-01-01 et non au 1925-01-01.19
de bord (plutôt que de modifier le paramètre de limite d'année au niveau du serveur). La date de conversion finale viendra à la fin.8700*PP + QQRR - 1300
qui évite la fonction (très longue) SQLSUBSTRING()
. Ce calcul vérifie les échantillons fournis, je suis presque sûr que c'est correct.DATEADD
pour ajouter ce nombre de jours à2000-01-01
, ce qui peut être raccourci à2000
.CONVERT()
vous obtenez un résultat purDATE
.Je pensais à un moment donné que j'ai trouvé une date problématique:
000229
. C’est la seule date qui analyse différemment pour 19xx par rapport à 20xx (puisque 2000 était une année bissextile, mais 1900 ne l’était pas, en raison d’ étranges exceptions pour les années bissextiles ). À cause de cela, cependant,000229
n’est même pas une entrée valide (puisque, comme mentionné, 1900 n’était pas une année bissextile), elle n’a donc pas à être prise en compte.la source
ISDATE
qu'il ne retourne pas de booléen, ou que des entiers ne peuvent pas être convertis implicitement en booléens,IIF
sinon vous pourriez économiser deux octets.LEFT()
etRIGHT()
function sur des entiers avant de les multiplier, cela aurait vraiment gâché le nombre d'octets-1300,'2000'
par-935,'1999'
.R , 126 octets
Essayez-le en ligne!
la source
000101
ou681231
)JavaScript (SpiderMonkey) , 103 octets
Essayez-le en ligne!
.toJSON
échouera sur un fuseau horaire UTC + X. Ce code fonctionne, mais plus longtemps (+11 octets):la source
.toJSON()
.Python 2 , 159 octets
Essayez-le en ligne!
la source
... and ... or ...
au lieu de... if ... else ...
.ABAP,
173171 octetsSauvegardé 2 octets en optimisant davantage la sortie
Selon la légende, un client SAP du début du 21ème siècle a déclaré:
Il avait raison. Aujourd'hui, en 2980, il n'y a plus de C ++, plus de COBOL. Après la guerre, tout le monde devait réécrire son code dans SAP ABAP. Pour offrir une compatibilité ascendante aux restes des programmes COBOL du 2800, nos scientifiques l'ont reconstruit en tant que sous-programme dans ABAP.
Il peut être appelé par un programme comme celui-ci:
Explication de mon code:
Le type Date de ABAP a la propriété impaire à mettre en forme en tant que JJMMAAAA si vous utilisez
WRITE
- cela peut dépendre des paramètres régionaux même si le format interne est AAAAMMJJ. Mais lorsque nous utilisons un sélecteur de sous-chaîne commed(4)
celui-ci, il sélectionne les 4 premiers caractères du format interne , nous donnant donc YYYY.Mise à jour : le format de sortie dans l'explication est maintenant obsolète, je l'ai optimisé de 2 octets dans la version avec golf:
la source
MUMPS
et nous survivrons à tout!Kotlin , 222 octets
Les champs du calendrier codés en dur nomment les constantes pour économiser 49 octets.
Essayez-le en ligne!
la source