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.
Pas de fuseau horaire dans j.u.Date
Comme l'indiquent les autres réponses correctes, une date 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 son toString
applique le fuseau horaire par défaut de la JVM lors de la génération d'une représentation sous forme de chaîne.
Éviter j.u.Date
Pour cette raison et bien d'autres, vous devriez éviter d'utiliser les formats intégrés java.util.Date & .Calendar & java.text.SimpleDateFormat. Ils sont notoirement problématiques.
Au lieu de cela, utilisez l'option Paquet java.time regroupés avec Java 8 .
java.time
Les classes java.time peuvent représenter un moment sur la ligne du temps de trois manières :
- UTC (
Instant
)
- Avec un décalage (
OffsetDateTime
con ZoneOffset
)
- Avec un fuseau horaire (
ZonedDateTime
con ZoneId
)
Instant
En java.time L'élément de base est le suivant Instant
, un moment sur la ligne du temps en UTC. Utiliser Instant
pour une grande partie de votre logique d'entreprise.
Instant instant = Instant.now();
OffsetDateTime
Appliquer un décalage par rapport à l'UTC pour s'adapter à la situation d'une localité l'heure de l'horloge murale .
Appliquer un ZoneOffset
pour obtenir un OffsetDateTime
.
ZoneOffset zoneOffset = ZoneOffset.of( "-04:00" );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );
ZonedDateTime
Il est préférable d'appliquer un fuseau horaire , un décalage plus les règles de traitement des anomalies telles que Heure d'été (DST) .
Appliquer un ZoneId
à un Instant
pour obtenir un ZonedDateTime
. Toujours spécifier un nom du fuseau horaire approprié . N'utilisez jamais les abréviations 3-4 telles que EST
o IST
qui ne sont ni uniques ni normalisés.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
LocalDateTime
Si la chaîne d'entrée ne contient pas d'indicateur de décalage ou de zone, elle est analysée en tant que LocalDateTime
.
Si vous êtes certain du fuseau horaire prévu, attribuez un ZoneId
pour produire un ZonedDateTime
. Voir l'exemple de code ci-dessus dans tl;dr en haut.
Chaînes formatées
Appeler le toString
sur l'une de ces trois classes pour générer une chaîne de caractères représentant la valeur de la date et de l'heure dans la norme ISO 8601 format. Le format ZonedDateTime
é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 fonction DateTimeFormatter
classe. Il est généralement préférable de laisser cette classe générer des formats localisés en utilisant la langue humaine et les normes culturelles attendues par l'utilisateur. Vous pouvez également spécifier un format particulier.
A propos de java.time
Les java.time est intégré à Java 8 et aux versions ultérieures. Ces classes remplacent les anciennes classes héritage les classes de date et d'heure telles que java.util.Date
, Calendar
, & SimpleDateFormat
.
Pour en savoir plus, consultez le site Tutoriel Oracle . Vous trouverez de nombreux exemples et explications sur Stack Overflow. La spécification est JSR 310 .
Les Joda-Time Le projet, en cours d'élaboration, est en cours de réalisation. mode de maintenance conseille de migrer vers l java.time classes.
Vous pouvez échanger java.time directement avec votre base de données. L'utilisation d'un Pilote JDBC conforme à JDBC 4.2 ou plus tard. Pas besoin de ficelles, pas besoin de java.sql.*
classes. Support d'Hibernate 5 et de JPA 2.2 java.time .
Où obtenir les classes java.time ?
Joda-Time
Tandis que Joda-Time est toujours activement maintenu, ses créateurs nous ont demandé de migrer vers java.time dès que possible. Je laisse cette section intacte en tant que référence, mais je suggère d'utiliser le fichier java.time
ci-dessus.
En Joda-Time un objet date-heure ( DateTime
) connaît vraiment le fuseau horaire qui lui est attribué. Cela signifie qu'un décalage par rapport à UTC y les règles et l'histoire 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 );
Appeler le toString
pour générer une chaîne de caractères en ISO 8601 format.
String output = dateTimeIndia.toString();
Joda-Time offre également de nombreuses possibilités pour générer toutes sortes d'autres formats de chaînes de caractères.
Si nécessaire, vous pouvez convertir une date Joda-Time DateTime en une date java.util.Date.
Java.util.Date date = dateTimeIndia.toDate();
Faites une recherche sur StackOverflow avec "joda date" pour trouver de nombreux autres exemples, dont certains sont très détaillés.
† En fait, il y a est un fuseau horaire intégré dans une java.util.Date, utilisé pour certaines fonctions internes (voir les commentaires sur cette réponse). Mais ce fuseau horaire interne n'est pas exposé comme une propriété, et ne peut pas être défini. Ce fuseau horaire interne est no celui utilisé par le toString
pour générer une représentation sous forme de chaîne de la valeur de la date et de l'heure ; à la place, le fuseau horaire par défaut de la JVM est appliqué à la volée. En résumé, nous disons souvent "j.u.Date n'a pas de fuseau horaire". Cela peut-il prêter à confusion ? Oui. Encore une autre raison d'éviter ces vieilles classes fatiguées.
8 votes
Bien que ce ne soit pas vraiment une réponse à votre question, j'ai utilisé Joda Time après l'avoir vu mentionné ici à plusieurs reprises. Il me semble plus rationnel que les API standard, et peut faire ce genre de choses assez facilement.
2 votes
@msandiford Aujourd'hui, utiliser java.time plutôt que Joda-Time. Les Joda-Time Le projet est maintenant en mode de maintenance L'équipe conseille la migration vers l'application java.time classes. Voir Tutoriel d'Oracle .