web-dev-qa-db-fra.com

Conversion de chaîne en date avec un fuseau horaire

J'ai une chaîne dans le modèle aaaa-MM-jj hh: mm a Et je peux obtenir l'objet de fuseau horaire séparément dans lequel la chaîne ci-dessus représente la date.

Je veux convertir ceci au format ci-dessous . Aaaa-MM-jj HH: mm: ss Z

Comment puis-je faire ceci?

14
John

Vous pouvez utiliser SimpleDateFormat avec yyyy-MM-dd HH:mm:ss et définir explicitement le TimeZone :

public static Date getSomeDate(final String str, final TimeZone tz)
    throws ParseException {
  final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm a");
  sdf.setTimeZone(tz);
  return sdf.parse(str);
}

/**
 * @param args
 * @throws IOException
 * @throws InterruptedException
 * @throws ParseException
 */
public static void main(final String[] args) throws ParseException {
  final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
  System.out.println(sdf.format(getSomeDate(
      "2010-11-17 01:12 pm", TimeZone.getTimeZone("Europe/Berlin"))));
  System.out.println(sdf.format(getSomeDate(
      "2010-11-17 01:12 pm", TimeZone.getTimeZone("America/Chicago"))));
}

Imprime: 

2010-11-17 13:12:00 +0100

2010-11-17 20:12:00 +0100

Mise à jour 2010-12-01: Si vous souhaitez imprimer explicitement un fuseau horaire spécial, définissez-le dans SimpleDateFormat:

sdf.setTimeZone(TimeZone .getTimeZone("IST")); 
System.out.println(sdf.format(getSomeDate(
    "2010-11-17 01:12 pm", TimeZone.getTimeZone("IST"))));

Quelles impressions 2010-11-17 13:12:00 +0530

21
Michael Konietzka

tl; dr

LocalDateTime.parse(                        // Parse string as value without time zone and without offset-from-UTC.
    "2017-01-23 12:34 PM" , 
    DateTimeFormatter.ofPattern( "uuuu-MM-dd hh:mm a" )
)                                           // Returns a `LocalDateTime` object.
.atZone( ZoneId.of( "America/Montreal" ) )  // Assign time zone, to determine a moment. Returns a `ZonedDateTime` object.
.toInstant()                                // Adjusts from zone to UTC.
.toString()                                 // Generate string: 2017-01-23T17:34:00Z
.replace( "T" , " " )                       // Substitute SPACE for 'T' in middle.
.replace( "Z" , " Z" )                      // Insert SPACE before 'Z'.

Évitez les anciennes classes date-heure

Les autres réponses utilisent les anciennes classes gênantes (Date, Calendar, etc.), désormais héritées, supplantées par les classes Java.time.

LocalDateTime

J'ai une chaîne dans le motif aaaa-MM-jj hh: mm a 

Une telle chaîne d'entrée n'a aucune indication de décalage par rapport à UTC ou de fuseau horaire. Nous analysons donc comme un { LocalDateTime

Définissez un modèle de mise en forme correspondant à votre entrée avec un objet DateTimeFormatter .

String input = "2017-01-23 12:34 PM" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd hh:mm a" );
LocalDateTime ldt = LocalDateTime.parse( input , f );

ldt.toString (): 2017-01-23T12: 34

Notez qu'une LocalDateTime est pas un moment spécifique, seulement une idée vague sur une plage de moments possibles. Par exemple, quelques minutes après minuit à Paris, la France est encore «hier» à Montréal, au Canada. Donc, sans le contexte d'un fuseau horaire tel que Europe/Paris ou America/Montreal , le simple fait de dire «quelques minutes après minuit» n'a pas de sens.

ZoneId

et je peux obtenir l'objet de fuseau horaire séparément dans lequel la chaîne ci-dessus représente la date.

Un fuseau horaire est représenté par la classe ZoneId

Spécifiez un nom du fuseau horaire } au format continent/region, tel que America/Montreal , Africa/Casablanca ou Pacific/Auckland. N'utilisez jamais les abréviations de 3-4 lettres telles que EST ou IST car elles sont pas des fuseaux horaires véritables, non standardisés et même pas uniques (!). 

ZoneId z = ZoneId.of( "America/Montreal" );

ZonedDateTime

Appliquez la ZoneId pour obtenir un ZonedDateTime qui est bien un point sur la timeline, un moment spécifique de l’histoire.

ZonedDateTime zdt = ldt.atZone( z );

zdt.toString (): 2017-01-23T12: 34-05: 00 [Amérique/Montréal]

Instant

Je veux convertir ceci au format ci-dessous. aaaa-MM-jj HH: mm: SS Z

Tout d'abord, sachez qu'un caractère littéral Z est l'abréviation de Zulu et signifie UTC . En d'autres termes, un décalage par rapport à l'heure UTC de zéro heure, +00:00.

La classe Instant représente un moment sur la ligne temporelle en UTC avec une résolution de nanosecondes (jusqu'à neuf (9) chiffres d'une fraction décimale). 

Vous pouvez extraire un objet Instant à partir de ZonedDateTime

Instant instant = zdt.toInstant();  // Extracting the same moment but in UTC.

Pour générer une chaîne au format standard ISO 8601 , tel que 2017-01-22T18:21:13.354Z, appelez toString. Le format standard n'a pas d'espaces, utilise une T pour séparer l'année, le mois et la date de l'heure, les minutes et les secondes et ajoute la Z de manière canon pour un décalage de zéro. 

String output = instant.toString();

instant.toString (): 2017-01-23T17: 34: 00Z

Je suggère fortement d'utiliser les formats standard chaque fois que possible. Si vous insistez pour utiliser des espaces dans le format souhaité, définissez votre propre modèle de formatage dans un objet DateTimeFormatter ou effectuez simplement une manipulation de chaîne sur la sortie de Instant::toString .

String output = instant.toString()
                       .replace( "T" , " " )  // Substitute SPACE for T.
                       .replace( "Z" , " Z" ); // Insert SPACE before Z.

sortie: 2017-01-23 17:34:00 Z

Essayez ceci code en direct sur IdeOne.com .


À propos de Java.time

Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciennes classes gênantes héritées _ date-heure telles que Java.util.Date , Calendar _, & SimpleDateFormat .

Le projet Joda-Time , désormais en mode maintenance , conseille de migrer vers les classes Java.time .

Pour en savoir plus, consultez le Tutoriel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .

Où obtenir les classes Java.time? 

  • Java SE 8 et SE 9 et versions ultérieures
    • Intégré. 
    • Une partie de l'API Java standard avec une implémentation fournie.
    • Java 9 ajoute quelques fonctionnalités et corrections mineures.
  • Java SE 6 et SE 7
    • Une grande partie de la fonctionnalité Java.time est rétroportée vers Java 6 et 7 dans ThreeTen-Backport .
  • Android

Le projet ThreeTen-Extra étend Java.time avec des classes supplémentaires. Ce projet est un terrain d’essai pour d’éventuels ajouts à Java.time. Vous pouvez y trouver des classes utiles telles que Interval _, YearWeek , YearQuarter _ et plus _.

9
Basil Bourque

Utilisez SimpleDateFormat

String string1 = "2009-10-10 12:12:12 ";
SimpleDateFormat sdf =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z")
sdf.setTimeZone(tz);
Date date = sdf.parse(string1);
5
Jigar Joshi

Sans aucun doute, le format généralement utilisé sera de la forme 2014-10-05T15:23:01Z (TZ)

Pour cela, il faut utiliser ce code

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
String dateInString = "2014-10-05T15:23:01Z";

 try {

     Date date = formatter.parse(dateInString.replaceAll("Z$", "+0000"));
     System.out.println(date);

 } catch (ParseException e) {
     e.printStackTrace();
 }

Sa sortie sera le Sun Oct 05 20:53:01 IST 2014

Cependant, je ne sais pas pourquoi nous avons dû remplacerTous "Z" si vous n’ajoutez pas replaceTout le programme échouera.

0
Somum

Créez une nouvelle instance de SimpleDateFormat en utilisant votre modèle de date. Vous pouvez ensuite appeler sa méthode d'analyse pour convertir les chaînes de date en un objet Java.util.Date.

0
Robert