Résolution du litige concernant le format de date

17

L'ordre de formatage des dates est l'un des problèmes les plus complexes et les plus conflictuels auxquels le monde est confronté aujourd'hui. Certains d'entre nous soutiennent avec véhémence que le mois / jour / année est approprié, étant donné que c'est ainsi que nous disons les dates à haute voix. D'autres proclament haut et fort que le jour / mois / année est le meilleur, car il place les termes dans l'ordre croissant de la durée qu'ils représentent.

Trop c'est trop. Les ordinateurs peuvent résoudre ce différend simplement et équitablement. Votre code, une fonction ou un programme complet, prendra une chaîne de date délimitée par des barres obliques, par exemple 12/1/2015. Notez que c'est le format exact, sans zéros de tête et avec une année à quatre chiffres à la fin.

  • Si c'est vraiment mois / jour / année, par exemple 10/31/1998, la sortie d' une représentation textuelle de cette date dans ce format exact, avec le nom complet du mois, le jour et l' année:October 31, 1998
  • Si c'est vraiment jour / mois / année, par exemple 25/12/1989, sortie le même type de représentation du texte: December 25, 1989.
  • S'il est ambigu, que ce soit Mois / Jour / Année ou Jour / Mois / Année, affichez une date qui résout l'ambiguïté en combinant les deux dates possibles comme suit:
    1. Créer un nouveau nom de mois en prenant la première moitié du nom du précédent mois et ajouter la deuxième moitié du plus tard mois. Pendant des mois avec une longueur impaire, la première moitié reçoit la lettre supplémentaire. Pour être explicite, la première moitié des mois sont Janu, Febr, Mar, Apr, Ma, Ju, Ju, Aug, Septe, Octo, Noveet Deceet les deuxièmes moitiés sont donc ary, uary, ch, il, y, ne, ly, ust, mber, ber, mberet mber.
    2. Calculez la journée en faisant la moyenne des deux jours possibles, en prenant la parole lorsque la moyenne n'est pas un entier.
    3. Sortez la représentation textuelle de cette date, par exemple pour la 10/8/2011sortie Augber 9, 2011.

Si la date d'entrée ne peut pas être Mois / Jour / Année ou Jour / Mois / Année (par exemple 13/13/2013ou même 2/30/2002), tout comportement est acceptable. Ce code golf, le code le plus court gagne!

Cas de test:

10/31/1998 donne October 31, 1998

25/12/1989 donne December 25, 1989

10/8/2011 donne Augber 9, 2011

8/5/1957 donne Maust 6, 1957

9/12/2012 (curieusement) donne September 10, 2012

1/1/2000 donne January 1, 2000

Luc
la source
20
Pour ce que ça vaut, beaucoup de ceux qui plaident pour le jour-mois-année disent également les dates dans cet ordre. (Bien sûr, les vrais programmeurs plaident pour l'année-mois-jour).
Peter Taylor
Juste pour être sûr: without leading zeroes and with a four-digit year at the endimpliqueyear >= 1000
edc65
C'est correct.
Luke
1
+ ∞ pour le 10 septembre 2012
ev3commander

Réponses:

1

Pyth - 156 octets

Code vraiment mauvais, et devra utiliser des chaînes compressées, mais c'est quelque chose.

Kc"January February March April May June July August September October November December"dJhM.g>k12=GsMcz\/?<eJ32++@KthJdtP`,eJeGss[@VCcL2KStMPGdPt`,s.OPGeG

Suite de tests .

Maltysen
la source
3

Mathematica 341 304 298 288 293 octets

Cela utilise une fonction pure ou anonyme, c'est-à-dire une fonction sans son propre nom.

DateStringrenvoie un message d'erreur si la date est ambiguë. Checkattrape l'ambiguïté et envoie la date incriminée à DateList, ce qui la transforme en liste de 3 entiers (qu'elle croit être {year, month, day}). Les entiers du mois et du jour sont triés par taille et utilisés pour déterminer le mois et le jour conformément aux instructions de l'OP.

Quiet fait taire l'erreur d'impression.

t=StringSplit;v=ToString;x=t[#,"-"]&/@t["Janu-ary Febr-uary Mar-ch Apr-il Ma-y Ju-ne Ju-ly Aug-ust Septe-mber Octo-ber Nove-mber Dece-mber"];
Quiet@Check[#~DateString~{"MonthName"," ","DayShort",", ","Year"},
{m,n,o}=DateList@#;{p,q}=Sort@d[[2;;3]];x[[p,1]]<>x[[q,2]]<>" "<>v@Floor@Mean@{n,o}<>", "<>v@d[[1]]]&

t=StringSplit;v=ToString;x=t[#,"-"]&/@t["Janu-ary Febr-uary Mar-ch Apr-il Ma-y Ju-ne Ju-ly Aug-ust Septe-mber Octo-ber Nove-mber Dece-mber"];
Quiet@Check[#~DateString~{"MonthName"," ","DayShort",", ","Year"},
{m,n,o}=DateList@#;{p,q}=Sort@d[[2;;3]];x[[p,1]]<>x[[q,2]]<>" "<>v@Floor@Mean@{n,o}<>", "<>v@d[[1]]]& /@ 
{"10/31/1998","25/12/1989", "10/8/2011", "8/5/1957", "9/12/2012", "1/1/2012"}

{"31 octobre 1998", "25 décembre 1989", "9 août 2011", "6 août 1957", "10 septembre 2012", "1er janvier 2012"}

DavidC
la source
Personnellement, je serais ravi de vous voir supprimer ce 0, mais je laisserai tomber les votes comme ils le peuvent.
Luke
Il renvoie désormais "1er janvier 2012" comme demandé.
DavidC
3

Javascript (ES6), 311 295 282 274 246 238 octets

a=>(a=a.split`/`,b=c=>e(c).length+1>>1,d=' ',e=f=>new Date(99,a[+f]-1).toLocaleString('en',{month:'long'}),g=+a[0],h=+a[1],i=g>h,j=g>12,k=h>12,(j&&!k?e(1)+d+g:k&&!j?e(0)+d+h:e(i).slice(0,b(i))+e(1-i).slice(b(1-i))+d+((g+h)>>1))+', '+a[2])

Edit: Utilise toLocaleStringpour générer des noms de mois. Modifiez les paramètres régionaux pour obtenir des résultats en utilisant les noms de mois dans différents paramètres régionaux!

Edit 2: Génère maintenant deux noms de mois au lieu des 12!

Non golfé:

func = inp => (
    inp = inp.split `/`,
    get = arg => months(arg).length + 1 >> 1,
    space = ' ',
    months = key => new Date(99, inp[+key] - 1).toLocaleString('en', { month: 'long' }),
    tmp1 = +inp[0],
    tmp2 = +inp[1],
    first = tmp1 > tmp2,
    t1greater = tmp1 > 12,
    t2greater = tmp2 > 12,
    (t1greater && !t2greater ?
        months(1) + space + tmp1
    :
        t2greater && !t1greater ?
            months(0) + space + tmp2
        :
            months(first).slice(0, get(first)) + months(1 - first).slice(get(1 - first)) + space + ((tmp1 + tmp2) >> 1)
    )
    + ', ' + inp[2]
)

Exemple:

console.log(
    func('10/31/1998') + '\n' +
    func('25/12/1989') + '\n' +
    func('10/8/2011') + '\n' +
    func('8/5/1957') + '\n' +
    func('9/12/2012') + '\n' +
    func('1/1/2000')
);

Merci à:
@ user81655 , 274 => 246 octets
@ edc65 , 246 => 238 octets

usandfriends
la source
1
Je n'ai pas l' air très bien , mais voici quelques améliorations que vous pourriez faire: le changement Math.ceil(e[c].length/2)à (r=e[c].length/2)+r%1, Array(2).fill().map((_,f)=>...)à f=>...et tout e[n]à e(n), i=+(g>h)à i=g>het e[i]à e[+i], supprimer les crochets inutiles dans le dernier opérateur ternaire, aussi newDatedevrait être new Date.
user81655
1
Évitez d' Math.ceilutiliserb=c=>e(c).length+1>>1
edc65
2

JavaScript ES6, 204

x=>(s=x=>x.split`/`,[a,b,y]=s(x).sort((a,b)=>a-b),(c=b)>12?c=a:b=a- -b>>1,s('/Janu/Febr/Mar/Apr/Ma/Ju/Ju/Aug/Septe/Octo/Nove/Dece')[a]+s('/ary/uary/ch/il/y/ne/ly/ust/mber/ber/mber/mber')[c]+` ${b}, `+y)

Extrait de test:

F=x=>(
  s=x=>x.split`/`,
  [a,b,y]=s(x).sort((a,b)=>a-b),
  (c=b)>12?c=a:b=a- -b>>1,
  s('/Janu/Febr/Mar/Apr/Ma/Ju/Ju/Aug/Septe/Octo/Nove/Dece')[a]
  +s('/ary/uary/ch/il/y/ne/ly/ust/mber/ber/mber/mber')[c]+` ${b}, `+y
)

console.log=x=>O.innerHTML+=x+'\n'

;['10/31/1998','25/12/1989','10/8/2011','8/5/1957','9/12/2012','1/1/2000']
.forEach(x=>console.log(x+' -> '+F(x)))
<pre id=O></pre>

edc65
la source
2

Python 3 (290 octets)

Similaire à la réponse d'Ashwin Gupta, mais en profitant du module de calendrier de Python pour éviter d'écrire tous les noms de mois.

import calendar as C
M,I,P,S,L,A=C.month_name,int,print," ",len,", "
def d(i):
 w=i.split("/")
 f,s,y=I(w[0]),I(w[1]),w[2]
 if(f>12):P(M[s]+S+w[0]+A+y)
 elif(s>12):P(M[f]+S+w[1]+A+y)
 else:l,h=min(f,s),max(f,s);P(M[l][:I(L(M[l])/2+.5)]+M[h][I(L(M[h])/2+.5):]+S+str(I((f+s)/2))+A+y)

Python 2 devrait couper quelques octets avec une division entière et perdre les parenthèses pour print.

Jack Brounstein
la source
1

Python, 558 554 octets

Un exemple vraiment, vraiment, vraiment horriblement golfé de comment faire cela en python. Désolé, je suis super mauvais dans ce truc de golf D:. Cela fonctionne cependant. Je suis sûr qu'il existe de nombreuses façons de simplifier cela, alors faites-le moi savoir dans les commentaires. Golfé:

import math
def d(i):
 l=["","January","February","March","April","May","June","July","August","September","October","November","December"]
 w=i.split('/')
 f=int(w[0])
 s=int(w[1])
 S=" "
 y=w[2]
 if(f>12):
  e=int(w[1])
  print(l[e]+S+w[0]+", "+y)
  elif(f<=12 and s>12):
   e=int(w[0])
   print(l[e]+S+w[0]+", "+y)
   else:
    if(f<s):
     o=l[f]
     t=l[s]
    else:
     o=l[s]
     t=l[f]
    o=o[0:int(math.ceil(len(o)/2))]
    t=t[int(math.ceil(len(t)/2)):len(t)]
    print(o+t+S +  str(math.floor((f + s)/2)) + ", " + y)

Non golfé

import math
def d(i):
    l = ["", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
    w = i.split('/')
    f = int(w[0])
    s = int(w[1])
    y = w[2]
    if(f > 12):
        e = int(w[1])
        print(l[e] + " " + w[0] + ", " + y)

    elif(f <= 12 and s > 12):
         e = int(w[0])
         print(l[e] + " " + w[0] + ", " + y)
    else:
         if(f < s):
            o=l[f]
            t=l[s]
         else:
            o=l[s]
            t=l[f]
         o = o[0:int(math.ceil(len(o)/2))]
         t = t[int(math.ceil(len(t)/2)):len(t)]
         print(o+t+" " +  str(math.floor((f + s)/2)) + ", " + y)

Capture d'écran: entrez la description de l'image ici

Ashwin Gupta
la source
mettre S=" "en haut, puis remplacer chaque instance de " "par S- qui enlèvera quelques octets
cat
il y a quelques espaces inutiles après les affectations ( e= int[..., o = o...). en outre, il peut s'avérer hasardeux de définir des appels souvent utilisés, comme des intvariables majuscules à une seule lettre
cat
1
Voici 447 octets:from math import* I=int S=" " C="," L=len P=print def d(i): l=["","January","February","March","April","May","June","July","August","September","October","November","December"];w=i.split('/');f=I(w[0]);s=I(w[1]);y=w[2] if f>12:e=I(w[1]);P(l[e]+S+w[0]+C+S+y) elif f<13and s>12:e=I(w[0]);P(l[e]+S+w[0]+C+S+y) else: if f<s:o=l[f];t=l[s] else:o=l[s];t=l[f];o=o[0:I(ceil(L(o)/2))];t=t[I(ceil(L(t)/2)):L(t)] P(o+t+S+str(floor((f+s)/2))+C+S+y)
cat
1
@sysreq ok mon esprit est officiellement soufflé. Je ne savais pas que vous pouviez stocker des fonctions dans une variable. Je vous remercie. Je vais le modifier. De plus, pourriez-vous me rendre service et essayer d'exécuter mon code (un golfé) et voir si cela fonctionne comme il se doit, car Luke semble obtenir des résultats différents de moi, donc je veux juste voir.
Ashwin Gupta
1
@sysreq ouais idk. Pourquoi c'est différent pour lui. Quoi qu'il en soit, merci encore pour les conseils, cela aide vraiment non seulement pour le golf, mais en général, car je suis encore nouveau sur Python. De plus, je viens de réaliser que je peux supprimer mes affectations initiales d'o et t et économiser 4 octets en plaçant l'élément de tableau directement dans mon séparateur. Je ferai tous ces changements cet après-midi. Grâce à vous, le nouveau nombre d'octets sera nettement inférieur!
Ashwin Gupta
0

PHP, 301 294 octets

function r($t){$e='return date("F",mktime(0,0,0,$o));';list($a,$b,$c)=explode('/',$t);$o=min($a,$b);$m=eval($e);$o=max($a,$b);$n=eval($e);echo(($a|$b)<13)?substr($m,0,ceil(strlen($m)/2)).substr($n,ceil(strlen($n)/2))." ".floor(($a+$b)/2).", $c":date("F j, Y",strtotime(($a>12)?"$b/$a/$c":$t));}

Je pensais pouvoir concurrencer la réponse Javascript. Tant pis.

Je pense que je pourrais le rendre plus petit et je n'aime pas le code que j'ai utilisé pour les dates ambiguës. Je pense qu'il y a une meilleure façon de le faire.

Non golfé:

function r($t){
    // Eval'd code to reduce char count
    $e='return date("F",mktime(0,0,0,$o));';

    // Split the date
    list($a,$b,$c)=explode('/',$t);

    // Get the earliest month
    $o=min($a,$b);
    $m=eval($e);

    // Get the latest month
    $o=max($a,$b);
    $n=eval($e);

    // If ambiguous
    if ($a<13 && $b<13) {
        print substr($m,0,ceil(strlen($m)/2)).substr($n,ceil(strlen($n)/2))." ".floor(($a+$b)/2).", $c";
    }
    else {
        print date("F j, Y",strtotime(($a>12)?"$b/$a/$c":$t));
    }
}
Kodos Johnson
la source