0% ont trouvé ce document utile (0 vote)
4 vues61 pages

Utilisation Des Dates Java

Le document traite de la manipulation des dates en Java, en mettant l'accent sur les défis liés aux différents calendriers, fuseaux horaires et formats de date. Il présente les classes standards du JDK pour gérer les dates, notamment java.util.Date, java.util.Calendar et java.text.SimpleDateFormat, ainsi que des recommandations pour une utilisation efficace. Le texte souligne également l'importance d'utiliser des fabriques pour obtenir des dates lors des tests unitaires afin d'éviter des erreurs liées à la date système.

Transféré par

sbiaialiteacher
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats DOCX, PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
4 vues61 pages

Utilisation Des Dates Java

Le document traite de la manipulation des dates en Java, en mettant l'accent sur les défis liés aux différents calendriers, fuseaux horaires et formats de date. Il présente les classes standards du JDK pour gérer les dates, notamment java.util.Date, java.util.Calendar et java.text.SimpleDateFormat, ainsi que des recommandations pour une utilisation efficace. Le texte souligne également l'importance d'utiliser des fabriques pour obtenir des dates lors des tests unitaires afin d'éviter des erreurs liées à la date système.

Transféré par

sbiaialiteacher
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats DOCX, PDF, TXT ou lisez en ligne sur Scribd

97.

L'utilisation des dates

Niveau : Elémentaire

La manipulation des dates n'est pas toujours facile à mettre en oeuvre :

 il existe plusieurs calendriers dont le plus usité est le calendrier Grégorien qui débute à la
naissance de Jésus Christ.
 le calendrier Grégorien comporte de nombreuses imperfections : le nombre de jours d'un
mois varie selon le mois, le nombre de jours d'une année varie selon l'année (année
bissextile), ...
 le format textuel de restitution des dates diffère selon la Locale utilisée
 l'existence des fuseaux horaires qui donnent une date/heure différente d'un point dans le
temps selon la localisation géographique
 la possibilité de prendre en compte un décalage horaire lié à l'heure d'été et à l'heure
d'hiver
 ...

Pourtant le temps s'écoule de façon linéaire : c'est d'ailleurs de cette façon que les calculs de dates
sont réalisés avec Java, en utilisant une représentation de la date qui indique le nombre de
millisecondes écoulées depuis un point d'origine défini. Dans le cas de Java, ce point d'origine est le
1er janvier 1970. Ceci permet de définir un point dans le temps de façon unique.

L'utilisation de dates en Java est de surcroît plus compliquée à cause de l'API historique qui permet
leur gestion car elle n'est pas toujours intuitive.

Il est intéressant de découpler l'obtention de la date/heure système par exemple en utilisant une
fabrique. Cette fabrique renvoie la date/heure système en production mais elle est aussi capable de
renvoyer une date/heure déterminée.

Exemple :

view source

print?
[Link] aujourdhui = [Link]();

L'utilisation d'une telle fabrique peut être particulièrement utile lors de tests unitaires ou
d'intégration pour faciliter la vérification des résultats par rapport à un type de données dont la
valeur par définition évolue constamment.

Ceci évite entre autres d'avoir à modifier la date système sur la ou les machines sur lesquelles les
tests sont exécutés.

La bibliothèque jFin aussi propose des fonctionnalités relatives au traitement des dates
spécifiquement dédiées à la finance.

Ce chapitre contient plusieurs sections :


 Les classes standards du JDK pour manipuler des dates
 Des exemples de manipulations de dates
 La classe SimpleDateFormat
 Joda Time
 La classe FastDateFormat du projet Apache [Link]

97.1. Les classes standards du JDK pour


manipuler des dates
En Java 1.0, la classe [Link] était seule responsable de l'encapsulation et de la manipulation
d'une date.

A partir de Java 1.1, la responsabilité de la gestion et des traitements sur les dates sont réparties
sur plusieurs classes :

 [Link] : elle encapsule un point dans le temps


 [Link] et [Link] : elle permet la manipulation d'une date
 [Link] et [Link] : elle encapsule un fuseau horaire à partir
du méridien de Greenwich (GMT) et les informations relatives aux décalages concernant
l'heure d'été et l'heure d'hiver
 java. [Link], [Link] : elle permet de convertir une date en
chaîne de caractères et vice versa
 [Link] : elle permet de traduire les différents éléments d'une date
(jour, mois, ...)

Les classes permettant la mise en oeuvre des dates sont dans le package [Link] exceptées celles
relatives à leur conversion de et vers une chaîne de caractères qui sont dans le package [Link]

Le package [Link] contient aussi des classes relatives aux dates et à leur utilisation dans une
base de données :

 [Link] : hérite de [Link] et n'encapsule que la date sans la partie horaire


 [Link] : hérite de [Link] et n'encapsule que la partie horaire sans la partie
date
 [Link] : encapsule un point dans le temps avec une représentation particulière
pour une utilisation avec SQL

Les classes abstraites Calendar, TimeZone et DateFormat possèdent toutes une implémentation
concrète respectivement GregorianCalendar, SimpleTimeZone et SimpleDateFormat.

La conception des classes qui encapsulent et manipulent des dates ne facilitent pas leur mise en
oeuvre. C'est d'autant plus dommageable que l'utilisation de dates est courante notamment dans
les applications de gestion.

Par exemple, l'API propose au moins quatre manières pour obtenir un point dans le temps depuis le
1 janvier 1970 :

Exemple :

view source

print?
[Link]([Link]());
[Link](new [Link]().getTime());
[Link]([Link]().getTimelnMillis() );
[Link]([Link]().getTime().getTime ())
L'API de gestion des dates en Java est particulièrement propice à la confusion et à l'obtention
d'erreurs potentielles :

 nommage de certaines méthodes ([Link](), [Link](), ...)


 gestion des mois de 0 à 11 au lieu de 1 à 12

97.1.1. La classe [Link]


Cette classe encapsule, sous la forme d'une variable de type long, un point dans le temps qui est
représenté par le nombre de millisecondes écoulées entre le 1 janvier 1970 à minuit heure GMT et
l'instant concerné.

Depuis la version 1.1, toutes les méthodes permettant de manipuler la date sont deprecated.

Par défaut, cette classe encapsule le point courant dans le temps obtenu en utilisant la méthode
[Link]() ce qui rend sa précision dépendante du système d'exploitation.

97.1.2. La classe [Link]


La classe Calendar encapsule un point dans le temps (une Date sous la forme d'une variable de
type long) et permet une représentation et une manipulation dans un calendrier et un fuseau
horaire.

La classe Calendar n'est pas stateless puisqu'elle encapsule un point dans le temps : il est donc
nécessaire d'initialiser ce point avant de pouvoir utiliser l'instance de Calendar.

Une nouvelle instance de la classe est toujours initialisée avec le point dans le temps courant. Pour
encapsuler un autre point, il faut obligatoirement après l'instanciation utiliser une des méthodes de
la classe pour modifier le point encapsulé.

Pour accéder aux différentes propriétés de la date encapsulée dans l'instance de Calendar, il
n'existe pas un getter pour chaque propriété mais une seule méthode get() qui attend en
paramètre le nom de la propriété souhaitée et qui retourne toujours une valeur de type int.

La classe Calendar définit des constantes de type int pour le nom de ces propriétés.

La classe Calendar définit aussi plusieurs constantes qui contiennent les valeurs possibles pour
certaines propriétés. Leur utilisation est fortement recommandée car certaines valeurs sont parfois
surprenantes notamment celles qui encapsulent un mois. La valeur d'un mois varie de 0 à 11
correspondants aux constantes [Link] à [Link]. Calendar définit aussi la
constante UNDECIMBER qui représente le treizième mois de l'année requis par certains calendriers.

Attention : toutes ces constantes sont définies pêle-mêle dans la classe et ne sont donc pas
groupées par une convention de nommage dans une interface dédiée par rôle. Elles sont toutes de
types int, ce qui peut permettre d'utiliser n'importe quelle constante à la place d'une autre.

Exemple :

view source

print?
[Link] calendar = [Link]();
[Link] ( [Link]( [Link] )==[Link] ) {
3. [Link]("la date courante est en janvier"); }

La classe Calendar propose trois façons de manipuler la date qu'elle encapsule en agissant sur les
éléments qui la compose :

 set() : permet de modifier un élément de la date


 add() : permet de modifier un élément de la date en tenant compte des impacts sur les
autres éléments qui composent la date
 roll() : identique à la méthode add() mais sans affecter les autres éléments de la date

La date encapsulée dans Calendar peut être manipulée de deux façons :

 directement par un calcul sur le nombre de millisecondes écoulées depuis le 1er janvier
1970
 en agissant sur les éléments qui composent la date en utilisant les méthodes dédiées

97.1.3. La classe [Link]


La classe [Link] est la seule implémentation concrète de la classe Calendar
fournie en standard. Cette implémentation correspond au calendrier Grégorien.

La méthode isLeapYear() permet de savoir si l'année encapsulée par la classe est bissextile.

97.1.4. Les classes [Link] et


[Link]
La classe abstraite TimeZone et sa sous-classe SimpleTimeZone encapsulent un fuseau horaire.

Une instance de type TimeZone est utilisée par la classe Calendar pour déterminer la date
correspondant au point dans le temps qu'elle encapsule. Un même point dans le temps correspond
à des dates/heures différentes pour deux fuseaux horaires différents.

Un fuseau horaire correspond à un certain décalage vis à vis du méridien de référence, le méridien
de Greenwich. Le fuseau horaire correspondant à ce méridien est désigné par GMT.

Ce décalage peut en plus être affecté par un second décalage induit par les heures d'été et d'hiver
(daylight savings time (DST)) si ceux-ci sont mis en place dans le fuseau horaire.

La classe TimeZone encapsule un nom long et un nom court qui permet d'identifier le fuseau
horaire qu'elle encapsule.

La méthode String[] getAvailableIDs() permet d'obtenir les noms des TimeZones définis en
standard : par exemple avec Java 6, il y a 597 TimeZones fournis.

La classe est une fabrique qui permet d'obtenir une instance de TimeZone à partir de son
identifiant en utilisant la méthode getTimeZone() ou celle correspondant à la Locale courante en
utilisant la méthode getDefault().

97.1.5. La classe [Link]


La clase abstraite DateFormat propose les fonctionnalités de base pour interpréter et formater une
date sous la forme d'une chaîne de caractères.

Ce formatage doit traduire certains éléments notamment le jour et le mois de la date selon la
Locale. De nombreux formats de dates sont aussi utilisés généralement dépendant eux aussi de la
Locale.

Quatre styles de formats sont définis par défaut : SHORT, MEDIUM, LONG, et FULL. Avec une Locale
et un style, la classe DateFormat peut fournir un formatage standard de la date.

La classe DateFormat propose plusieurs méthodes statiques getXXXlnstance() qui sont des
fabriques qui renvoient des instances de type DateFormat.

La méthode format() permet de formater une date en chaîne de caractères.

La méthode parse() permet d'extraire une date à partir de sa représentation sous la forme d'une
chaîne de caractères.

La Locale et le style de la classe DateFormat ne peuvent pas être modifiés après la création de son
instance.

97.1.6. La classe [Link]


La classe SimpleDateFormat permet de formater et d'analyser une date en tenant compte d'une
Locale. Elle hérite de la classe abstraite DateFormat.

Pour réaliser ces traitements, cette classe utilise un modèle (pattern) sous la forme d'une chaîne de
caractères.

La classe DataFormat propose plusieurs méthodes pour obtenir le modèle par défaut de la Locale
courante :

 getTimeInstance(style)
 getDateInstance(style)
 getDateTimeInstance(styleDate, styleHeure)

Ces méthodes utilisent la Locale par défaut mais chacune de ces méthodes possède une surcharge
qui permet de préciser une Locale.

Pour chacune de ces méthodes, quatre styles sont utilisables : SHORT, MEDIUM, LONG et FULL. Ils
permettent de désigner la richesse des informations contenues dans le modèle pour la date et/ou
l'heure.

Exemple :

view source

print?
[Link] [Link];
02.
[Link] [Link];
[Link] [Link];
[Link] [Link];
06.
[Link] class TestFormaterDate2 {
08.
09. /**
10. * @param args
11. */
12. public static void main(String[] args) {
13. Date aujourdhui = new Date();
14.
15. DateFormat shortDateFormat = [Link](
16. [Link],
17. [Link]);
18.
19. DateFormat shortDateFormatEN = [Link](
20. [Link],
21. [Link], new Locale("EN","en"));
22.
23. DateFormat mediumDateFormat = [Link](
24. [Link],
25. [Link]);
26.
27. DateFormat mediumDateFormatEN = [Link](
28. [Link],
29. [Link], new Locale("EN","en"));
30.
31. DateFormat longDateFormat = [Link](
32. [Link],
33. [Link]);
34.
35. DateFormat longDateFormatEN = [Link](
36. [Link],
37. [Link], new Locale("EN","en"));
38.
39. DateFormat fullDateFormat = [Link](
40. [Link],
41. [Link]);
42.
43. DateFormat fullDateFormatEN = [Link](
44. [Link],
45. [Link], new Locale("EN","en"));
46.
47. [Link]([Link](aujourdhui));
48. [Link]([Link](aujourdhui));
49. [Link]([Link](aujourdhui));
50. [Link]([Link](aujourdhui));
51. [Link]("");
52. [Link]([Link](aujourdhui));
53. [Link]([Link](aujourdhui));
54. [Link]([Link](aujourdhui));
55. [Link]([Link](aujourdhui));
56. }
57.
58.}
Résultat :

view source

print?
01.27/06/06 21:36
02.27 juin 2006 21:36:30
03.27 juin 2006 21:36:30 CEST
[Link] 27 juin 2006 21 h 36 CEST
05.
06.6/27/06 9:36 PM
[Link] 27, 2006 9:36:30 PM
[Link] 27, 2006 9:36:30 PM CEST
[Link], June 27, 2006 9:36:30 PM CEST

Il est aussi possible de définir son propre format en utilisant les éléments du tableau ci-dessous.
Chaque lettre du tableau est interprétée de façon particulière. Pour utiliser les caractères sans
qu'ils soient interprétés dans le modèle il faut les encadrer par de simples quotes. Pour utiliser une
quote il faut en mettre deux consécutives dans le modèle.

Lettr
Description Exemple
e

AD (Anno Domini), BC (Before


G Era
Christ)

y Année 06 ; 2006

M Mois dans l'année Septembre; Sept.; 07

w Semaine dans l'année 34

W Semaine dans le mois 2

D Jour dans l'année 192

d jour dans le mois 23

F Jour de la semaine dans le mois 17

E Jour de la semaine Mercredi; Mer.

Marqueur AM/PM (Ante/Post


a PM, AM
Meridiem)

H Heure (0-23) 23

k Heure (1-24) 24

K Heure en AM/PM (0-11) 6

h Heure en AM/PM (1-12) 7

m Minutes 59

s Secondes 59

S Millisecondes 12564

CEST; Heure d'été d'Europe


z Zone horaire générale
centrale

Z Zone horaire (RFC 822) +0200


Ces caractères peuvent être répétés pour préciser le format à utiliser :

 Pour les caractères de type Text : moins de 4 caractères consécutifs représentent la version
abrégée sinon c'est la version longue qui est utilisée.
 Pour les caractères de type Number : c'est le nombre de répétitions qui désigne le nombre
de chiffres utilisés, complété si nécessaire par des 0 à gauche.
 Pour les caractères de type Year : 2 caractères précisent que l'année est codée sur deux
caractères.
 Pour les caractères de type Month : 3 caractères ou plus représentent la forme littérale
sinon c'est la forme numérique du mois.

Exemple :

view source

print?
[Link] [Link];
02.
[Link] [Link];
[Link] [Link];
[Link] [Link];
06.
[Link] class TestFormaterDate {
08.
09. public static void main(String[] args) {
10. SimpleDateFormat formater = null;
11.
12. Date aujourdhui = new Date();
13.
14. formater = new SimpleDateFormat("dd-MM-yy");
15. [Link]([Link](aujourdhui));
16.
17. formater = new SimpleDateFormat("ddMMyy");
18. [Link]([Link](aujourdhui));
19.
20. formater = new SimpleDateFormat("yyMMdd");
21. [Link]([Link](aujourdhui));
22.
23. formater = new SimpleDateFormat("h:mm a");
24. [Link]([Link](aujourdhui));
25.
26. formater = new SimpleDateFormat("K:mm a, z");
27. [Link]([Link](aujourdhui));
28.
29. formater = new SimpleDateFormat("hh:mm a, zzzz");
30. [Link]([Link](aujourdhui));
31.
32. formater = new SimpleDateFormat("EEEE, d MMM yyyy");
33. [Link]([Link](aujourdhui));
34.
35. formater = new SimpleDateFormat("'le' dd/MM/yyyy 'à' hh:mm:ss");
36. [Link]([Link](aujourdhui));
37.
38. formater = new SimpleDateFormat("'le' dd MMMM yyyy 'à' hh:mm:ss");
39. [Link]([Link](aujourdhui));
40.
41. formater = new SimpleDateFormat("dd MMMMM yyyy GGG, hh:mm aaa");
42. [Link]([Link](aujourdhui));
43.
44. formater = new SimpleDateFormat("yyyyMMddHHmmss");
45. [Link]([Link](aujourdhui));
46.
47. }
48.
49.}

Résultat :

view source

print?
01.27-06-06
02.270606
03.060627
04.9:37 PM
05.9:37 PM, CEST
06.09:37 PM, Heure d'été d'Europe centrale
[Link], 27 juin 2006
[Link] 27/06/2006 à 09:37:10
[Link] 27 juin 2006 à 09:37:10
10.27 juin 2006 ap. J.-C., 09:37 PM
11.20060627213710

Il existe plusieurs constructeurs de la classe SimpleDateFormat :

Constructeur Rôle

Constructeur par défaut utilisant le modèle par défaut et les


SimpleDateFormat()
symboles de formatage de dates de la Locale par défaut

Constructeur utilisant le modèle fourni et les symboles de


SimpleDateFormat(String)
formatage de dates de la Locale par défaut

SimpleDateFormat(String, Constructeur utilisant le modèle et les symboles de formatage


DateFormatSymbols) de dates fournis

Constructeur utilisant le modèle fourni et les symboles de


SimpleDateFormat(String, Locale)
formatage de dates de la Locale fournie

La classe DateFormatSymbols encapsule les différents éléments textuels qui peuvent entrer dans la
composition d'une date pour une Locale donnée (les jours, les libellés courts des mois, les libellés
des mois, ...).

Exemple :

view source
print?
[Link] [Link];
02.
[Link] [Link];
[Link] [Link];
05.
[Link] class TestFormaterDate3 {
07.
08. public static void main(String[] args) {
09. DateFormatSymbols dfsFR = new DateFormatSymbols([Link]);
10. DateFormatSymbols dfsEN = new DateFormatSymbols([Link]);
11.
12. String[] joursSemaineFR = [Link]();
13. String[] joursSemaineEN = [Link]();
14.
15. StringBuffer texteFR = new StringBuffer("Jours FR ");
16. StringBuffer texteEN = new StringBuffer("Jours EN ");
17.
18. for (int i = 1; i < [Link]; i++) {
19. [Link](" : ");
20. [Link](joursSemaineFR[i]);
21. [Link](" : ");
22. [Link](joursSemaineEN[i]);
23. }
24. [Link](texteFR);
25. [Link](texteEN);
26.
27. texteFR = new StringBuffer("Mois courts FR ");
28. texteEN = new StringBuffer("Mois courts EN ");
29. String[] moisCourtsFR = [Link]();
30. String[] moisCourtsEN = [Link]();
31.
32. for (int i = 0; i < [Link] - 1; i++) {
33. [Link](" : ");
34. [Link](moisCourtsFR[i]);
35. [Link](" : ");
36. [Link](moisCourtsEN[i]);
37. }
38.
39. [Link](texteFR);
40. [Link](texteEN);
41.
42. texteFR = new StringBuffer("Mois FR ");
43. texteEN = new StringBuffer("Mois EN ");
44. String[] moisFR = [Link]();
45. String[] moisEN = [Link]();
46.
47. for (int i = 0; i < [Link] - 1; i++) {
48. [Link](" : ");
49. [Link](moisFR[i]);
50. [Link](" : ");
51. [Link](moisEN[i]);
52. }
53.
54. [Link](texteFR);
55. [Link](texteEN);
56.
57. }
58.
59.}

Résultat :

view source

print?
[Link] FR : dimanche : lundi : mardi : mercredi : jeudi : vendredi :
samedi
[Link] EN : Sunday : Monday : Tuesday : Wednesday : Thursday : Friday :
Saturday
[Link] courts FR : janv. : févr. : mars : avr. : mai : juin : juil. :
août : sept. : oct.
04. : nov. : déc.
[Link] courts EN : Jan : Feb : Mar : Apr : May : Jun : Jul : Aug : Sep :
Oct : Nov : Dec
[Link] FR : janvier : février : mars : avril : mai : juin : juillet :
août : septembre :
[Link] : novembre : décembre
[Link] EN : January : February : March : April : May : June : July :
August : September :
09. October : November : December

Il est possible de définir son propre objet DateFormatSymbols pour personnaliser les éléments
textuels nécessaires au traitement des dates. La classe DateFormatSymbols propose à cet effet des
setters sur chacun des éléments.

Exemple :

view source

print?
[Link] [Link];
02.
[Link] [Link];
[Link] [Link];
[Link] [Link];
06.
[Link] class TestFormaterDate4 {
08.
09. public static void main(String[] args) {
10. Date aujourdhui = new Date();
11. DateFormatSymbols monDFS = new DateFormatSymbols();
12. String[] joursCourts = new String[] {
13. "",
14. "Di",
15. "Lu",
16. "Ma",
17. "Me",
18. "Je",
19. "Ve",
20. "Sa" };
21. [Link](joursCourts);
22. SimpleDateFormat dateFormat = new SimpleDateFormat(
23. "EEE dd MMM yyyy HH:mm:ss",
24. monDFS);
25. [Link]([Link](aujourdhui));
26. }
27.
28.}

Résultat :

view source

print?
[Link] 27 juin 2006 21:38:22

Attention : il faut consulter la documentation de l'API pour connaître précisément le contenu et


l'ordre des éléments fournis sous la forme de tableaux aux setters de la classe. Dans l'exemple, ci-
dessus, les jours de la semaine commencent par dimanche.

La méthode applyPattern() permet de modifier le modèle d'un objet SimpleDateFormat.

La classe SimpleDataFormat permet également d'analyser une date sous la forme d'une chaîne de
caractères pour la transformer en objet de type Date en utilisant un modèle. Cette opération est
réalisée grâce à la méthode parse(). Si elle échoue, elle lève une exception de type ParseException.

Exemple :

view source

print?
[Link] [Link];
02.
[Link] [Link];
[Link] [Link];
[Link] [Link];
06.
[Link] class TestParserDate {
08.
09. public static void main(String[] args) {
10. Date date = null;
11. SimpleDateFormat simpleDateFormat = new
SimpleDateFormat("dd/MM/yyyy");
12.
13. String date1 = "22/06/2006";
14. String date2 = "22062006";
15.
16. try {
17. date = [Link](date1);
18. [Link](date);
19. date = [Link](date2);
20. [Link](date);
21. } catch (ParseException e) {
22. [Link]();
23. }
24. }
25.}

Résultat :

view source

print?
[Link] Jun 22 00:00:00 CEST 2006
[Link]: Unparseable date: "22062006"
3. at [Link](Unknown Source)
4. at [Link]([Link])

97.1.7. Les classes [Link], [Link],


[Link]
Ces trois classes héritent de la classe [Link] pour encapsuler des données correspondant
aux types DATE, TIME et TIMESTAMP de la norme SQL 92.

La classe [Link] n'encapsule que la partie date en ignorant la partie horaire du point dans le
temps qu'elle encapsule.

La classe [Link], elle, n'encapsule que la partie horaire en ignorant la partie date du point
dans le temps qu'elle encapsule.

La classe [Link] encapsule un point dans le temps en millisecondes et des


informations permettant d'avoir le point dans le temps avec une précision en nanosecondes.

Ces trois méthodes redéfinissent la méthode toString() pour permettre une représentation
respectant le standard SQL 92.

Exemple :

view source

print?
[Link] [Link] dateSQL = new [Link](new Date().getTime()) ;
[Link](dateSQL);

Remarque : ces trois classes ne permettent pas de prendre en compte un TimeZone explicite
puisque généralement c'est celui de la base de données qui est toujours utilisé par défaut.

97.2. Des exemples de manipulations de dates


Cette section présente des portions de code pour répondre à des besoins courants de
manipulations de dates.

Formater une date

Exemple :

view source

print?
[Link] static final SimpleDateFormat dateFormat =
02. new SimpleDateFormat("dd/MM/yyyy");
[Link] static final SimpleDateFormat dateHeureFormat =
04. new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
05.
[Link] static String formatterDate(Date date) {
07. return [Link](date);
08.}
[Link] static String formatterDateHeure(Date date) {
10. return [Link](date);
11.}

Extraire une date d'une chaîne de caractères

Exemple :

view source

print?
[Link] df = new SimpleDateFormat("dd-MM-yyyy");
[Link] date=null;
[Link]
4.{
5. date= [Link]("25-12-2010");
6.} catch (ParseException e){
7. [Link]();
8.}

Ajouter/retrancher des jours à une date :


Exemple :

view source

print?
[Link] static Date ajouterJour(Date date, int nbJour) {
2. Calendar cal = [Link]();
3. [Link]([Link]();
4. [Link]([Link], nbJour);
5. return [Link]();
6.}

ou

Exemple :

view source

print?
[Link] static Date ajouterJour(Date date, int nbJour) {
2. Calendar cal = [Link]();
3. [Link]([Link]();
4. [Link](Calendar.DAY_OF_MONTH, nbJour);
5. return [Link]();
6.}

Pour retrancher des jours, il faut fournir un paramètre négatif au nombre de jours.

Ajouter/retrancher des mois à une date

Exemple :

view source

print?
[Link] static Date ajouterMois(Date date, int nbMois) {
2. Calendar cal = [Link]();
3. [Link]([Link]();
4. [Link]([Link], nbMois);
5. return [Link]();
6.}

Pour retrancher des mois, il faut fournir un paramètre négatif au nombre de mois.

Ajouter/retrancher des années à une date

Exemple :
view source

print?
[Link] static Date ajouterAnnee(Date date, int nbAnnee) {
2. Calendar cal = [Link]();
3. [Link]([Link]());
4. [Link]([Link], nbAnnee);
5. return [Link]();
6.}

Pour retrancher des années, il faut fournir un paramètre négatif au nombre d'années.

Ajouter/retrancher des heures à une date

Exemple :

view source

print?
[Link] static Date ajouterHeure(Date date, int nbHeure) {
2. Calendar cal = [Link]();
3. [Link]([Link]());
4. [Link]([Link], nbHeure);
5. return [Link]();
6.}

Pour retrancher des heures, il faut fournir un paramètre négatif au nombre d'heures.

Ajouter/retrancher des minutes à une date

Exemple :

view source

print?
[Link] static Date ajouterMinute(Date date, int nbMinute) {
2. Calendar cal = [Link]();
3. [Link]([Link]());
4. [Link]([Link], nbMinute);
5. return [Link]();
6.}

Pour retrancher des minutes, il faut fournir un paramètre négatif au nombre de minutes.

Ajouter/retrancher des secondes à une date

Exemple :
view source

print?
[Link] static Date ajouterSeconde(Date date, int nbSeconde) {
2. Calendar cal = [Link]();
3. [Link]([Link]());
4. [Link]([Link], nbSeconde);
5. return [Link]();
6.}

Pour retrancher des secondes, il faut fournir un paramètre négatif au nombre de secondes.

97.3. La classe SimpleDateFormat


La classe SimpleDateFormat permet de formater une date pour lui donner une représentation
textuelle dans un format donné ou de parser une chaîne de caractères pour extraire une date dans
un format donné.

97.3.1. L'utilisation de la classe SimpleDateFormat


Le constructeur de la classe SimpleDateFormat attend en paramètre une chaîne de caractères qui
précise le format à utiliser durant les traitements de formatage et de parsing.

La méthode format() permet de formater la date fournie en paramètre.

Exemple :

view source

print?
[Link] simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy");
[Link] dateStr = [Link](new Date());
[Link](dateStr);

Le format comporte de nombreuses options et peut même contenir du texte brut qui doit être
échappé avec des quotes simples.

Par défaut, la classe SimpleDateFormat travail avec la Locale courante. Il est possible de préciser
une autre Locale en tant que paramètre du constructeur.

Exemple :

view source

print?
[Link] simpleDateFormat = new SimpleDateFormat("dd MMMM yyyy
zzzz G", [Link]);
[Link] dateStr = [Link](new Date());
[Link](dateStr);

La méthode parse() permet de déterminer une date extraite d'une chaîne de caractères en utilisant
un format donné.

Exemple :

view source

print?
[Link] simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy");
[Link] date = [Link]("25/12/2010");
[Link](date);

Par défaut, SimpleDateFormat travail avec la Locale par défaut qui contient le fuseau horaire (time
zone)

Si la chaîne de caractères ne contient pas explicitement le fuseau horaire, il peut être nécessaire de
le préciser en utilisant la méthode setTimeZone();

Exemple :

view source

print?
[Link] simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy");
[Link]([Link]("PST"));
[Link] date = [Link]("25/12/2010");
[Link](date);

Il est possible de préciser le siècle si la date à parser ne contient que deux chiffres : par exemple
"01/01/02" peut correspondre à une date de l'année 1902 ou 2002. La méthode
set2DigitYearStart() permet de préciser la date de début de la plage de 100 ans dans laquelle
l'année sera traitée. Par défaut, cette plage de 100 ans correspond à la date du jour - 80 ans
jusqu'à la date du jour + 20 ans.

Exemple :

view source

print?
[Link] simpleDateFormat =
[Link] SimpleDateFormat("dd MMMM yy", [Link]);
[Link] date = [Link]("25-12-02");
[Link](date);
[Link] debut20emeSiecle = new GregorianCalendar(1901,1,1).getTime();
[Link].set2DigitYearStart(debut20emeSiecle);
[Link] = [Link]("25-12-02");
[Link](date);

Par défaut, le parsing de la date est très permissif : le format de la date n'a pas à respecter
strictement le format fourni à SimpleDateFormat. Dans ce cas, SimpleDateFormat va tenter
d'extraire une date qui potentiellement ne correspond pas du tout sans générer d'erreur.

Exemple :

view source

print?
[Link] simpleDateFormat =
[Link] SimpleDateFormat("dd-MM-yyyy", [Link]);
[Link] date = [Link]("31-04-10");
[Link](date);

Dans l'exemple ci-dessus, le mois d'avril ne possède que 30 jours. La classe SimpleDateFormat en
déduit que l'on veut le jour suivant le 30 avril soit le 1er mai. Ce comportement est rarement celui
souhaité.

Pour demander un respect strict du format, il faut passer la valeur false à la méthode setLenient().
Si le format de la date à traiter ne correspond pas, une exception est levée.

Exemple :

view source

print?
[Link] simpleDateFormat =
[Link] SimpleDateFormat("dd-MM-yyyy", [Link]);
[Link](false);
[Link] date = [Link]("31-04-10");
[Link](date);

La classe SimpleDateFormat n'est pas thread-safe car elle maintient son état, entre autre, avec
deux objets de type Calendar et NumberFormat. Si deux threads utilisent la même instance pour
manipuler deux dates en même temps, le résultat des traitements est aléatoire : généralement il
est erroné par rapport à la date traitée ce qui conduit à une corruption des données qui n'est pas
facilement détectable ou, plus rarement, une exception est levée.

L'utilisation d'une même instance de SimpleDateFormat dans un contexte multithreads implique


donc qu'il est nécessaire de prendre des précautions : le résultat peut être aléatoire lors du parsing
et du formatage d'une date :

 tout peut bien se passer


 le résultat peut être erroné
 une exception peut être levée
97.3.2. Les points faibles de la classe
SimpleDateFormat
La classe SimpleDateFormat présente deux faiblesses lors de sa mise en oeuvre :

 son instanciation est très couteuse


 ses traitements ne sont pas threadsafe

Exemple :

view source

print?
[Link] [Link];
[Link] [Link];
[Link] [Link];
04.
[Link] class DateUtil {
06.
07. public static final Date parse(String date) throws ParseException{
08. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-
yyyy");
09. return [Link](date);
10. }
11.
12. public static final String format(Date date) throws ParseException{
13. SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-
yyyy");
14. return [Link](date); }
15. }

Cette solution est threadsafe mais son inconvénient est qu'elle peut requérir de nombreuses
ressources si le nombre d'invocations est important.

Pour pallier au premier souci, il est possible de créer une instance de classe statique qui permettra
de n'avoir qu'un seul objet.

Exemple :

view source

print?
[Link] [Link];
[Link] [Link];
[Link] [Link];
04.
[Link] class DateUtil {
06.
07. public static final SimpleDateFormat simpleDateFormat = new
SimpleDateFormat("dd-MM-yyyy");
08.
09. public static final Date parse(String date) throws ParseException{
10. return [Link](date);
11. }
12.
13. public static final String format(Date date) throws ParseException{
14. return [Link](date);
15. }
16.}

Cette solution fréquemment utilisée permet de réduire le nombre d'instances créées.


Malheureusement, comme indiqué dans la JavaDoc, elle ne fonctionne pas dans un environnement
multithreads puisque la classe SimpleDateFormat n'est pas threadsafe. L'utilisation de la classe ci-
dessus dans un contexte multithreads peut donner des résultats aléatoires.

Cependant ces résultats aléatoires ne sont pas faciles à détecter dans une application car il faut
que plusieurs threads sollicitent en même temps l'instance de SimpleDateFormat.

Exemple :

view source

print?
[Link] [Link];
02.
[Link] class TestSimpleDateFormat {
04.
05. public static void main(String[] args) {
06. final String[] dates = new String[] {"15-01-2000", "28-02-2005", "20-
04-2005",
07. "31-07-2015" };
08.
09. Runnable runnable = new Runnable() { public void run() {
10. try {
11. for (int j = 0; j < 1000; j++) {
12. for (int i = 0; i < 2; i++) {
13. String date = [Link]([Link](dates[i]));
14. if (!(dates[i].equals(date))) {
15. throw new ParseException(dates[i] + " =>"+ date, 0);
16. }
17. }
18. }
19. } catch (ParseException e) {
20. [Link]();
21. }
22.
23. new Thread(runnable).start();
24.
25. Runnable runnable2 = new Runnable() {
26. public void run() {
27. try {
28. for (int j = 0; j < 1000; j++) {
29. for (int i = 0; i < 2; i++) {
30. String date = [Link]([Link](dates[i]));
31. if (!(dates[i].equals(date))) {
32. throw new ParseException(dates[i] + " =>"+ date, 0);
33. }
34. }
35. }
36. } catch (ParseException e) {
37. [Link]();
38. }
39. }
40. };
41. new Thread(runnable2).start();
42. }
43.}

Dans cet exemple, le nombre d'exceptions et d'anomalies de traitement est important car les
threads utilisent en permanence le même objet. Dans la réalité, par exemple dans une application
web, les exceptions et les dates erronées sont très rares. L'ennui avec les erreurs de formatage et
de parsing c'est qu'elles sont difficiles à détecter.

Il est possible de sécuriser l'utilisation de l'instance de SimpleDateFormat en l'entourant d'un bloc


synchronized dont le moniteur est l'instance de la classe SimpleDateFormat ou en définissant les
méthodes utilisant l'instance synchronized. Ainsi, un seul thread pourra accéder à l'instance à la
fois.

Exemple :

view source

print?
[Link] [Link];
[Link] [Link];
[Link] [Link];
04.
[Link] class DateUtil {
06.
07. public static final SimpleDateFormat simpleDateFormat = new
SimpleDateFormat("dd-MM-yyyy");
08.
09. public synchronized static final Date parse(String date) throws
ParseException{
10. return [Link](date);
11. }
12.
13. public synchronized static final String format(Date date) throws
ParseException{
14. return [Link](date);
15. }
16.}
Cette solution simple est thread-safe mais elle peut impliquer de la contention liée au verrou posé
lors de l'exécution de la méthode qui bloque l'invocation par d'autres threads.

Une autre solution est d'utiliser la classe ThreadLocal qui est capable de fournir une instance pour
le thread en cours, ainsi chaque thread peut avoir sa propre instance.

Exemple :

view source

print?
[Link] [Link];
[Link] [Link];
[Link] [Link];
04.
[Link] class DateUtil {
06.
07. private static ThreadLocal<SimpleDateFormat> format = new
ThreadLocal<SimpleDateFormat>() {
08. protected synchronized SimpleDateFormat initialValue() {
09. return new SimpleDateFormat("dd-MM-yyyy");
10. }
11. };
12.
13. public static final Date parse(String date) throws ParseException{
14. return [Link]().parse(date);
15. }
16.
17. public static final String format(Date date) throws ParseException{
18. return [Link]().format(date); }
19. }

Remarque : selon l'implémentation fournie de la classe ThreadLocal par le JRE, il peut y avoir des
fuites de mémoire lors du redéploiement de l'application dans un conteneur web.

Il peut être intéressant d'utiliser une SoftReference en paramètre du ThreadLocal pour améliorer la
gestion de la mémoire par la JVM.

Exemple :

view source

print?
[Link] [Link];
[Link] [Link];
[Link] [Link];
[Link] [Link];
[Link] [Link];
06.
[Link] class DateUtil {
08.
09. private static final ThreadLocal<SoftReference<DateFormat» format =
10. new ThreadLocal<SoftReference<DateFormat>>();
11.
12. private static DateFormat getDateFormat() {
13. SoftReference<DateFormat> softRef = [Link]();
14. if (softRef != null) {
15. final DateFormat result = [Link]();
16. if (result != null) {
17. return result;
18. }
19. }
20. final DateFormat result = new SimpleDateFormat("dd-MM-yyyy");
21. softRef = new SoftReference<DateFormat>(result);
22. [Link](softRef);
23. return result;
24. }
25.
26. public static final Date parse(final String date) throws ParseException
{
27. return getDateFormat().parse(date);
28. }
29.
30. public static final String format(final Date date) throws
ParseException {
31. return getDateFormat().format(date);
32. }
33.}

Cette approche nécessite de recréer l'instance locale de SimpleDateFormat dans le cas où le


ramasse-miettes aurait détruit la précédente.

Une autre solution peut être d'utiliser une API tiers tel que :

 Joda Time : en remplaçant [Link] par


[Link]
 Apache Jakarta Common Lang : utiliser la classe FastDateFormat. Malheureusement cette
classe ne permet que de formater mais pas de parser une date.

Lors de la mise en oeuvre de la classe SimpleDateFormat, il faut aussi être vigilent car par défaut,
la classe SimpleDateFormat est très permissive : elle tente au mieux de faire correspondre la date
selon le format fourni, ce qui peut conduire à un comportement non souhaité et surtout à des
résultats indésirables.

Exemple :

view source

print?
[Link] [Link];
[Link] [Link];
[Link] [Link];
[Link] [Link];
05.
[Link] class TestDate {
07.
08. public static void main(final String[] args) {
09. final DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
10. Date d;
11. try {
12. d = [Link]("2010-01-15 07:23:30");
13. [Link](d);
14. } catch (final ParseException e) {
15. [Link]();
16. }
17. }
18.}

Résultat :

view source

print?
[Link] Nov 30 23:05:07 CET 2009

Pour que la classe SimpleDateFormat respecte strictement le format fourni et lève une exception
de type [Link], il faut invoquer la méthode setLenient() en lui passant la valeur
false en paramètre.

Exemple :

view source

print?
[Link] [Link];
[Link] [Link];
[Link] [Link];
[Link] [Link];
05.
[Link] class TestDate {
07.
08. public static void main(final String[] args) {
09. final DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
10. [Link](false);
11. Date d;
12. try {
13. d = [Link]("2010-01-15 07:23:30");
14. [Link](d);
15. } catch (final ParseException e) {
16. [Link]();
17. }
18. }
19.}

Résultat :

view source

print?
[Link]: Unparseable date: "2010-01-15 07:23:30"
[Link] [Link]([Link]) at
[Link]([Link])

97.4. Joda Time


La plupart des applications ont besoin à un moment ou à un autre de manipuler des données de
type date ou heure. Le JDK fournit des classes pour permettre ces manipulations, notamment les
classes Date et Calendar, mais leur utilisation n'est pas simple et généralement source d'erreurs.

Joda Time est une bibliothèque open source dont le but est de fournir une solution simple et
complète pour manipuler des données de types date/heure.

Joda Time propose au travers de son API :

 Le support de plusieurs systèmes calendaires dont celui par défaut est celui définit par le
standard ISO8601 (utilisé par XML) : Grégorien, Julien, Bouddhiste, Islamique, ...
 Le parsing et le formatage de dates
 Le support des fuseaux horaires
 Le support de plusieurs classes temporelles : date/heure locale, durée, période,
intervalle, ...

Le but de Joda Time est de proposer une solution de remplacement aux classes de gestion des
dates du JDK qui possèdent plusieurs inconvénients :

 Il n'est pas facile à utiliser pour manipuler des données courantes


 La conception des classes Date et Calendar
 Les performances de certaines fonctionnalités sont plutôt mauvaises

Par exemple, Joda Time gère les mois de 1 à 12 dans son implémentation du calendrier Grégorien
alors que la classe GregorianCalendar du JDK gère les mois de 0 à 11.

Joda Time a été développé pour améliorer la manière d'utiliser des données de type date/heure en
mettant l'accent sur :

 La faciliter d'utilisation
 La fourniture d'un ensemble complet de fonctionnalités relatives aux traitements de
données de type dates/heures
 L'extensibilité : Joda Time propose le support de plusieurs calendriers qui reposent sur la
classe Chronology
 L'interopérabilité avec les classes correspondantes du JDK
 La performance
 La maturité

La version couverte dans cette section est la 2.1. Elle nécessite une version 1.5 ou supérieure du
JDK.

La partie publique de l'API est contenue dans les packages [Link] et [Link].
Joda Time utilise plusieurs concepts :

 Instant (un point unique dans le temps)


 Temps partiel (points multiples dans le temps)
 Intervalle et durée
 Système calendaire
 Fuseau horaire

La classe JodaTimePermission peut être utilisée dans le mécanisme standard de sécurité de la JVM
pour restreindre l'utilisation à certaines fonctionnalités globales de JodaTime.

L'API Joda Time a été utilisée comme une grande source d'inspiration pour la JSR 310.

97.4.1. Les principales classes de JodaTime


La plupart des classes de Joda Time sont immuables : les méthodes qui permettent d'effectuer des
modifications les font sur une copie de l'objet qu'elles retournent.

Classe Rôle

DateTime Equivalent de la classe Calendar

DateMidnight Classe immuable qui encapsule une date dont l'heure est forcée à minuit

LocalDate Classe immuable qui encapsule une date locale (sans fuseau horaire)

LocalTime Classe immuable qui encapsule une heure locale (sans fuseau horaire)

LocalDateTime Classe immuable qui encapsule une date/heure locale (sans fuseau horaire)

97.4.2. Le concept d'Instant


Un instant est un point unique dans le temps dont la représentation est le nombre de millisecondes
depuis le 1er janvier 1970 minuit. Ceci rend un Instant compatible avec les classes Calendar et Date
du JDK.

La représentation d'un instant en une date est dépendante du calendrier et du fuseau horaire
utilisés pour représenter cet instant.

Un instant est défini par l'interface ReadableInstant.

[Link]. L'interface ReadableInstant

L'interface ReadableInstant décrit les fonctionnalités d'un objet qui encapsule un instant.

Les implémentations de cette interface peuvent être immuables ou non.

Joda Time propose plusieurs classes qui implémentent l'interface ReadableInstant dont :

 Instant : une implémentation immuable qui encapsule un instant dans le temps sans utiliser
de système calendaire ou de fuseau horaire particulier. Elle stocke en interne une valeur de
type long qui contient le nombre de millisecondes écoulées depuis le 1 er janvier 1970 à
minuit.
 DateTime : encapsule une date/heure selon un système calendaire et un fuseau horaire
donnés. C'est l'implémentation la plus fréquemment utilisée.
 DateMidnight : cette classe agit comme la classe DateTime excepté le fait que l'heure
encapsulée est toujours minuit.
 MutableDateTime : cette classe agit comme la classe DateTime excepté le fait qu'elle ne
soit pas immuable.

Attention : l'interface ReadableInstant n'est qu'un sous-ensemble des fonctionnalités des classes
qui l'implémente. Il est généralement préférable de typer les variables avec leur implémentation
plutôt que de les typer avec l'interface ReadableInstant sauf si les fonctionnalités requises de
l'instance sont définies dans l'interface.

Il est généralement recommandé d'utiliser dans la mesure du possible des implémentations qui
soient immuables. L'objet ne peut ainsi pas être modifié sans créer une nouvelle instance, ce qui lui
permet d'être thread safe.

Important : Joda Time considère qu'un instant null correspond à l'instant présent. Ainsi lorsqu'une
méthode attend en paramètre un objet de ReadableInstant et que la valeur reçue en paramètre est
null, alors cela revient à passer en paramètre un instant qui correspond à l'instant présent.

[Link]. La classe DateTime

La classe DateTime encapsule un instant dans le temps pour un système calendaire et un fuseau
horaire donné : ceux-ci lui permettent de restituer l'instant encapsulé sous la forme d'une date et
d'une heure.

Par défaut, une instance de type DataTime utilise le système calendaire ISOChronology et le fuseau
horaire obtenu du système. De nombreux constructeurs attendent en paramètre un objet de type
Chronology et/ou DateTimeZone qui permettent de préciser le système calendaire et /ou le fuseau
horaire à utiliser.

Le constructeur sans paramètre créé une instance qui encapsule l'instant courant représenté dans
le système calendaire ISO et le fuseau horaire par défaut.

Exemple :

view source

print?
[Link] datetime = new DateTime();

Plusieurs constructeurs permettent de préciser les éléments de la date/heure encapsulée : année,


mois, jour, heure, minute, seconde.

Exemple :

view source

print?
[Link] datetime = new DateTime(2012,12,25,0,0,0);

La classe DateTime propose plusieurs autres constructeurs qui acceptent une instance de type
Object comme valeur pour représenter la date/heure. Ces surcharges permettent à Joda Time d'être
extensible mais en sacrifiant le typage fort.

Par défaut, la classe ConverterManager permet de gérer les différents types supportés :
 ReadableInstant
 String : une chaîne de caractères qui contient la date au format ISO-8601
 [Link] : dans ce cas, le système calendaire encapsulé est utilisé
 [Link] et [Link]
 Long : un nombre de millisecondes
 null : est interprété par Joda Time comme l'instant présent

Exemple :

view source

print?
[Link] date = new Date();
[Link] timeEnMs = [Link]();
[Link] dateTime = new DateTime(timeEnMs);

Exemple :

view source

print?
[Link] date = new Date();
[Link] dateTime = new DateTime(date);

Exemple :

view source

print?
[Link] calendar = [Link]();
[Link](new Date());
[Link] dateTime = new DateTime(calendar);

Exemple :

view source

print?
[Link] timeString = "2012-12-25";
[Link] dateTime = new DateTime(timeString);

Exemple :

view source

print?
[Link] dt = new DateTime("2012-10-28T16:23:13.324+01:00");

Il est ainsi facile de convertir une instance de type [Link] ou [Link] en un objet
de type DateTime simplement en passant l'instance au constructeur de la classe DateTime.
A l'exécution de l'exemple ci-dessous une exception de type IllegalArgumentException est levée
avec le message No instant converter found for type: [Link] car Joda Time ne peut pas
convertir l'instance de type Object fournie en paramètre en un instant.

Exemple :

view source

print?
[Link] liste = new ArrayList();
[Link] dateCourante = new DateTime(liste);

Plusieurs méthodes statiques permettent d'obtenir une instance de type DateTime.

Méthode Rôle

Obtenir une instance de type DateTime qui encapsule la


static DateTime now() date/heure système courante en utilisant le système
calendaire ISO et le fuseau horaire par défaut

Obtenir une instance de type DateTime qui encapsule la


static DateTime now(Chronology
date/heure système courante en utilisant le système
chronology)
calendaire fourni en paramètre et le fuseau horaire par défaut

Obtenir une instance de type DateTime qui encapsule la


static DateTime
date/heure système courante en utilisant le système
now(DateTimeZone zone)
calendaire ISO et le fuseau horaire fourni en paramètre

Extraire une date/heure de la chaîne de caractères fournie en


static DateTime parse(String str)
paramètre

static DateTime parse(String str, Extraire une date/heure de la chaîne de caractères fournie en
DateTimeFormatter formatter) utilisant le formatteur passé en paramètre

Les opérations de manipulations de date/heure encapsulées dans un objet de type DateTime


peuvent être réalisés en invoquant des méthodes de DateTime ou en invoquant des méthodes sur
les propriétés de l'objet DateTime. Cela rend ces opérations particulièrement pratiques et flexibles
selon les besoins.

La classe DateTime encapsule une date/heure de manière immuable. Les méthodes qui permettent
de modifier un élément de la date/heure encapsulée renvoie une nouvelle instance de type
DateTime qui encapsule le résultat de l'opération.

Méthode Rôle

Renvoyer une nouvelle instance de DateTime


DateTime minus(long duration)
dont la durée fournie a été soustraite

Renvoyer une nouvelle instance de DateTime


DateTime minus(ReadableDuration duration)
dont la durée fournie a été soustraite

Renvoyer une nouvelle instance de DateTime


DateTime minus(ReadablePeriod period)
dont la période fournie a été soustraite

Renvoyer une nouvelle instance de DateTime


DateTime minusDays(int days)
dont le nombre de jours fourni a été soustrait

Renvoyer une nouvelle instance de DateTime


DateTime minusHours(int hours)
dont le nombre d'heures fourni a été soustrait

DateTime minusMillis(int millis) Renvoyer une nouvelle instance de DateTime


dont le nombre de millisecondes fourni a été
soustrait

Renvoyer une nouvelle instance de DateTime


DateTime minusMinutes(int minutes) dont le nombre de minutes fourni a été
soustrait

Renvoyer une nouvelle instance de DateTime


DateTime minusMonths(int months)
dont le nombre de mois fourni a été soustrait

Renvoyer une nouvelle instance de DateTime


DateTime minusSeconds(int seconds) dont le nombre de secondes fourni a été
soustrait

Renvoyer une nouvelle instance de DateTime


DateTime minusWeeks(int weeks) dont le nombre de semaines fourni a été
soustrait

Renvoyer une nouvelle instance de DateTime


DateTime minusYears(int years) dont le nombre d'années fourni a été
soustrait

Renvoyer une nouvelle instance de DateTime


DateTime plus(long duration)
dont la durée fournie a été ajoutée

Renvoyer une nouvelle instance de DateTime


DateTime plus(ReadableDuration duration)
dont la durée fournie a été ajoutée

Renvoyer une nouvelle instance de DateTime


DateTime plus(ReadablePeriod period)
dont la période fournie a été ajoutée

Renvoyer une nouvelle instance de DateTime


DateTime plusDays(int days)
dont le nombre de jours fourni a été ajouté

Renvoyer une nouvelle instance de DateTime


DateTime plusHours(int hours)
dont le nombre d'heures fourni a été ajouté

Renvoyer une nouvelle instance de DateTime


DateTime plusMillis(int millis) dont le nombre de millisecondes fourni a été
ajouté

Renvoyer une nouvelle instance de DateTime


DateTime plusMinutes(int minutes)
dont le nombre de minutes fourni a été ajouté

Renvoyer une nouvelle instance de DateTime


DateTime plusMonths(int months)
dont le nombre de mois fourni a été ajouté

Renvoyer une nouvelle instance de DateTime


DateTime plusSeconds(int seconds) dont le nombre de secondes fourni a été
ajouté

Renvoyer une nouvelle instance de DateTime


DateTime plusWeeks(int weeks) dont le nombre de semaines fourni a été
ajouté

Renvoyer une nouvelle instance de DateTime


DateTime plusYears(int years)
dont le nombre d'années fourni a été ajouté

Convertir en une instance de type


DateMidnight toDateMidnight() DateMidnight en utilisant le même système
calendaire

Convertir en une instance de type LocalDate


LocalDate toLocalDate()
en utilisant le même système calendaire

Convertir en une instance de type


LocalDateTime toLocalDateTime() LocalDateTime en utilisant le même système
calendaire

Renvoyer une nouvelle instance de DateTime


DateTime withCenturyOfEra(int centuryOfEra)
dont le siècle a été modifié
Renvoyer une nouvelle instance de DateTime
DateTime withChronology(Chronology
qui utilise le système calendaire fourni en
newChronology)
paramètre

DateTime withDate(int year, int monthOfYear, int Renvoyer une nouvelle instance de DateTime
dayOfMonth) dont l'année, le mois et le jour ont été modifié

Renvoyer une nouvelle instance de DateTime


DateTime withDayOfMonth(int dayOfMonth)
dont le jour du mois a été modifié

Renvoyer une nouvelle instance de DateTime


DateTime withDayOfWeek(int dayOfWeek)
dont le jour de la semaine a été modifié

Renvoyer une nouvelle instance de DateTime


DateTime withDayOfYear(int dayOfYear)
dont le jour de l'année a été modifié

DateTime withDurationAdded(long durationToAdd, Renvoyer une nouvelle instance de DateTime


int scalar) à la laquelle la durée a été ajoutée

DateTime withDurationAdded(ReadableDuration Renvoyer une nouvelle instance de DateTime


durationToAdd, int scalar) à la laquelle la durée a été ajoutée

Renvoyer une nouvelle instance de DateTime


DateTime withEra(int era)
dont l'ère a été modifiée

DateTime withField(DateTimeFieldType fieldType, Renvoyer une nouvelle instance de DateTime


int value) dont la propriété fournie a été modifiée

DateTime withFieldAdded(DurationFieldType Renvoyer une nouvelle instance de DateTime


fieldType, int amount) dont la propriété fournie a été ajoutée

Renvoyer une nouvelle instance de DateTime


DateTime withHourOfDay(int hour)
dont l'heure du jour a été modifiée

Renvoyer une nouvelle instance de DateTime


DateTime withMillis(long newMillis)
dont le nombre de millisecondes a été modifié

Renvoyer une nouvelle instance de DateTime


DateTime withMillisOfDay(int millis) dont le nombre de millisecondes du jour a été
modifié

Renvoyer une nouvelle instance de DateTime


DateTime withMillisOfSecond(int millis) dont le nombre de millisecondes courant a
été modifié

Renvoyer une nouvelle instance de DateTime


DateTime withMinuteOfHour(int minute)
dont le nombre de minutes a été modifié

Renvoyer une nouvelle instance de DateTime


DateTime withMonthOfYear(int monthOfYear)
dont le mois a été modifié

DateTime withPeriodAdded(ReadablePeriod period, Renvoyer une nouvelle instance de DateTime


int scalar) à laquelle la période a été ajoutée

Renvoyer une nouvelle instance de DateTime


DateTime withSecondOfMinute(int second)
dont le nombre de secondes a été modifié

DateTime withTime(int hourOfDay, int Renvoyer une nouvelle instance de DateTime


minuteOfHour, int secondOfMinute, int dont les heures, les minutes, les secondes et
millisOfSecond) les millisecondes ont été modifiées

Renvoyer une nouvelle instance de DateTime


DateTime withYear(int year)
dont l'année a été modifiée

Renvoyer une nouvelle instance de DateTime


DateTime withZone(DateTimeZone newZone) qui utilise le fuseau horaire fourni en
paramètre sans modifier l'instant encapsulé

DateTime withZoneRetainFields(DateTimeZone Renvoyer une nouvelle instance de DateTime


newZone) qui utilise le fuseau horaire fourni en
paramètre sans modifier les champs
encapsulés

Exemple :

view source

print?
[Link] dateCourante = new DateTime();
[Link] dateLimite = [Link](2);

La classe DateTime propose plusieurs solutions pour obtenir individuellement chacun des champs
de la date/heure encapsulée :

 un getter pour chaque champs


 une méthode qui renvoie un objet de type [Link] pour chaque champs
 la méthode property() qui attend en paramètre et renvoie un objet de type
[Link]

Les propriétés contenues dans un DateTime sont :

Propriété Rôle

centuryOfEra Le siècle

dayOfMonth Le jour du mois

dayOfWeek Le jour de la semaine

dayOfYear Le jour de l'année

era L'ère comme défini par le système calendaire

hourOfDay L'heure

millisOfDay Le nombre de millisecondes du jour

millisOfSecond Le nombre de millisecondes de l'heure

minuteOfDay Le nombre de minutes du jour

minuteOfHour Le nombre de minutes

monthOfYear Le mois

secondOfDay Le nombre de secondes du jour

secondOfMinute Le nombre de secondes

weekOfWeekyear La semaine de l'année

weekYear

Year L'année

yearOfCentury L'année du siècle

yearOfEra

Exemple :

view source

print?
[Link] dateTime = new DateTime();
[Link]([Link]());
[Link]([Link]().get());
[Link]([Link]([Link]()).get());

La classe [Link] encapsule la valeur d'un champ qui est un élément d'une [Link]
classe [Link] propose quelques getters :

Méthode Rôle

Chronology
Retourne le système calendaire du DateTime correspondant au champ
getChronology()

DateTime getDateTime() Retourne l'instance de type DateTime correspondant au champ

DateTimeField getField() Retourne le champ encapsulé

Retourne le nombre de millisecondes du DateTime correspondant au


long getMillis()
champ

La classe DateTime propose plusieurs méthodes qui permettent de modifier la valeur du champ et
de retourner une nouvelle instance de type DateTime qui encapsule le résultat de la mise à jour.

Méthode Rôle

Ajouter une valeur à la valeur de ce champ dans l'instance


DateTime addToCopy(int value)
retournée

Ajouter une valeur à la valeur de ce champ dans l'instance


DateTime addToCopy(long value)
retournée

DateTime setCopy(int value) Modifier la valeur de ce champ dans l'instance retournée

DateTime setCopy(String text) Modifier la valeur de ce champ dans l'instance retournée

DateTime setCopy(String text, Locale


Modifier la valeur de ce champ dans l'instance retournée
locale)

Forcer la valeur de ce champ à sa valeur maximale dans


DateTime withMaximumValue()
l'instance retournée

Forcer la valeur de ce champ à sa valeur minimale dans


DateTime withMinimumValue()
l'instance retournée

Exemple :

view source

print?
[Link] dateTime = new DateTime(new Date());
[Link](dateTime);
[Link]("dayOfMonth " + [Link]().get());
[Link]("dayOfWeek " + [Link]().get());
[Link]("dayOfYear " + [Link]().get());
[Link]("ear " + [Link]().get());
[Link]("hourOfDay " + [Link]().get());
[Link]("millisOfDay " + [Link]().get());
[Link]("millisOfSecond " +
[Link]().get());
[Link]("minuteOfDay " + [Link]().get());
[Link]("minuteOfHour " + [Link]().get());
[Link]("monthOfYear " + [Link]().get());
[Link]("secondOfDay " + [Link]().get());
[Link]("secondOfMinute " +
[Link]().get());
[Link]("weekOfWeekyear " +
[Link]().get());
[Link]("weekyear " + [Link]().get());
[Link]("year " + [Link]().get());
[Link]("yearOfCentury " + [Link]().get());
[Link]("yearOfEra " + [Link]().get());

Résultat :

view source

print?
01.2012-11-08T06:56:46.781+01:00
[Link] 8
[Link] 4
[Link] 313
[Link] 1
[Link] 6
[Link] 25006781
[Link] 781
[Link] 416
[Link] 56
[Link] 11
[Link] 25006
[Link] 46
[Link] 45
[Link] 2012
[Link] 2012
[Link] 12
[Link] 2012

Elle possède aussi de nombreuses méthodes héritées de la classe AbstractReadableInstantField.

Méthode Rôle

Comparer ce champ au champ correspondant de


int compareTo(ReadableInstant instant)
l'instant

Comparer ce champ au champ correspondant de


int compareTo(ReadablePartial partial)
l'instant partiel

boolean equals(Object object) Comparer ce champ à un autre

int get() Obtenir la valeur du champ

String getAsShortText() Obtenir la valeur textuelle courte du champ dans la


locale par défaut.

Obtenir la valeur textuelle du champ dans la locale


String getAsShortText(Locale locale)
fournie.

Obtenir la valeur du champ sous la forme d'une chaîne


String getAsString()
de caractères

Obtenir la valeur textuelle du champ dans la locale par


String getAsText()
défaut.

Obtenir la valeur textuelle du champ dans la locale


String getAsText(Locale locale)
fournie.

int getDifference(ReadableInstant Obtenir la différence entre la valeur de champ et celle


instant) correspondante dans l'instant passé en paramètre

long
Obtenir la différence entre la valeur de champ et celle
getDifferenceAsLong(ReadableInstant
correspondante dans l'instant passé en paramètre
instant)

DateTimeFieldType getFieldType() Obtenir le type du champ

int getMaximumShortTextLength(Locale Obtenir la taille maximale de valeur textuelle courte


locale) pour ce champ

int getMaximumTextLength(Locale Obtenir la taille maximale de valeur textuelle pour ce


locale) champ

int getMaximumValue() Obtenir la valeur maximale pour ce champ

Obtenir la valeur maximale pour ce champ sans tenir


int getMaximumValueOverall()
compte de l'instant

protected abstract long getMillis() Obtenir le nombre de millisecondes du datetime

int getMinimumValue() Obtenir la valeur minimale pour ce champ

Obtenir la valeur minimale pour ce champ sans tenir


int getMinimumValueOverall()
compte de l'instant

String getName() Obtenir le nom du champ

Retourner un booléen qui indique si la valeur du champ


boolean isLeap()
est bissextile

Obtenir une représentation textuelle orientée debug du


String toString()
champ

Exemple :

view source

print?
[Link] dateTime = new DateTime(new Date());
[Link]("date = "+dateTime);
[Link]("nom du champ = "+[Link]().getName());
[Link]("mois EN =
"+[Link]().getAsText([Link]));
[Link]("mois court =
"+[Link]().getAsShortText());
[Link]("est bissextile = "+[Link]().isLeap());
[Link]("jour rounded =
"+[Link]().roundFloorCopy());
[Link]("mois rounded =
"+[Link]().roundFloorCopy());
[Link]("dayofWeek = "+[Link]().toString());

Résultat :

view source

print?
[Link] = 2012-11-08T07:04:03.265+01:00
[Link] du champ = year
[Link] EN = November
[Link] court = nov.
[Link] bissextile = true
[Link] rounded = 2012-11-08T00:00:00.000+01:00
[Link] rounded = 2012-11-01T00:00:00.000+01:00
[Link] = Property[dayOfWeek]

97.4.3. Le concept de Partial


Un instant partiel peut représenter plusieurs points dans le temps. Par exemple, le premier janvier
existe chaque année dans le calendrier Grégorien. Un instant partiel est aussi pratique pour gérer
des dates/heures locales (sans fuseau horaire) ou pour gérer uniquement des dates ou des heures.

L'interface ReadablePartial définit les fonctionnalités d'un objet qui encapsule une date partielle
locale (pas de fuseau horaire). Il est possible de définir tout ou partie des champs de la date/heure
encapsulée.

Il parfois nécessaire de manipuler une partie d'une date et/ou d'une heure : par exemple
uniquement le jour, le mois ou l'heure. Ce besoin est défini par l'interface ReadablePartial qui
représente un instant partiellement défini.

Joda Time propose plusieurs classes qui implémentent l'interface ReadablePartial dont :

 Partial
 LocalDate
 LocalTime
 LocalDateTime

Il est possible de convertir une instance de type ReadablePartial en une instance de type
ReadableInstant en utilisant la méthode toDateTime().

La classe LocalDate encapsule une date (année, mois, jour), sans heure et sans fuseau horaire de
manière immuable.

La classe LocalDate propose plusieurs constructeurs.

Exemple :

view source

print?
1. LocalDate
[Link] = new LocalDate(2012, 12, 25);
A partir de la version 1.3 de Joda Time, la classe LocalDate doit être utilisée à la place de la classe
YearMonthDay qui est deprecated.

La classe LocalTime encapsule une heure (heure, minutes, secondes, millisecondes) sans fuseau
horaire de manière immuable.

La classe LocalTime propose plusieurs constructeurs.

Exemple :

view source

print?
[Link] localTime = new LocalTime(17, 30, 45);

97.4.4. Les concepts d'intervalle, de durée et de


période
Joda Time propose un support pour la gestion d'intervalles qui correspondent à une plage entre
deux dates et de périodes de temps qui sont une durée grâce à trois classes : Interval, Period et
Duration.

Les classes Interval et MutableInterval implémentent l'interface ReadableInterval.

[Link]. La classe Interval

La classe Interval encapsule un intervalle entre deux instants de manière immuable. L'instant de
début est inclus et l'instant de fin est exclu de l'intervalle. L'instant de fin doit donc être supérieur
ou égal à l'instant de début.

Les deux instants doivent obligatoirement utiliser le même système calendaire et le même fuseau
horaire.

La classe Interval propose plusieurs constructeurs.

Exemple :

view source

print?
[Link] interval = new Interval(
2. new DateTime("2012-12-10"),
3. new DateTime("2012-12-15"));

La méthode getStart() renvoie l'instant de début de l'intervalle. La méthode getEnd() renvoie


l'instant de fin de l'intervalle.

La classe Interval propose plusieurs autres méthodes pour manipuler le contenu de l'intervalle.
Exemple :

view source

print?
[Link] debut = new DateTime("2012-01-01");
[Link] fin = [Link]([Link](1));
[Link] interval = new Interval(debut, fin);
[Link]("Interval = " + interval);
[Link] = [Link]([Link]().plusMonths(1));
[Link]("Interval = " + interval);

Résultat :

view source

print?
[Link] =
2.2012-01-01T00:00:00.000+01:00/2012-02-01T00:00:00.000+01:00
[Link] = 2012-01-01T00:00:00.000+01:00/2012-03-01T00:00:00.000+01:00

La méthode contains() permet de déterminer si un Instant est inclus dans l'intervalle ou pas

Exemple :

view source

print?
[Link] interval = new Interval(
02. new DateTime("2012-12-10"),
03. new DateTime("2012-12-15"));
[Link]([Link](
05. new DateTime(2012, 12, 9, 23, 59, 59, 999)));
[Link]([Link](
07. new DateTime(2012, 12, 10, 0, 0, 0, 0)));
[Link]([Link](
09. new DateTime(2012, 12, 14, 23, 59, 59, 999)));
[Link]([Link](
11. new DateTime(2012, 12, 15, 0, 0, 0, 0)));

Résultat :

view source

print?
[Link]
[Link]
[Link]
[Link]
La méthode toDuration() permet d'obtenir une instance de type Duration à partir de l'instance de
type Interval.

Pour comparer deux instances de type Interval, il faut comparer leur durée.

[Link]. La classe Period

Une période ne possède ni système calendaire ni fuseau horaire. Elle ne possède donc pas de
représentation en millisecondes : il est nécessaire d'utiliser un Instant qui servira de référence et
qui précisera le système calendaire et le fuseau horaire à utiliser pour y associer la période.

Par exemple, une période d'un mois ne correspond pas au même nombre de millisecondes si on
l'ajoute au premier janvier ou au premier février. C'est aussi le cas si l'on ajoute une heure : ce ne
sont pas forcement 60 minutes qui sont ajoutés selon le fuseau horaire et l'utilisation de l'heure
d'été/d'hiver.

La classe Period encapsule une durée dont la valeur est constituée de valeurs dans des champs qui
expriment différentes unités.

Par défaut, les champs utilisables dans une Period (années, mois, semaines, jours, heures, minutes,
secondes, millisecondes) sont définis dans une instance de la classe PeriodType. Il est possible de
restreindre les champs utilisables en utilisant la classe PeriodType. La classe PeriodType propose
plusieurs fabriques qui renvoient des instances de type PeriodType :

 Standard : années, mois, semaine, jours, heures, minutes, secondes, millisecondes (c'est
l'instance par défaut)
 YearMonthDayTime : années, mois, jours, heures, minutes, secondes, millisecondes
 YearMonthDay : années, mois, jours
 YearWeekDayTime : années, semaines, jours, heures, minutes, secondes, millisecondes
 YearWeekDay : années, semaines, jours
 YearDayTime : années, jours, heures, minutes, secondes, millisecondes
 YearDay : années, jours, heures
 DayTime : jours, heures, minutes, secondes, millisecondes
 Time : heures, minutes, secondes, millisecondes
 Et une fabrique pour chaque champ

JodaTime propose plusieurs classes qui encapsulent une valeur pour un des champs de manière
immuable : Years, Weeks, Months, Days, Hours, Minutes, Seconds.

Ces classes implémentent l'interface Comparable et proposent quelques méthodes permettant de


réaliser des opérations mathématiques de base sur les valeurs qu'elles encapsulent (plus(),
multipliedBy(), dividedBy(), negated(), ...) et des opérations de comparaison (isGreaterThan(),
isLesserThan()).

La classe Days encapsule un nombre de jours. Elle ne possède pas de constructeur public : pour
obtenir une instance, il faut utiliser une des méthodes statiques qui sont des fabriques.

La méthode days() est une fabrique qui retourne une constante de type Days ou un instance selon
le valeur fournie en paramètre.

La méthode daysBetween() permet d'obtenir une instance qui encapsule le nombre de jours entre
deux Instant ou deux Partial.

La méthode daysIn() permet d'obtenir une instance qui encapsule le nombre de jours d'un Interval.

La classe Hours encapsule un nombre d'heures. Elle ne possède pas de constructeur public : pour
obtenir une instance, il faut utiliser la méthode hours() qui est une fabrique qui retourne une
constante ou une instance de type Hours selon la valeur fournie en paramètre.
La méthode hoursBetween() permet d'obtenir une instance qui encapsule le nombre d'heures entre
deux Instant ou deux Partial.

La méthode hoursIn() permet d'obtenir une instance qui encapsule le nombre d'heure d'un Interval.

La classe Minutes encapsule un nombre de minutes. Elle ne possède pas de constructeur public :
pour obtenir une instance, il faut utiliser la méthode minutes() qui est une fabrique qui retourne
une constante ou une instance de type Minutes selon la valeur fournie en paramètre.

La méthode minutesBetween() permet d'obtenir une instance qui encapsule le nombre de minutes
entre deux Instant ou deux Partial.

La méthode minutesIn() permet d'obtenir une instance qui encapsule le nombre de minutes d'un
Interval.

La classe Seconds encapsule un nombre de secondes. Elle ne possède pas de constructeur public :
pour obtenir une instance, il faut utiliser la méthode seconds() qui est une fabrique qui retourne
une constante ou une instance de type Seconds selon la valeur fournie en paramètre.

La méthode secondsBetween() permet d'obtenir une instance qui encapsule le nombre de secondes
entre deux Instant ou deux Partial.

La méthode secondsIn() permet d'obtenir une instance qui encapsule le nombre de secondes d'un
Interval.

La classe Weeks encapsule un nombre de semaines. Elle ne possède pas de constructeur public :
pour obtenir une instance, il faut utiliser la méthode weeks() qui est une fabrique qui retourne une
constante ou une instance de type Weeks selon la valeur fournie en paramètre.

La méthode weeksBetween() permet d'obtenir une instance qui encapsule le nombre de semaines
entre deux Instant ou deux Partial.

La méthode weeksIn() permet d'obtenir une instance qui encapsule le nombre de semaines d'un
Interval.

La classe Years encapsule un nombre d'années. Elle ne possède pas de constructeur public : pour
obtenir une instance, il faut utiliser la méthode years() qui est une fabrique qui retourne une
constante ou une instance de type Years selon la valeur fournie en paramètre.

La méthode yearsBetween() permet d'obtenir une instance qui encapsule le nombre d'années entre
deux Instant ou deux Partial.

La méthode yearsIn() permet d'obtenir une instance qui encapsule le nombre d'années d'un
Interval.

La classe Period propose de nombreux constructeurs.

Une instance de type Period peut utiliser avec une instance de type Instant pour obtenir une
nouvelle instance de type Instant

Exemple :

view source

print?
[Link] noel = new DateTime("2012-12-25");
[Link] nouvelAn = [Link]([Link](7));
[Link](nouvelAn);
Les classes Period et MutablePeriod implémentent l'interface ReadablePeriod.

La conversion d'une période peut être complexe : par exemple, une journée ne vaut pas forcement
24 heures : elle peut aussi valoir 23 ou 25 heures en fonction de l'heure d'été/d'hiver. Cependant
une journée est généralement considérée comme composée de 24 heures : la classe Days possède
la méthode toStandardHours() qui permet de convertir la valeur en heures sur la base d'une
journée de 24 heures.

La classe Period propose des méthodes pour obtenir et pour modifier les valeurs des différents
champs. Comme la classe Period est immuable, les opérations de modifications renvoient une
nouvelle instance.

Il est possible de créer une instance de type Period qui encapsule la durée entre deux instants. Il
suffit simplement de passer les deux instants en paramètre du constructeur de la classe Period.

Exemple :

view source

print?
[Link] noel12 = new DateTime("2012-12-25");
[Link] noel13 = new DateTime("2013-12-25");
[Link] period = new Period(noel12, noel13);
[Link]([Link]() + " an entre les deux dates");

Le même calcul peut se faire en utilisant la classe Years

Exemple :

view source

print?
[Link] noel12 = new DateTime("2012-12-25");
[Link] noel13 = new DateTime("2013-12-25");
[Link] year = [Link](noel12, noel13);
[Link]([Link]() + " an entre les deux dates");

Attention : Joda Time considère une instance de type Period qui est null comme une période dont
tous les champs sont à zéro.

[Link]. La classe Duration

La classe Duration encapsule une durée mesurée en millisecondes de manière immuable. Un objet
de type Duration ne possède aucun système calendaire ni fuseau horaire.

La classe Duration implémente l'interface ReadableDuration. L'interface ReadableDuration est un


sous-ensemble des opérations du type Duration, il est donc généralement préférable de définir une
variable de type Duration que du type ReadableDuration.
La classe Duration possède plusieurs constructeurs qui attendent en paramètre la durée ou deux
instants qui seront utilisés pour déterminer la durée encapsulée.

Exemple :

view source

print?
[Link] noel = new DateTime("2012-12-25");
[Link] nouvelAn = new DateTime("2013-01-01");
[Link] duree = new Duration(noel, nouvelAn);

Un objet de type Duration peut être ajouté à un objet de type Instant pour obtenir une nouvelle
instance de type Instant

Exemple :

view source

print?
[Link] noel = new DateTime("2012-12-25");
[Link] nouvelAn = [Link](new Duration(24L * 60L * 60L * 1000L *
7));
[Link](nouvelAn);

Une instance de type ReadableDuration à null est considérée par Joda Time comme une instance de
type ReadableDurantion ayant pour durée la valeur zéro.

97.4.5. Les calendriers et les fuseaux horaires


Joda Time propose support de plusieurs systèmes calendaires et la gestion des fuseaux horaires.

La classe abstraite Chronology est la classe de base pour encapsuler un système calendaire. La
classe DateTimeZone encapsule un fuseau horaire.

Joda Time utilise par défaut le système calendaire ISO et le fuseau horaire par défaut du système.

En interne, Joda Time utilise des fabriques pour créer des instances de type Chronology et
DateTimeZone qui sont des singletons.

[Link]. La classe Chronology

Un système calendaire est une manière particulière de représenter le temps et de permettre de


réaliser des calculs temporaux. Joda Time propose en standard le support de plusieurs systèmes
calendaires.

La classe abstraite Chronology est la classe mère de toutes les classes qui encapsulent un système
calendaire. Une instance de type Chronology encapsule un moteur de calcul pour appliquer les
règles d'un système calendaire.
Joda Time propose un système extensible pour supporter différents systèmes calendaires. Joda
Time propose plusieurs classes filles, chacune encapsulant une implémentation d'un système
calendaire :

 ISOChronology : calendrier définit par le standard ISO8601 (calendrier par défaut)


 GJChronology : permet une utilisation du calendrier Julien et du calendrier Grégorien
 GregorianChronology : le calendrier Gregorien
 IslamicChronology : le calendrier Islamique
 JulianChronology : le calendrier Julien
 CopticChronology : le calendrier Copte
 BuddhistChronology : le calendrier Bouddhiste
 EthiopicChronology : le calendrier Ethiopien

Pour obtenir une instance dédiée à un système calendaire, il faut utiliser la fabrique correspondante
en invoquant la méthode getInstance() de la classe qui encapsule le système calendaire souhaité.

Exemple :

view source

print?
[Link] calendrierCopte = [Link]()
[Link] dt = new DateTime(calendrierCopte);

Le système de calendrier par défaut de Joda Time est le calendrier ISO. Ce calendrier est
couramment utilisé mais ne convient pas pour des dates antérieures à 1583.

Il est possible de fournir une instance de type DateTimeZone qui encapsule un fuseau horaire en
paramètre de la fabrique pour préciser le fuseau horaire à utiliser.

Exemple :

view source

print?
[Link] zone = [Link]("Europe/Paris");
[Link] calendrierCopte = [Link](zone)
[Link] dt = new DateTime(calendrierCopte);

Attention : une instance de type Chonology à null est toujours considérée par l'API Joda Time
comme une instance de type Chronology par défaut (système calendaire ISO8601 et fuseau horaire
par défaut).

[Link]. La classe DateTimeZone

Un fuseau horaire correspond à un découpage géographique de la surface de la Terre relatif au


méridien de Greenwich : le fuseau horaire de ce méridien est nommé GMT (Greenwich Mean Time).
Le concept d'UTC (Universal Coordonated Time) est similaire mais pas tout à fait identique.

Le fuseau horaire permet de préciser un décalage, positif ou négatif, par rapport à l'UTC. La valeur
de ce décalage peut varier en fonction de l'utilisation de l'heure d'été/d'hiver (DST en anglais :
Daylight Saving Time).
Un fuseau horaire est utilisé pour calculer une heure par rapport à une position géographique.

La classe DateTimeZone encapsule un fuseau horaire de manière immuable.

Lors du calcul de certaines données temporelles, il peut être important de connaître le lieu où un
point dans le temps doit être représenté. Cela se fait avec un fuseau horaire car selon celui-ci, la
représentation du point dans un calendrier peut être différente.

C'est la raison pour laquelle une instance de type Chronology encapsule une instance de type
DateTimeZone. Si aucun fuseau horaire n'est précisé, alors c'est le fuseau horaire par défaut qui est
utilisé : c'est celui de la machine hôte.

La méthode forId() de la classe DateTimeZone est une fabrique qui permet de créer une instance
en passant en paramètre l'identifiant de la zone concernée.

Exemple :

view source

print?
[Link] zone = [Link]("Europe/Paris");

La classe DateTimeZone définit la constante UTC qui correspond à l'instance de DateTimeZone


pour l'UTC.

La méthode getDefault() permet d'obtenir une instance de type DateTimeZone qui encapsule le
fuseau horaire par défaut qui correspond à celui du système hôte

Exemple :

view source

print?
[Link] zone = [Link]();
[Link](zone);

C'est ce fuseau horaire qui sera utilisé par défaut par l'API Joda Time si aucun fuseau horaire n'est
explicitement précisé.

La méthode statique setDefault() peut être utiliser pour modifier le fuseau horaire qui doit être
utilisé par défaut.

Les fuseaux horaires sont des concepts qui évoluent fréquemment en fonction du contexte
politique du pays concerné. Le JDK et Joda Time utilise la TZ Database. Comme le JDK peut ne pas
être mis à jour, il est possible de mettre à jour la base incluse dans Joda Time et de recompiler la
bibliothèque pour tenir compte des mises à jour dans la définition des fuseaux horaires.

La dernière version de la base peut être téléchargée à l'url : [Link]

Il faut télécharger les sources de l'API Joda Time à l'url [Link]

Il faut décompresser les sources et remplacer les fichiers dans le sous-répertoire


src/java/org/joda/time/tz/src par les fichiers téléchargés.
La recompilation du code source se fait en utilisant la commande ant jar dans le répertoire racine
des sources. Il est recommandé dans ce cas de renommer le fichier jar généré pour indiquer que
cette version à été modifiée par rapport à l'original.

[Link]. Le système calendaire ISO8601

Le système calendaire ISO8601 est une normalisation basée sur le calendrier Grégorien afin de
faciliter les échanges de date/heures entre applications, systèmes et pays.

Ce système calendaire est implémenté dans la classe ISOChronology qui est immuable.

Ce standard définit :

 12 mois : de janvier à décembre, numéroté de 1 à 12


 7 jours : de lundi à dimanche, numéroté de 1 à 7
 plusieurs formats pour restituer la date dont le plus commun est YYYY-MM-
DDTHH:MM:[Link] : il est notamment utilisé dans le standard XML.

La classe ISOChronology est l'implémentation utilisée par défaut par Joda Time : si une instance de
type Chronology fournie à l'API est null, alors c'est une instance de type ISOChronology qui sera
utilisée.

Pour obtenir une instance de type ISOChronology, il faut invoquer sa méthode getInstance().

Exemple :

view source

print?
[Link] chrono = [Link]();
[Link] dt = new DateTime(2012, 12, 25, 0, 0, 0, 0, chrono);

[Link]. La calendrier Bouddhiste

Le calendrier Bouddhiste ne possède qu'une seule ère et ces années possèdent un décalage de 543
ans par rapport au calendrier Grégorien.

La classe BuddhistChronology est l'implémentation du calendrier Bouddhiste. Pour obtenir une


instance, il faut invoquer la méthode getInstance() de la classe BuddhistChronology.

Exemple :

view source

print?
[Link] noel12 = new DateTime("2012-12-25");
[Link] dt = [Link]([Link]());
[Link](dt);

Résultat :

view source
print?
1.2555-12-25T00:00:00.000+01:00

[Link]. Le calendrier Copte

Le calendrier copte est basé sur le calendrier utilisé dans l'Ancien Egypte. Il est utilisé par l'Eglise
Orthodoxe Copte.

Le calendrier Copte repose sur 12 mois de 30 jours chacun suivi d'une période de 5 ou 6 jours.
L'année contient donc 365 ou 366 jours. Les années bissextiles sont celles qui durent 366 jours :
elles surviennent tous les 4 ans.

La classe CopticChronology implémente le calendrier Copte. Dans cette implémentation, les 5ou 6
jours complémentaires sont stockées dans un treizième mois.

Pour obtenir une instance, il faut invoquer sa méthode getInstance().

Exemple :

view source

print?
[Link] noel12 = new DateTime("2012-12-25");
[Link] dt = [Link]([Link]());
[Link](dt);

Résultat :

view source

print?
1.1729-04-16T00:00:00.000+01:00

[Link]. Le calendrier Ethiopien

Le calendrier Ethiopien est similaire au calendrier Copte.

La classe EthiopicChronology implémente le calendrier Ethiopien. Pour obtenir une instance, il faut
invoquer sa méthode getInstance().

Exemple :

view source

print?
[Link] noel12 = new DateTime("2012-12-25");
[Link] dt = [Link]([Link]());
[Link](dt);

Résultat :

view source

print?
1.2005-04-16T00:00:00.000+01:00

[Link]. Le calendrier Grégorien

Le calendrier Grégorien est le calendrier majoritairement utilisé pour les traitements métiers. Ce
calendrier a remplacé le calendrier Julien. Le calendrier Grégorien définit une année bissextile tous
les quatre ans avec deux exceptions : les années divisibles par 100 ne sont pas bissextiles sauf
celles divisibles par 400.

Ce système calendaire est compatible avec le système calendaire ISO même si la gestion du siècle
est légèrement différente. Il n'est utilisable que pour des dates postérieures à 1583.

La classe GregorianChronology implémente le calendrier Grégorien. Pour obtenir une instance, il


faut invoquer sa méthode getInstance().

Exemple :

view source

print?
[Link] noel12 = new DateTime("2012-12-25");
[Link] dt = [Link]([Link]());
[Link](dt);

Résultat :

view source

print?
1.2012-12-25T00:00:00.000+01:00

[Link]. Le système calendaire Grégorien/Julien

Le système calendaire Grégorien/Julien est la combinaison des systèmes calendaires utilisés par les
chrétiens et les romains. Ce système calendaire est utilisé pour des traitements de dates
historiques puisqu'il permet de gérer les dates du calendrier Julien puis celles du calendrier
Grégorien. La date de basculement de calendrier est configurable : elle est par défaut au
15/10/1582 comme la définit le pape Grégory XIII.

La classe GJChronology implémente le calendrier Grégorien/Julien. Cette classe est similaire à la


classe [Link] du JDK.

Pour obtenir une instance, il faut invoquer sa méthode getInstance().


Exemple :

view source

print?
[Link] noel12 = new DateTime("2012-12-25");
[Link] dt = [Link]([Link]());
[Link](dt);

Résultat :

view source

print?
1.2012-12-25T00:00:00.000+01:00

Une des surcharge de la méthode getInstance() permet de préciser le point dans le temps où le
calendrier Grégorien doit être utilisé.

[Link]. Le calendrier Islamique

Le calendrier Islamique est basé sur les cycles de la Lune : il est utilisé dans de nombreux pays
musulmans.

La classe IslamicChronology implémente le système calendaire Islamique. Pour obtenir une


instance, il faut invoquer sa méthode getInstance().

Exemple :

view source

print?
[Link] noel12 = new DateTime("2012-12-25");
[Link] dt = [Link]([Link]());
[Link](dt);

Résultat :

view source

print?
1.1434-02-11T00:00:00.000+01:00

La classe [Link] permet de définir la façon dont les années


bissextiles sont définies.

[Link]. Le calendrier Julien


Le calendrier Julien est utilisé jusqu'au 15 octobre 1582 où il a été remplacé par le calendrier
Grégorien.

La classe JulianChronology implémente le système calendaire Julien. Pour obtenir une instance, il
faut invoquer sa méthode getInstance().

Exemple :

view source

print?
[Link] noel12 = new DateTime("1012-12-25");
[Link] dt = [Link]([Link]());
[Link](dt);

Résultat :

view source

print?
1.1012-12-19T00:00:00.000+00:09:21

97.4.6. La manipulation des dates


Les fonctionnalités de manipulation de dates sont le point fort de l'API Joda Time de part leur
richesse et leur facilité d'utilisation par rapport aux classes fournies par le JDK.

Exemple :

view source

print?
[Link] [Link];
02.
[Link] [Link];
04.
[Link] class TestJodaTime {
06. public static void main(String[] args) {
07. DateTime dateTime = new DateTime(2012, 1, 1, 0, 0, 0, 0);
08. [Link]([Link](30)
09. .toString("dd/MM/yyyy HH:mm:[Link]"));
10. }
11.}

Le code équivalent en utilisant les classes du JDK est le suivant :

Exemple :

view source
print?
[Link] [Link];
02.
[Link] [Link];
[Link] [Link];
05.
[Link] class TestJodaTime {
07.
08. public static void main(String[]args) {
09. Calendar calendar = [Link]();
10. [Link](0);
11. [Link](2012, [Link], 1, 0, 0, 0);
12. SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy
HH:mm:[Link]");
13. [Link](Calendar.DAY_OF_MONTH, 30);
14. [Link]([Link]([Link]()));
15. }
16.}

Cette section propose plusieurs exemples pour illustrer certaines fonctionnalités de manipulation
de dates proposées par Joda Time.

Exemple : obtenir la date/heure courante plus une heure et demi

Exemple :

view source

print?
[Link] now = new DateTime();
[Link] limite = [Link](1).plusMinutes(30);
[Link](limite);

Exemple : obtenir le dernier jour du mois précédent

Exemple :

view source

print?
[Link] dernierJourduMoisPrecedent = [Link]() // aujourd'hui
2. .minusMonths(1) // on retire un mois
3. .dayOfMonth() // on récupère le jour du mois
4. .withMaximumValue(); // on lui affecte sa valeur maximale
[Link](dernierJourduMoisPrecedent);

Exemple : obtenir le lundi de la semaine de Noël


Exemple :

view source

print?
[Link] dateTime = new DateTime("2012-12-25");
[Link] result =
[Link]().setCopy([Link]);
[Link](result);

Résultat :

view source

print?
1.2012-12-24T00:00:00.000+01:00

Exemple : Obtenir la date de paiement à 90 jours fin de mois

Exemple :

view source

print?
[Link] datePaiement = [Link]() // aujourd'hui
2. .plusDays(90) // on ajoute 90 jours
3. .dayOfMonth() // on récupère le jour du mois
4. .withMaximumValue(); // on lui affecte sa valeur maximale
[Link](datePaiement);

Pour calculer le nombre de jours entre deux dates, il est possible d'utiliser la méthode
daysBetween() de la classe Days.

Exemple :

view source

print?
[Link] dateTimeDeb = new DateTime("2012-12-25");
[Link] dateTimeFin = new DateTime("2012-12-31");
[Link] d = [Link](dateTimeDeb, dateTimeFin);
[Link] days = [Link]();
[Link](days);

Résultat :

view source
print?
1.6

Pour obtenir le nombre des différents éléments qui composent l'écart entre deux dates, il est
possible d'utiliser la classe Period.

Exemple :

view source

print?
[Link] dateTimeDeb = new DateTime("2011-11-25");
[Link] dateTimeFin = new DateTime("2012-12-31");
[Link] p = new Period(dateTimeDeb, dateTimeFin,
[Link]());
[Link]("annees " + [Link]());
[Link]("semaines " + [Link]());
[Link]("jours " + [Link]());

Résultat :

view source

print?
[Link] 1
[Link] 5
[Link] 1

Exemple : Obtenir le nombre de jours avant la nouvelle année

Exemple :

view source

print?
[Link] aujourdhui = [Link]();
[Link] nouvelAn = [Link](1).withDayOfYear(1);
[Link] nbJours = [Link](aujourdhui, nouvelAn);
[Link]([Link]());

97.4.7. L'intéropabilité avec les classes du JDK


Joda Time offre une grande facilité pour l'interopérabilité avec les classes du JDK relatives aux
traitements des données de type date/heure (notamment les classes Date et Calendar).
Il est possible de convertir des classes du JDK vers leur équivalent et vice versa tout en profitant de
la facilité et de la richesse des fonctionnalités de manipulation de dates/heures offertes par Joda
Time.

Les classes de Joda Time qui encapsulent une date/heure acceptent comme paramètre dans une
surcharge de leur constructeur un objet de type [Link] ou [Link].

La méthode toCalendar() de la classe AbstractDateTime permet de convertir l'objet Joda Time en


une instance de type [Link].

Exemple :

view source

print?
[Link] dateTime = new DateTime("2012-12-25");
[Link] calendar = [Link]([Link]());
[Link](calendar);

La méthode toGregorianCalendar() de la classe AbstractDateTime permet de convertir l'objet Joda


Time en une instance de type [Link].

Exemple :

view source

print?
[Link] dateTime = new DateTime("2012-12-25");
[Link] calendar = [Link]();
[Link](calendar);

La méthode toDate() de la classe AbstractInstant permet de convertir l'objet Joda Time en une
instance de type [Link].

Exemple :

view source

print?
[Link] dateTime = new DateTime("2012-12-25");
[Link] date = [Link]();
[Link](date);

Pour convertir un objet de type LocalDate en un objet de type Date ou Calender, il est nécessaire
de le convertir au préalable en une instance de type DateMidnight en invoquant la méthode
toDateMidnight().

Exemple :

view source
print?
[Link] localDate = new LocalDate("2012-12-25");
[Link] date = [Link]().toDate();
[Link](date);

97.4.8. Le formattage des dates


L'obtention d'une date à partir d'une ressource externe (fichiers, services web, ...) ou d'une zone de
saisie de l'utilisateur ou le formattage d'une date sont fréquents dans une application. Le format de
ces dates n'est pas toujours le même : Joda Time propose plusieurs solutions pour définir ce format
de manière simple ou personnalisée.

Le plus simple pour formater un objet de type DateTime est d'invoquer sa méthode toString().

Il est possible de fournir en paramètre de la méthode toString() une chaîne de caractères qui
contient le format désiré. Le format à utiliser est quasiment le même que la classe
SimpleDateFormat du JDK.

Exemple :

view source

print?
[Link] dateTime = new DateTime("2012-12-25");
[Link]([Link]("dd-MM-yyyy HH:mm:ss"));
[Link]([Link]("EEEE dd MMMM yyyy HH:mm:ss"));
[Link]([Link]("MM/dd/yyyy HH:mm ZZZZ"));
[Link]([Link]("MM/dd/yyyy HH:mm Z"));

Résultat :

view source

print?
1.25-12-2012 00:00:00
[Link] 25 décembre 2012 00:00:00
3.12/25/2012 00:00 Europe/Paris
4.12/25/2012 00:00 +0100

La classe ISODateTimeFormat est une fabrique pour obtenir des instances de type
DateTimeFormatter pour différent format de dates respectant la norme ISO8601.

Exemple :

view source

print?
[Link] dateTime = new DateTime("2012-12-25");
[Link]([Link]([Link]()))
;
[Link]([Link](ISODateTimeFormat
4. .basicDateTimeNoMillis()));
[Link]([Link](ISODateTimeFormat
6. .basicOrdinalDateTime()));
[Link]
8. .println([Link]([Link]()));

Résultat :

view source

print?
1.20121225T000000.000+0100
2.20121225T000000+0100
3.2012360T000000.000+0100
4.2012W522T000000.000+0100

La classe DateTimeFormatter est utilisée pour formater et extraire une date d'une chaîne de
caractères.

La classe DateTimeFormatter est thread-safe et immuable. Elle contient un cache en interne qui
maintient des instances ce qui évite d'avoir à créer une instance à chaque utilisation.

La classe DateTimeFormat propose plusieurs méthodes qui sont des fabriques pour obtenir des
instances de type DateTimeFormatter. La plupart de ces méthodes proposent des formats
standards. La méthode forPattern() permet de préciser explicitement le format de la date/heure à
utiliser.

Exemple :

view source

print?
[Link] formatter = DateTimeFormat
2. .forPattern("dd-MM-yyyy HH:mm:ss");
[Link] dateTime = [Link]("25-12-2012 00:00:00");
[Link](dateTime);

Résultat :

view source

print?
1.2012-12-25T00:00:00.000+01:00

La méthode withLocale() permet de préciser la locale à utiliser et renvoie une nouvelle instance.
Exemple :

view source

print?
[Link] dateTime = new DateTime("2012-12-25");
[Link] formatter = DateTimeFormat
3. .forPattern("EEEE dd MMMM yyyy HH:mm:ss");
[Link] frenchFmt = [Link]([Link]);
[Link]([Link](dateTime));
[Link] englishFmt = [Link]([Link]);
[Link]([Link](dateTime));

Résultat :

view source

print?
[Link] 25 décembre 2012 00:00:00
[Link] 25 December 2012 00:00:00

Pour des formats très spécifiques, Joda Time propose la classe DateTimeFormatterBuilder qui
implémente le motif de conception builder pour créer une instance de type DateTimeFormatter.

La classe DateTimeFormatterBuilder propose de nombreuses méthodes appendXXX() qui permet de


préciser chaque élément qui devront être ajoutés pour définir le format de la date.

La méthode toFormatter() permet de demander l'instance de type DateTimeFormatter selon la


configuration définie.

L'exemple ci-dessous va demander le formatage de l'année sur deux caractères.

Exemple :

view source

print?
[Link] dateTime = new DateTime("2012-12-25");
[Link] fmt = new
DateTimeFormatterBuilder().appendDayOfMonth(2)
3. .appendLiteral(' ').appendMonthOfYearShortText().appendLiteral(' ')
4. .appendTwoDigitYear(1949).toFormatter();
[Link]([Link](dateTime));

Résultat :

view source

print?
1.25 déc. 12
La méthode clear() permet de réinitialiser la configuration.

97.4.9. D'autres fonctionnalités de Joda Time


Joda Time propose aussi des fonctionnalités pour modifier la date/heure par défaut ou utiliser des
objets mutables.

[Link]. La modification de l'heure de la JVM

La classe DateTimeUtils propose plusieurs méthodes qui permettent de modifier la date/heure


obtenue par l'API Joda Time.

La méthode setCurrentMillisFixed() permet de modifier la date/heure de Joda Time avec celle


correspondant au nombre de millisecondes fournies en paramètre.

La méthode setCurrentMillisOffset() permet de modifier la date/heure de Joda Time en effectuant un


décalage avec le nombre de millisecondes fournies en paramètre.

La méthode setCurrentMillisSystem() permet de modifier la date/heure de Joda Time avec celle du


système.

Exemple :

view source

print?
[Link] noel13 = new DateTime("2013-12-25");
[Link]([Link]());
[Link](new Date());
[Link]([Link]());
05.
06.// remettre la date de Joda Time à la date systeme
[Link]();
[Link]([Link]());
09.
10.// modifier la date de Joda Time à la veille
[Link](1000 * 60 * 60 * 24);
[Link]([Link]());

L'utilisation de ces méthodes peut être pratique pour des tests.

Attention : la date/heure de la JVM obtenue avec les API du JDK n'est pas modifiée.

[Link]. Les objets mutables

Comme la plupart des objets Joda Time sont immuables, leur modification implique la création
d'une nouvelle instance à chaque méthode invoquée. Si plusieurs champs doivent être modifiés, il
peut être utile d'utiliser une version mutable afin de limiter le nombre d'instances créées.
Joda Time propose les classes MutableDateTime, MutableInterval et MutablePeriod.

Exemple :

view source

print?
[Link] noel13 = new DateTime("2013-12-25");
[Link] mdt = [Link]();
[Link](1);
[Link](2012);
[Link](1);
[Link] result = [Link]();
[Link](result);

La classe MutableDateTime possède de nombreux constructeurs pour indiquer la date/heure


encapsulée.

La classe DateTime propose aussi la méthode toMutableDateTime() qui renvoie une instance de
type MutableDateTime qui encapsule la date/heure de l'objet.

La classe MutableDateTime propose de nombreuses méthodes qui ne renvoient rien pour modifier
un champ de la date/heure encapsulée.

La méthode toDateTime() permet de renvoyer une instance de type DateTime qui encapsule la
date/heure de l'objet.

97.5. La classe FastDateFormat du projet


Apache [Link]
La classe [Link] permet le formatage d'une date comme
SimpleDateFormat mais elle est plus performante et surtout thread-safe.

La classe FastDateFormat offre des fonctionnalités de formatage d'une date similaires à celles de la
clase SimpleDateFormat : elle propose cependant un support du timezone différent dans le
formatage.

FastDateFormat ne permet que le formatage d'une date, elle ne permet pas comme la classe
SimpleDateFormat le fait, d'extraire une date d'une chaîne de caractères.

Exemple :

view source

print?
[Link] [Link]; import [Link];
02.
[Link] [Link];
04.
[Link] class TestSdf {
06.
07. public static void main(final String[] args) {
08. final String format = "dd-MM-yyyy HH:mm:[Link]";
09. SimpleDateFormat sdf = new SimpleDateFormat(format);
10. FastDateFormat fdf = [Link](format);
11. final Date d = new Date();
12. final int nblteration = 1000000;
13. long start = 0;
14. long tempsTrt = 0;
15.
16. start = [Link]();
17. for (int i = 0; i < nblteration; i++) {
18. fdf = [Link](format);
19. [Link]([Link]());
20. [Link](d);
21. }
22. tempsTrt = [Link]() - start;
23. [Link]("FastDateFormat : " + tempsTrt + " ms");
24.
25. start = [Link]();
26. for (int i = 0; i < nblteration; i++) {
27. sdf = new SimpleDateFormat(format);
28. [Link]([Link]());
29. [Link](d);
30. }
31. tempsTrt = [Link]() - start;
32. [Link]("SimpleDateFormat : " + tempsTrt + " ms");
33. }
34.
35.}

Résultat :

view source

print?
[Link] : 2041 ms
[Link] : 5360 ms

La classe [Link] est une classe utilitaire pour le


formatage de dates et d'heures en utilisant la classe FastDateFormat.

Elle propose des constantes pour des instances de FastDateFormat avec des motifs de formatage
courants en ISO08601 et SMTP :

formatage d'une date/heure en ISO860 sans timezone :


ISO_DATETIME_FORMAT
yyyy-MM-dd'T'HH:mm:ss

formatage d'une date/heure en ISO8601 avec timezone :


ISO_DATETIME_TIMEZONE_FORMAT
yyyy-MM-dd'T'HH:mm:ssZZ

formatage d'une date enISO8601 sans timezone : yyyy-


ISO_DATE_FORMAT
MM-dd
formatage d'une heure en pseudo ISO8601 sans time zone
ISO_TIME_FORMAT (la spécification ne permet pas d'avoir une heure sans
timezone) : 'T'HH:mm:ss

formatage d'une date enISO8601 sans timezone (la


ISO_DATE_TIME_ZONE_FORMAT spécification ne permet pas d'avoir une heure sans
timezone) : yyyy-MM-ddZZ

formatage d'une heure en ISO8601 avec time zone :


ISO_TIME_TIMEZONE_FORMAT
'T'HH:mm:ssZZ.

formatage d'une heure en pseudo ISO8601 sans time zone


ISO_TIME_NOT_FORMAT (la spécification requiert que l'heure soit préfixée par le
caractère T) : HH:mm:ss.

formatage d'une heure en pseudo ISO8601 avec time zone


ISO_TIME_NOTTIMEZONE_FORMAT (la spécification requiert que l'heure soit préfixée par le
caractère T) : HH:mm:ssZZ.

formatage d'une date heure au format requis par SMTP :


SMTP_DATETIME_FORMAT
EEE, dd MMM yyyy EH:mm:ss Z in US locale.

Il n'est pas recommandé d'utiliser son constructeur par défaut.

Elle propose de nombreuses méthodes notamment plusieurs surcharges des méthodes format() et
formatUTC() acceptant la date à formater en plusieurs formats (long, Date, Calendar) et permettant
de préciser le format et la Locale à utiliser.

Exemple :

view source

print?
[Link] static void main(final String[] args) {
02. final Date today = new Date();
03.
04. /*
05. * formatage en ISO8601 sans timezone : yyyy-MM-dd'T'HH:mm:ss.
06. */
07. String timestamp = DateFormatUtils.ISO_DATETIME_FORMAT.format(today);
08. [Link]("timestamp = " + timestamp);
09.
10. /*
11. * formatage en ISO8601 avec timezone : yyyy-MM-dd' T'HH:mm:ssZZ.
12. */
13. timestamp =
DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(today)
14. [Link]("timestamp = " + timestamp);
15.
16. /*
17. * formatage au format SMTP : EEE, dd MMM yyyy HH:mm:ss Z (Locale US).
18. */
19. timestamp = DateFormatUtils.SMTP_DATETIME_FORMAT.format(today);
20. [Link]("timestamp = " + timestamp); }

Vous aimerez peut-être aussi