web-dev-qa-db-fra.com

Comment changer TIMEZONE pour un Java.util.Calendar / Date

Je voudrais changer la valeur TIMEZONE dans une instance de Java Calendar à l'exécution. J'ai essayé ci-dessous. Mais le résultat est le même dans les deux cas:

    Calendar cSchedStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
    System.out.println(cSchedStartCal.getTime().getTime());
    cSchedStartCal.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta"));
    System.out.println(cSchedStartCal.getTime().getTime());

SORTIE:
1353402486773
1353402486773

J'ai essayé cela aussi mais la sortie est toujours la même:

    Calendar cSchedStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
    System.out.println(cSchedStartCal.getTime());

    Calendar cSchedStartCal1 = Calendar.getInstance(TimeZone.getTimeZone("Asia/Calcutta"));
    cSchedStartCal1.setTime(cSchedStartCal.getTime());
    System.out.println(cSchedStartCal.getTime());

Dans l'API, je vois le commentaire ci-dessous mais je ne peux pas en comprendre beaucoup:

     * calls: cal.setTimeZone(EST); cal.set(HOUR, 1); cal.setTimeZone(PST).
     * Is cal set to 1 o'clock EST or 1 o'clock PST?  Answer: PST.  More
     * generally, a call to setTimeZone() affects calls to set() BEFORE AND
     * AFTER it up to the next call to complete().

Pourriez-vous m'aider s'il vous plait?

Une solution possible:

    Calendar cSchedStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
    long gmtTime = cSchedStartCal.getTime().getTime();

    long timezoneAlteredTime = gmtTime + TimeZone.getTimeZone("Asia/Calcutta").getRawOffset();
    Calendar cSchedStartCal1 = Calendar.getInstance(TimeZone.getTimeZone("Asia/Calcutta"));
    cSchedStartCal1.setTimeInMillis(timezoneAlteredTime);

Cette solution est-elle acceptable?

38
Kanagavelu Sugumar

En Java, les dates sont représentées de manière interne en millisecondes UTC depuis l'époque (donc les fuseaux horaires ne sont pas pris en compte, c'est pourquoi vous obtenez les mêmes résultats, puisque getTime() vous donne les millisecondes mentionnées).
Dans votre solution:

Calendar cSchedStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
long gmtTime = cSchedStartCal.getTime().getTime();

long timezoneAlteredTime = gmtTime + TimeZone.getTimeZone("Asia/Calcutta").getRawOffset();
Calendar cSchedStartCal1 = Calendar.getInstance(TimeZone.getTimeZone("Asia/Calcutta"));
cSchedStartCal1.setTimeInMillis(timezoneAlteredTime);

vous ajoutez simplement le décalage de GMT au fuseau horaire spécifié ("Asie/Calcutta" dans votre exemple) en millisecondes, cela devrait donc fonctionner correctement.

Une autre solution possible consisterait à utiliser les champs statiques de la classe Calendar:

//instantiates a calendar using the current time in the specified timezone
Calendar cSchedStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
//change the timezone
cSchedStartCal.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta"));
//get the current hour of the day in the new timezone
cSchedStartCal.get(Calendar.HOUR_OF_DAY);

Reportez-vous à stackoverflow.com/questions/7695859/ ) pour une explication plus détaillée.

47
Basti M
  1. La classe Date/Timestamp Représente un instant spécifique dans le temps, avec une précision de l'ordre de la milliseconde, depuis le 1er janvier 1970 à 00:00:00 GMT. Donc, cette différence de temps (d’époque à l’heure actuelle) sera la même sur tous les ordinateurs du monde, quel que soit le fuseau horaire.

  2. Date/Timestamp Ne sait pas à quel moment donné correspond à quel fuseau horaire.

  3. Si nous voulons que l'heure soit basée sur le fuseau horaire, nous devrions utiliser les classes Calendar ou SimpleDateFormat en Java.

  4. Si vous essayez d'imprimer un objet Date/Horodatage à l'aide de toString(), le programme convertira et imprimera l'heure avec le fuseau horaire par défaut de votre appareil.

  5. On peut donc dire que (Date/Timestamp) .getTime () aura toujours UTC (time in milliseconds)

  6. Pour conclure, Date.getTime() donnera l'heure UTC, mais toString() se trouve sur le fuseau horaire spécifique à l'environnement local, pas à l'heure UTC.

Maintenant, comment vais-je créer/changer l'heure sur le fuseau horaire spécifié?

Le code ci-dessous vous donne une date (heure en millisecondes) avec les fuseaux horaires spécifiés. Le seul problème ici est que vous devez donner la date au format chaîne.

   DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
   dateFormatLocal.setTimeZone(timeZone);
   Java.util.Date parsedDate = dateFormatLocal.parse(date);

Utilisez dateFormat.format Pour prendre en entrée la date (qui est toujours UTC), le fuseau horaire et la date de retour sous forme de chaîne.

Comment stocker l'heure UTC/GMT dans la base de données:

Si vous imprimez l'objet parsedDate, l'heure sera dans le fuseau horaire par défaut. Mais vous pouvez stocker l'heure UTC dans la base de données comme ci-dessous.

        Calendar calGMT = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        Timestamp tsSchedStartTime = new Timestamp (parsedDate.getTime());
        if (tsSchedStartTime != null) {
            stmt.setTimestamp(11, tsSchedStartTime, calGMT );
        } else {
            stmt.setNull(11, Java.sql.Types.DATE);
        }
15
Kanagavelu Sugumar