Quel est le meilleur moyen d’analyser une date au format MM / JJ / AA et de l’ajuster au siècle en cours / précédent?

StackOverflow https://stackoverflow.com/questions/251535

  •  05-07-2019
  •  | 
  •  

Question

Un de nos clients souhaite pouvoir entrer une date avec seulement 2 chiffres pour la composante de l'année. La date sera dans le passé, nous voulons donc que cela fonctionne pour le siècle précédent si l'année à 2 chiffres est postérieure à l'année en cours, mais fonctionne pour le siècle en cours si l'année à 2 chiffres est égale ou inférieure à l'année en cours.

à compter d'aujourd'hui 30/10/2008

01/01/01 = 01/01/2001

01/01/09 = 01/01/1909

C’est une exigence étrange et j’ai résolu le problème. Je n’aime pas ma solution. C'est comme s'il y avait un meilleur moyen de le faire.

Merci pour l'aide.

public static String stupidDate(String dateString)
{
    String twoDigitYear = StringUtils.right(dateString, 2);
    String newDate = StringUtils.left(dateString, dateString.length() - 2);
    int year = NumberUtils.toInt(twoDigitYear);
    Calendar c = GregorianCalendar.getInstance();
    int centuryInt = c.get(Calendar.YEAR) - year;
    newDate = newDate + StringUtils.left(Integer.toString(centuryInt), 2) + twoDigitYear;
    return newDate;
}
Était-ce utile?

La solution

Script Groovy (assez facile à intégrer en Java) illustrant le propos de @bobince à propos de SimpleDateFormat.

import java.text.SimpleDateFormat

SimpleDateFormat sdf = new SimpleDateFormat('MM/dd/yy')
SimpleDateFormat fmt = new SimpleDateFormat('yyyy-MM-dd')

Calendar cal = Calendar.getInstance()
cal.add(Calendar.YEAR, -100)
sdf.set2DigitYearStart(cal.getTime())

dates = ['01/01/01', '10/30/08','01/01/09']
dates.each {String d ->
  println fmt.format(sdf.parse(d))
}

Rendements

2001-01-01
2008-10-30
1909-01-01

Autres conseils

SimpleDateFormat effectue déjà une analyse d’année sur deux chiffres, à l’aide de la & deux lettres & # 8216; yy & # 8217; format. (Cela autorisera toujours quatre chiffres, évidemment.)

Par défaut, il utilise maintenant-80 et maintenant + 20, ce n'est donc pas exactement la même règle que vous proposez, mais elle est raisonnable et normalisée (du moins dans le monde Java), et peut être remplacée à l'aide de set2DigitYearStart () si tu veux.

DateFormat informat= new SimpleDateFormat("MM/dd/yy");
DateFormat outformat= new SimpleDateFormat("MM/dd/yyyy");
return outformat.format(informat.parse(dateString));

À plus long terme, essayez de migrer vers le format de date ISO8601 (aaaa-MM-jj), car le format MM / jj / aa est approximativement le format de date le plus défavorable et ne peut que provoquer des problèmes.

Que diriez-vous de cela:

public static String anEasierStupidDateWithNoStringParsing(String dateString) {
    DateFormat df = new SimpleDateFormat("MM/dd/yyyy");

    //handling ParseExceptions is an exercise left to the reader!
    Date date = df.parse(dateString);
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);

    Calendar now = Calendar.getInstance();
    if (cal.after(now)) {
        cal.add(Calendar.YEAR, -100);
    }

    return cal;
}

En d'autres termes, laissez SimpleDateFormat analyser la chaîne et ajustez simplement l'année au siècle précédent si SimpleDateFormat ( qui a ses propres règles d'interprétation des chaînes d'année ) renvoie une date postérieure à la date actuelle.

Cela garantirait que toutes les dates renvoyées sont passées. Cependant, il ne tient pas compte des dates susceptibles d'être analysées avant avant ce siècle dernier - par exemple, avec le format MM / jj / aaaa , une chaîne de date comme "01/11/12" analyse jusqu'au 11 janvier, 12 h.

Si Joda Time est une option:

String inputDate = "01/01/08";
// assuming U.S. style date, since it's not clear from your original question
DateTimeFormatter parser = DateTimeFormat.forPattern("MM/dd/yy");
DateTime dateTime = parser.parseDateTime(inputDate);
// if after current time
if (dateTime.isAfter(new DateTime())) {
    dateTime = dateTime.minus(Years.ONE);
}

return dateTime.toString("MM/dd/yyyy");

Je sais que Joda Time ne fait pas partie de Java SE et, comme je l'ai dit dans un autre fil, je ne tolère généralement pas l'utilisation d'une bibliothèque tierce lorsqu'il existe une bibliothèque Java qui fait la même chose. Cependant, la personne qui développe Joda Time dirige également JSR310, l’API Date et heure qui entrera dans Java 7. Jose Time sera donc dans les prochaines versions de Java.

Date deliverDate = new SimpleDateFormat("MM/dd/yy").parse(deliverDateString);
String dateString2 = new SimpleDateFormat("yyyy-MM-dd").format(deliverDate);

Travailler pour moi.

Année pivot dans Joda-Time

L'excellente bibliothèque Joda-Time 2.5 comprend cette fonctionnalité. Pas besoin d'écrire du code vous-même. Appelez simplement avecPivotYear () sur un DateTimeFormatter . Voir ce document lié pour des exemples d'utilisation.

Le meilleur moyen consiste à utiliser l'API Joda Time pour les dates et les heures en Java.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top