Cum se schimbă FONDUL ORAR pentru un java.util.Calendar/Date (Programare, Java, Datetime, Calendar)

Kanagavelu Sugumar a intrebat.

Aș dori să schimb valoarea TIMEZONE într-o instanță Java Calendar în timpul execuției. am încercat mai jos. Dar rezultatul este același în ambele instanțe:

    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());

OUTPUT:
1353402486773
1353402486773

Am încercat și acest lucru, dar rezultatul este același:

    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());

În API văd comentariul de mai jos, dar nu reușesc să înțeleg mare lucru din el:

     * 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().

Puteți să mă ajutați, vă rog?

O posibilă soluție :

    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);

Este această soluție în regulă?

Comentarii

  • Posibil duplicat al stackoverflow.com/questions/7670355/ – –  > Por KeyNone.
  • @BastiM linkul dă soluția; numai dacă știm valoarea offset-ului. Eu nu vreau asta, deoarece am doar valoarea fusului orar. Puteți să-mi spuneți, vă rog, care este greșeala de mai sus? sau Soluția? –  > Por Kanagavelu Sugumar.
  • Ce vă așteptați să se întâmple? Ambele Calendar obiecte se referă la același timp absolut de la epocă. Acesta este un comportament corect. –  > Por augurar.
2 răspunsuri
KeyNone

În Java, Datele sunt reprezentate intern în milisecunde UTC de la epoca (deci nu se ține cont de fusurile orare, de aceea obțineți aceleași rezultate, ca și getTime() îți dă milisecundele menționate).
În soluția dvs:

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);

trebuie doar să adăugați decalajul de la GMT la fusul orar specificat („Asia/Calcutta” în exemplul dvs.) în milisecunde, deci ar trebui să funcționeze bine.

O altă soluție posibilă ar fi utilizarea câmpurilor statice ale fișierului Calendar clasă:

//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);

Consultați stackoverflow.com/questions/7695859/ pentru o explicație mai detaliată.

Comentarii

  • Prima jumătate a acestui răspuns este complet greșită. Milisecundele de la epocă specifică un punct absolut în timp, fără informații despre fusul orar. Ajustarea milisecundei de timp a calendarului va schimba calendarul pentru a reprezenta un punct diferit în timp. În mod clar, OP dorește să reprezinte același punct absolut în timp, în diferite fusuri orare. –  > Por augurar.
  • Ceea ce a spus @augurar. De asemenea, pentru cei care doar copiază și lipesc a doua parte a răspunsului, fiți atenți că nu toate fusurile orare sunt decalate cu ore întregi. –  > Por Roy Solberg.
  • De asemenea, ar trebui să includeți utilizarea metodei getDSTSavings() TimeZone pentru a vă asigura că ora de vară este luată în considerare. –  > Por dazed.
  • fiți atenți la faptul că getRawOffset() nu ia în considerare regulile de economisire a luminii zilei. –  > Por behzad.
Kanagavelu Sugumar
  1. Clasa Date/Timestamp reprezintă un anumit moment în timp, cu o precizie de milisecunde, începând cu 1 ianuarie 1970, 00:00:00 GMT. Astfel, această diferență de timp (de la epocă la ora actuală) va fi aceeași în toate computerele din întreaga lume, indiferent de fusul orar.

  2. Date/Timestamp nu știe despre ora dată este pe ce fus orar.

  3. Dacă dorim ca ora să se bazeze pe fusul orar, ar trebui să folosim clasele Calendar sau SimpleDateFormat din java.

  4. Dacă încercați să imprimați un obiect Data/Timestamp utilizând toString(), acesta va converti și va imprima ora în funcție de fusul orar implicit al mașinii dumneavoastră.

  5. Astfel, putem spune că obiectul (Date/Timestamp).getTime() va avea întotdeauna UTC (ora în milisecunde).

  6. În concluzie Date.getTime() va da ora UTC, dar toString() este pe fusul orar specific localității, nu UTC.

Acum, cum voi crea/modifica ora pe un anumit fus orar?

Codul de mai jos vă oferă o dată (timp în milisecunde) cu fusurile orare specificate. Singura problemă aici este că trebuie să dați data în format șir de caractere.

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

Utilizați dateFormat.format pentru a primi Date (care este întotdeauna UTC), fusul orar și a returna data sub forma unui șir de caractere.

Cum se stochează ora UTC/GMT în BD:

Dacă imprimați parsedDate ora va fi în fusul orar implicit, dar puteți stoca ora UTC în baza de date, după cum urmează.

        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);
        }