tl; dr
… Analysé… à partir d'une chaîne… le fuseau horaire n'est pas spécifié… je veux définir un fuseau horaire spécifique
LocalDateTime.parse( "2018-01-23T01:23:45.123456789" ) // Parse string, lacking an offset-from-UTC and lacking a time zone, as a `LocalDateTime`.
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Assign the time zone for which you are certain this date-time was intended. Instantiates a `ZonedDateTime` object.
Aucun fuseau horaire dans juDate
Comme les autres bonnes réponses l'ont indiqué, un java.util.Date n'a pas de fuseau horaire † . Il représente UTC / GMT (pas de décalage de fuseau horaire). Très déroutant car sa toString
méthode applique le fuseau horaire par défaut de la JVM lors de la génération d'une représentation String.
Évitez juDate
Pour cela et pour bien d'autres raisons, vous devez éviter d'utiliser le java.util.Date & .Calendar & java.text.SimpleDateFormat intégré. Ils sont notoirement gênants.
Utilisez plutôt le package java.time fourni avec Java 8 .
java.time
Les classes java.time peuvent représenter un moment sur la timeline de trois manières:
- UTC (
Instant
)
- Avec un décalage (
OffsetDateTime
avec ZoneOffset
)
- Avec un fuseau horaire (
ZonedDateTime
avec ZoneId
)
Instant
Dans java.time , le bloc de construction de base est Instant
, un moment sur la ligne de temps en UTC. Utilisez des Instant
objets pour une grande partie de votre logique métier.
Instant instant = Instant.now();
OffsetDateTime
Appliquez un décalage par rapport à l'UTC pour ajuster le temps d'horloge murale d' une localité .
Appliquez un ZoneOffset
pour obtenir un OffsetDateTime
.
ZoneOffset zoneOffset = ZoneOffset.of( "-04:00" );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );
ZonedDateTime
Il vaut mieux appliquer un fuseau horaire , un décalage ainsi que les règles de gestion des anomalies telles que l' heure d'été (DST) .
Appliquez un ZoneId
à un Instant
pour obtenir un ZonedDateTime
. Spécifiez toujours un nom de fuseau horaire correct . N'utilisez jamais 3-4 abréviations telles que EST
ou IST
qui ne sont ni uniques ni standardisées.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
LocalDateTime
Si la chaîne d'entrée n'avait aucun indicateur de décalage ou de zone, analysez comme a LocalDateTime
.
Si vous êtes certain du fuseau horaire prévu, attribuez a ZoneId
pour produire a ZonedDateTime
. Voir l'exemple de code ci-dessus dans la section tl; dr en haut.
Chaînes formatées
Appelez la toString
méthode sur l'une de ces trois classes pour générer une chaîne représentant la valeur date-heure au format ISO 8601 standard. La ZonedDateTime
classe étend le format standard en ajoutant le nom du fuseau horaire entre parenthèses.
String outputInstant = instant.toString(); // Ex: 2011-12-03T10:15:30Z
String outputOdt = odt.toString(); // Ex: 2007-12-03T10:15:30+01:00
String outputZdt = zdt.toString(); // Ex: 2007-12-03T10:15:30+01:00[Europe/Paris]
Pour d'autres formats, utilisez la DateTimeFormatter
classe. Il est généralement préférable de laisser cette classe générer des formats localisés en utilisant le langage humain et les normes culturelles attendus de l'utilisateur. Ou vous pouvez spécifier un format particulier.
À propos de java.time
Le framework java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciens gênants hérités des classes date-heure tels que java.util.Date
, Calendar
, et SimpleDateFormat
.
Le projet Joda-Time , désormais en mode maintenance , conseille la migration vers les classes java.time .
Pour en savoir plus, consultez le didacticiel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .
Vous pouvez échanger des objets java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou version ultérieure. Pas besoin de chaînes, pas besoin de java.sql.*
cours.
Où obtenir les classes java.time?
Le projet ThreeTen-Extra étend java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour de futurs ajouts possibles à java.time. Vous trouverez peut - être des classes utiles ici, comme Interval
, YearWeek
, YearQuarter
et plus .
Joda-Time
Bien que Joda-Time soit toujours activement maintenu, ses fabricants nous ont dit de migrer vers java.time dès que cela serait pratique. Je laisse cette section intacte comme référence, mais je suggère d'utiliser la java.time
section ci-dessus à la place.
Dans Joda-Time , un objet date-heure ( DateTime
) connaît vraiment son fuseau horaire attribué. Cela signifie un décalage par rapport à l'UTC et aux règles et à l'historique de l'heure d'été (DST) de ce fuseau horaire et à d'autres anomalies de ce type.
String input = "2014-01-02T03:04:05";
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( input, timeZone );
DateTime dateTimeUtcGmt = dateTimeIndia.withZone( DateTimeZone.UTC );
Appelez la toString
méthode pour générer une chaîne au format ISO 8601 .
String output = dateTimeIndia.toString();
Joda-Time offre également de riches capacités pour générer toutes sortes d'autres formats de chaîne.
Si nécessaire, vous pouvez convertir Joda-Time DateTime en java.util.Date.
Java.util.Date date = dateTimeIndia.toDate();
Recherchez StackOverflow pour "date Joda" pour trouver de nombreux autres exemples, certains assez détaillés.
† En fait, il y a un fuseau horaire intégré dans un java.util.Date, utilisé pour certaines fonctions internes (voir les commentaires sur cette réponse). Mais ce fuseau horaire interne n'est pas exposé en tant que propriété et ne peut pas être défini. Ce fuseau horaire interne n'est pas celui utilisé par la toString
méthode pour générer une représentation sous forme de chaîne de la valeur date-heure; au lieu de cela, le fuseau horaire par défaut actuel de la JVM est appliqué à la volée. Donc, en sténographie, nous disons souvent «juDate n'a pas de fuseau horaire». Déroutant? Oui. Encore une autre raison d'éviter ces vieilles classes fatiguées.