web-dev-qa-db-fra.com

Convertir une chaîne en objet de calendrier en Java

Je suis nouveau sur Java, travaille généralement avec PHP.

J'essaie de convertir cette chaîne:

Lundi 14 mars 16:02:37 GMT 2011

Dans un objet de calendrier afin que je puisse facilement extraire l'année et le mois comme ceci:

String yearAndMonth = cal.get(Calendar.YEAR)+cal.get(Calendar.MONTH);

Serait-ce une mauvaise idée de l'analyser manuellement? Vous utilisez une méthode de sous-chaîne?

Tout conseil aiderait merci!

145
Doug Molineux
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
cal.setTime(sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));// all done

remarque: définissez Locale en fonction de votre environnement/de vos besoins


Voir également

352
Jigar Joshi

Eh bien, je pense que ce serait une mauvaise idée de reproduire le code déjà présent dans des classes telles que SimpleDateFormat .

D'autre part, personnellement, je suggérerais d'éviter si possible Calendar et Date entièrement et d'utiliser Joda Time à la place, comme une API de date et heure bien mieux conçue. Par exemple, vous devez savoir que SimpleDateFormat est not thread-safe, vous avez donc besoin de locals de thread, d'une synchronisation ou d'une nouvelle instance chaque fois que vous l'utilisez. Les analyseurs et formateurs Joda sont thread-safe.

14
Jon Skeet

tl; dr

L'approche moderne utilise les classes Java.time

YearMonth.from(
    ZonedDateTime.parse( 
        "Mon Mar 14 16:02:37 GMT 2011" , 
        DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" )
     )
).toString()

2011-03

Évitez les anciennes classes date-heure

La manière moderne est avec les classes Java.time. Les anciennes classes date-heure telles que Calendar se sont révélées mal conçues, confuses et gênantes.

Définissez un formateur personnalisé correspondant à votre entrée de chaîne.

String input = "Mon Mar 14 16:02:37 GMT 2011";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" );

Analyser comme une ZonedDateTime.

ZonedDateTime zdt = ZonedDateTime.parse( input , f );

Vous êtes intéressé par l'année et le mois. Les classes Java.time incluent la classe YearMonth à cette fin.

YearMonth ym = YearMonth.from( zdt );

Vous pouvez interroger les numéros de l'année et du mois si nécessaire.

int year = ym.getYear();
int month = ym.getMonthValue();

Mais la méthode toString génère une chaîne au format standard ISO 8601 .

String output = ym.toString();

Mettez tout cela ensemble.

String input = "Mon Mar 14 16:02:37 GMT 2011";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
YearMonth ym = YearMonth.from( zdt );
int year = ym.getYear();
int month = ym.getMonthValue();

Dump à la console.

System.out.println( "input: " + input );
System.out.println( "zdt: " + zdt );
System.out.println( "ym: " + ym );

entrée: lundi 14 mars 16:02:37 GMT 2011

zdt: 2011-03-14T16: 02: 37Z [GMT]

ym: 2011-03

Code live

Voir ce code est en cours d'exécution dans IdeOne.com .

Conversion

Si vous devez avoir un objet Calendar, vous pouvez convertir en un GregorianCalendar à l'aide de nouvelles méthodes ajoutées aux anciennes classes.

GregorianCalendar gc = GregorianCalendar.from( zdt );

À 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 la migration vers 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 _.

12
Basil Bourque

Aucun nouveau calendrier ne doit être créé, SimpleDateFormat utilise déjà un calendrier en dessous.

SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.EN_US);
Date date = sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));// all done
Calendar cal = sdf.getCalendar();

(Je ne peux pas encore commenter, c'est pourquoi j'ai créé une nouvelle réponse)

9
GoGoris

SimpleDateFormat est super, il suffit de noter que HH est différent de hh lorsque vous travaillez avec des heures. HH retournera des heures basées sur 24 heures et hh retournera des heures basées sur 12 heures.

Par exemple, ce qui suit retournera l'heure 12 heures:

SimpleDateFormat sdf = new SimpleDateFormat("hh:mm aa");

Bien que cela revienne 24 heures:

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
5
Philip

Oui, ce serait une mauvaise pratique de l'analyser soi-même. Jetez un oeil à SimpleDateFormat , il transformera la chaîne en date et vous pourrez définir la date comme une instance de calendrier.

3
John Vint

Analyser une heure avec un fuseau horaire, Z dans le modèle correspond au fuseau

String aTime = "2017-10-25T11:39:00+09:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.getDefault());
try {
    Calendar cal = Calendar.getInstance();
    cal.setTime(sdf.parse(aTime));
    Log.i(TAG, "time = " + cal.getTimeInMillis()); 
} catch (ParseException e) {
    e.printStackTrace();
}

Sortie: il retournera l'heure UTC

1508899140000

 enter image description here

Si nous ne définissons pas le fuseau horaire dans un modèle tel que yyyy-MM-dd'T'HH:mm:ss. SimpleDateFormat utilisera le fuseau horaire défini dans Setting

1
Linh

Méthode simple:

public Calendar stringToCalendar(String date, String pattern) throws ParseException {
    String DEFAULT_LOCALE_NAME = "pt";
    String DEFAULT_COUNTRY = "BR";
    Locale DEFAULT_LOCALE = new Locale(DEFAULT_LOCALE_NAME, DEFAULT_COUNTRY);
    SimpleDateFormat format = new SimpleDateFormat(pattern, LocaleUtils.DEFAULT_LOCALE);
    Date d = format.parse(date);
    Calendar c = getCalendar();
    c.setTime(d);
    return c;
}
0