web-dev-qa-db-fra.com

Min/Max Date/DateHeure dans JodaTime

Y at-il un moyen dans JodaTime de construire une Date/DateHeure qui sera toujours plus petite/plus grande que toute autre Date/DateHeure? Quelque chose dans le sens de 

DateTime bigBang = DateTime.xxx();
DateTime endOfUniverse = DateTime.yyy();

Contrainte: je ne souhaite pas utiliser les bibliothèques de date Java standard.

14
Ueli Hofstetter

Java.time

Le projet Joda-Time est maintenant en mode maintenance. L'équipe conseille la migration vers les classes Java.time.

Pour min/max en Java.time, voir ma réponse sur une question similaire.

Joda-Time

Joda-Time enregistre le temps sous la forme d'un nombre de millisecondes depuis l'époque du premier moment de 1970 en UTC . Ce nombre est conservé en utilisant un entier 64 bitslong. Donc, techniquement, les maximum et minimum sont les limites +/- d'une long.

… new DateTime( Long.MIN_VALUE )
… new DateTime( Long.MAX_VALUE )

Joda-Time n'a pas de telles valeurs minimum/maximum disponibles sous forme de constantes. En revanche, notez que le successeur de Joda-Time, Java.time intégré à Java 8 et versions ultérieures, offre effectivement les constantes LocalDateTime.MIN et LocalDateTime.MAX .

En passant, l’équipe de Joda-Time a conseillé de migrer vers Java.time. Une grande partie de la fonctionnalité Java.time est rétroportée vers Java 6 et 7 dans le ThreeTen-Backport , puis adaptée à Android dans ThreeTen-ABP .

Trop grand, trop petit

Méfiez-vous de ces extrêmes. Leur utilisation n'est pas pratique. Diverses bibliothèques, applications, bases de données et autres puits/sources de valeurs date-heure peuvent avoir des limites très différentes, certaines beaucoup plus grandes mais généralement beaucoup plus petites.

Par exemple, de nombreux systèmes utilisent l'ancienne tradition d'UNIX et POSIX du temps de suivi sous la forme d'un nombre entier 32 bits de secondes entières depuis le 1970-01-01T00: 00: 00Z. La limite naturelle de +/- deux milliards de secondes entraîne le risque imminent problème de l'an 2038

Une autre limite est la taille d'affichage physique des champs sur les formulaires et les rapports qui n'attendent que quatre chiffres dans un numéro d'année.

Workaround

Vous pouvez définir votre propre min/max. 

Vous voudrez peut-être des valeurs extrêmes telles que les années 0000 et 9999. Joda-Time prend en charge les années ultérieures à 9 999, mais je conserverais 4 chiffres pour correspondre aux formats couramment utilisés pour l'affichage à l'écran et dans les rapports. Visuellement, les quatre neuf se démarquent comme une date factice.

Ou vous pouvez souhaiter une valeur minimale attendue adaptée à votre logique métier. Si vous créez un nouveau système de facturation, sachez que l'année doit toujours être cette année ou plus tard.

Je suggère de définir des constantes sur une classe d'assistance. Quelque chose comme ça:

package com.example;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;

public class JodaTimeHelper {

    static final public DateTime START_OF_TIME = new DateTime( 0000, 1, 1, 0, 0, 0, DateTimeZone.UTC );
    static final public DateTime END_OF_TIME = new DateTime( 9999, 1, 1, 0, 0, 0, DateTimeZone.UTC );

    static final public DateTime MINIMUM_INVOICE_DATETIME = new DateTime( 2015, 1, 1, 0, 0, 0, DateTimeZone.UTC );

}

Voici la syntaxe pour appeler ces constantes.

System.out.println( "START_OF_TIME: " + JodaTimeHelper.START_OF_TIME );
System.out.println( "END_OF_TIME: " + JodaTimeHelper.END_OF_TIME );
System.out.println( "MINIMUM_INVOICE_DATETIME: " + JodaTimeHelper. MINIMUM_INVOICE_DATETIME );

Quand couru.

START_OF_TIME: 0000-01-01T00:00:00.000Z
END_OF_TIME: 9999-01-01T00:00:00.000Z
MINIMUM_INVOICE_DATETIME: 2015-01-01T00:00:00.000Z
12
Basil Bourque

Lorsque toutes les dates sont dans le même fuseau horaire, vous pouvez créer un objet DateTime avec des champs affectés à une valeur minimale ou maximale.
Cependant, lors de l'utilisation de ce constructeur

DateTime(int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minuteOfHour, int secondOfMinute)

avec Years.MAX_VALUE.getYears() j'ai ci-dessous exception:

 enter image description here

Donc, en utilisant le nombre maximum d'années d'exception, j'ai proposé le dateTime de fin d'univers suivant:

DateTime dtMax = new DateTime(292278993, 12, 31, 23, 59, 59);
System.out.println(dtMax);
// prints 292278993-12-31T23:59:59

Voir documentation pour plus de détails.
On peut également lire une discussion intéressante ici .

2
MaxZoom

Après avoir lu de nombreuses tangentes à ce sujet, j'ai finalement décidé de trouver un cas minimal qui fonctionne à la fois pour le minimum et le maximum pour le fuseau horaire UTC. Et il s'avère que tenter d'utiliser les MIN_VALUE et MAX_VALUE de Long m'envoie dans les traces des lapins.

Donc, étant donné l'extrait de code suivant:

new DateTime(milliseconds, DateTimeZone.UTC)

voici les valeurs minimum/maximum qui fonctionnent pour milliseconds (testé en Java 1.7):

UTC_DATE_TIME_MIN_VALUE_IN_MILLIS = 9223372017129599999L
UTC_DATE_TIME_MAX_VALUE_IN_MILLIS = -9223372017043200000L

Ces deux valeurs se trouvent à environ 20 milliards de dollars de Long.MIN_VALUE et Long.MAX_Value.

0
chaotic3quilibrium