Jak ustawić strefę czasową w Javie.util.Randka?

Parsowałem java.util.Date z String, ale ustawia on lokalną strefę czasową jako strefę czasową obiektu date.

Strefa czasowa nie jest określona w String, z której Date jest przetwarzana. Chcę ustawić określoną strefę czasową date obiektu.

Jak mogę to zrobić?
Author: Matt Johnson, 2010-05-23

8 answers

Użyj DateFormat. Na przykład,

SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = isoFormat.parse("2010-05-23T09:01:02");
 252
Author: ZZ Coder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-08 13:22:33

Należy pamiętać, że obiekty java.util.Date same w sobie nie zawierają żadnych informacji o strefie czasowej - nie można ustawić strefy czasowej na obiekcie Date. Jedyne co zawiera obiekt Date to liczba milisekund od "epoki" - 1 stycznia 1970, 00: 00: 00 UTC.

Jak pokazuje program ZZ Coder, ustawiasz strefę czasową w obiekcie DateFormat, aby określić, w której strefie czasowej chcesz wyświetlić datę i godzinę.

 137
Author: Jesper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-23 14:45:21

Tl;dr

...parsed ... from a String ... time zone is not specified ... I want to set a specific time zone

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.

Brak strefy czasowej w J. U. Data

Jak stwierdzono w innych poprawnych odpowiedziach, java.util.Data nie ma strefy czasowej. Reprezentuje UTC / GMT (bez przesunięcia strefy czasowej). Bardzo mylące, ponieważ jej metoda toString stosuje domyślną strefę czasową JVM podczas generowania reprezentacji łańcuchowej.

Unikaj j. U. Date

Dla z tego i wielu innych powodów należy unikać używania wbudowanej Javy.util.Date & .KALENDARZ & java.tekst.SimpleDateFormat. Są notorycznie kłopotliwe.

Zamiast tego użyj Javy.pakiet czasu w pakiecie z Java 8.

Java.czas

Java.klasy czasu mogą reprezentować moment na osi czasu na trzy sposoby:]}

  • UTC (Instant)
  • z offsetem (OffsetDateTime z ZoneOffset)
  • ze strefą czasową (ZonedDateTime z ZoneId)

Instant

W java.czas , podstawowym budulcem jest Instant, moment na linii czasowej w UTC. Używaj obiektów Instant dla większej części swojej logiki biznesowej.

Instant instant = Instant.now();

OffsetDateTime

Zastosujoffset-from-UTC , aby dostosować się do jakiegoś czasuwall-clock .

Apply a ZoneOffset aby uzyskać OffsetDateTime.

ZoneOffset zoneOffset = ZoneOffset.of( "-04:00" );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );

ZonedDateTime

Lepiej jest zastosować strefę czasową , przesunięcie plus zasady postępowania z anomaliami, takimi jak czas letni (DST) .

Apply a ZoneId do an Instant aby uzyskać ZonedDateTime. Zawsze należy podać właściwą nazwę strefy czasowej . Nigdy nie używaj 3-4 skrótów, takich jak EST lub IST, które nie są ani unikalne, ani standaryzowane.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

LocalDateTime

Jeśli łańcuch wejściowy nie zawiera żadnego wskaźnika offsetu lub strefy, parse as a LocalDateTime.

Jeśli są pewne strefy czasowej, przypisać ZoneId do wytworzenia ZonedDateTime. Zobacz przykład kodu w sekcji TL;dr u góry.

Sformatowane Ciągi

Wywołaj metodę toString na którejkolwiek z tych trzech klas, aby wygenerować ciąg znaków reprezentujący wartość Data-Czas w standardowym formacie ISO 8601. Klasa ZonedDateTime rozszerza standardowy format poprzez dodanie nazwy strefy czasowej w nawiasach.

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]

Dla innych formatów użyj DateTimeFormatter klasy. Ogólnie najlepiej pozwolić tej klasie generować zlokalizowane formaty przy użyciu oczekiwanego przez użytkownika ludzkiego języka i norm kulturowych. Możesz też określić konkretny format.


O java.czas

The java.czas framework jest wbudowany w Java 8 i nowsze. Klasy te zastępują kłopotliwe stare dziedzictwo klasy date-time, takie jak java.util.Date, Calendar, & SimpleDateFormat.

The Joda-czas projekt, obecnie w trybie konserwacji , radzi migrację do java.czas klasy.

Aby dowiedzieć się więcej, Zobacz samouczek Oracle. I wyszukaj przepełnienie stosu dla wielu przykładów i wyjaśnień. Specyfikacja to JSR 310 .

Możesz wymienić Javę.obiekty time bezpośrednio z bazą danych. Użyj sterownika JDBCzgodnego z JDBC 4.2 lub nowszego. Nie ma potrzeby. w przypadku ciągów nie ma potrzeby stosowania klas java.sql.*.

Skąd pobrać Javę.zajęcia czasowe?

The ThreeTen-Extra projekt rozszerza Javę.czas z dodatkowymi zajęciami. Ten projekt jest poligonem dla potencjalnych przyszłych dodatków do Javy.czas. Możesz znaleźć tutaj kilka przydatnych klas, takich jak Interval, YearWeek, YearQuarter, i więcej.


Joda-Czas

While Joda-czas jest nadal aktywnie utrzymywany, jego twórcy nakazali nam migrację do Javy.czas jak najszybciej jest dogodny. Pozostawiam tę sekcję nienaruszoną jako odniesienie, ale sugeruję użycie sekcji java.time powyżej.

In Joda-Time , obiekt date-time(DateTime) naprawdę zna przydzieloną strefę czasową. Oznacza to przesunięcie od UTC i reguł i historii czasu letniego danej strefy czasowej (DST) i innych tego typu anomalii.

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

Wywołanie metody toString aby wygenerować ciąg znaków w formacie ISO 8601 .

String output = dateTimeIndia.toString();

Joda-Time oferuje również bogate możliwości generowania wszelkiego rodzaju innych formatów ciągów.

Jeśli jest to wymagane, możesz przekonwertować z Joda-Time DateTime do Javy.util.Data.

Java.util.Date date = dateTimeIndia.toDate();

Wyszukaj StackOverflow dla "Joda date", aby znaleźć wiele więcej przykładów, niektóre dość szczegółowe.


W rzeczywistości istnieje Strefa czasowa osadzona w Javie.util.Data, używana dla niektórych funkcji wewnętrznych (Zobacz komentarze do tej odpowiedzi). Ale ta wewnętrzna Strefa czasowa nie jest wystawiona jako właściwość i nie może być ustawiona. Ta wewnętrzna Strefa czasowa to , a nie ta używana przez toString metoda w generowaniu łańcuchowej reprezentacji wartości data-czas; zamiast tego bieżąca domyślna Strefa czasowa JVM jest stosowana w locie. Tak więc, jako skrót, często mówimy "j. U. Date nie ma strefy czasowej". Mylące? Tak. Kolejny powód, aby uniknąć tych zmęczonych starych klas.

 61
Author: Basil Bourque,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-29 19:11:32

Możesz również ustawić strefę czasową na poziomie JVM

Date date1 = new Date();
System.out.println(date1);

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
// or pass in a command line arg: -Duser.timezone="UTC"

Date date2 = new Date();
System.out.println(date2);

Wyjście:

Thu Sep 05 10:11:12 EDT 2013
Thu Sep 05 14:11:12 UTC 2013
 60
Author: starmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-08 13:23:55

java.util.Calendar jest zwykłym sposobem obsługi stref czasowych przy użyciu tylko klas JDK. Apache Commons ma inne alternatywy/narzędzia, które mogą być pomocne. Edit notka Sponga przypomniała mi, że słyszałem naprawdę dobre rzeczy o Joda-Time (choć sam z niej nie korzystałem).

 6
Author: T.J. Crowder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-02 10:30:43

Jeśli musisz pracować tylko ze standardowymi klasami JDK możesz użyć tego:

/**
 * Converts the given <code>date</code> from the <code>fromTimeZone</code> to the
 * <code>toTimeZone</code>.  Since java.util.Date has does not really store time zome
 * information, this actually converts the date to the date that it would be in the
 * other time zone.
 * @param date
 * @param fromTimeZone
 * @param toTimeZone
 * @return
 */
public static Date convertTimeZone(Date date, TimeZone fromTimeZone, TimeZone toTimeZone)
{
    long fromTimeZoneOffset = getTimeZoneUTCAndDSTOffset(date, fromTimeZone);
    long toTimeZoneOffset = getTimeZoneUTCAndDSTOffset(date, toTimeZone);

    return new Date(date.getTime() + (toTimeZoneOffset - fromTimeZoneOffset));
}

/**
 * Calculates the offset of the <code>timeZone</code> from UTC, factoring in any
 * additional offset due to the time zone being in daylight savings time as of
 * the given <code>date</code>.
 * @param date
 * @param timeZone
 * @return
 */
private static long getTimeZoneUTCAndDSTOffset(Date date, TimeZone timeZone)
{
    long timeZoneDSTOffset = 0;
    if(timeZone.inDaylightTime(date))
    {
        timeZoneDSTOffset = timeZone.getDSTSavings();
    }

    return timeZone.getRawOffset() + timeZoneDSTOffset;
}

Kredyt idzie do tego post .

 6
Author: diadyne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-22 18:37:00

Jeśli ktoś kiedykolwiek tego potrzebuje, jeśli chcesz przekonwertować strefę czasową XMLGregorianCalendar na bieżącą strefę czasową z UTC, wszystko, co musisz zrobić, to ustawić strefę czasową na 0, a następnie wywołać toGregorianCalendar() - pozostanie ta sama strefa czasowa, ale Date wie, jak przekonwertować ją na swoją, dzięki czemu możesz pobrać dane stamtąd.

XMLGregorianCalendar xmlStartTime = DatatypeFactory.newInstance()
    .newXMLGregorianCalendar(
        ((GregorianCalendar)GregorianCalendar.getInstance());
xmlStartTime.setTimezone(0);
GregorianCalendar startCalendar = xmlStartTime.toGregorianCalendar();
Date startDate = startCalendar.getTime();
XMLGregorianCalendar xmlStartTime = DatatypeFactory.newInstance()
    .newXMLGregorianCalendar(startCalendar);
xmlStartTime.setHour(startDate.getHours());
xmlStartTime.setDay(startDate.getDate());
xmlStartTime.setMinute(startDate.getMinutes());
xmlStartTime.setMonth(startDate.getMonth()+1);
xmlStartTime.setTimezone(-startDate.getTimezoneOffset());
xmlStartTime.setSecond(startDate.getSeconds());
xmlStartTime.setYear(startDate.getYear() + 1900);
System.out.println(xmlStartTime.toString());

Wynik:

2015-08-26T12:02:27.183Z
2015-08-26T14:02:27.183+02:00
 0
Author: EpicPandaForce,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-08 13:22:07

Konwertuj datę na łańcuch znaków i zrób to za pomocą SimpleDateFormat.

    SimpleDateFormat readFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    readFormat.setTimeZone(TimeZone.getTimeZone("GMT" + timezoneOffset));
    String dateStr = readFormat.format(date);
    SimpleDateFormat writeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    Date date = writeFormat.parse(dateStr);
 0
Author: avisper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-18 19:31:59