
В этом руководстве мы покажем вам несколько примеров ( ZonedDateTime (Java 8) , Дата , Календарь и Время Joda ) для преобразования даты и времени между различными часовыми поясами.
Все примеры будут преобразовывать дату и время из
(UTC+8:00) Asia/Singapore - Singapore Time
Date : 22-1-2015 10:15:55 AM
в
(UTC-5:00) America/New_York - Eastern Standard Time
Date : 21-1-2015 09:15:55 PM
Какой использовать?
Для часового пояса избегайте Date а также Calendar
- Если вы используете JDK> = 8, используйте новый
java.time.*фреймворк. - Если вы используете JDK <8, используйте Joda Time. (Новая Java 8
java.time.*рамки вдохновлены этой библиотекой)
1. ZonedDateTime
Всегда используйте эту новую Java 8 java.time.ZonedDateTime представлять дату и время, содержащие часовой пояс.
ZonedDateTimeExample.java
package com.csharpcoderr.date;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class ZonedDateTimeExample {
private static final String DATE_FORMAT = "dd-M-yyyy hh:mm:ss a";
public static void main(String[] args) {
String dateInString = "22-1-2015 10:15:55 AM";
LocalDateTime ldt = LocalDateTime.parse(dateInString, DateTimeFormatter.ofPattern(DATE_FORMAT));
ZoneId singaporeZoneId = ZoneId.of("Asia/Singapore");
System.out.println("TimeZone : " + singaporeZoneId);
// LocalDateTime + ZoneId = ZonedDateTime
ZonedDateTime asiaZonedDateTime = ldt.atZone(singaporeZoneId);
System.out.println("Date (Singapore) : " + asiaZonedDateTime);
ZoneId newYokZoneId = ZoneId.of("America/New_York");
System.out.println("TimeZone : " + newYokZoneId);
ZonedDateTime nyDateTime = asiaZonedDateTime.withZoneSameInstant(newYokZoneId);
System.out.println("Date (New York) : " + nyDateTime);
DateTimeFormatter format = DateTimeFormatter.ofPattern(DATE_FORMAT);
System.out.println("n---DateTimeFormatter---");
System.out.println("Date (Singapore) : " + format.format(asiaZonedDateTime));
System.out.println("Date (New York) : " + format.format(nyDateTime));
}
}
Выход
TimeZone : Asia/Singapore
Date (Singapore) : 2015-01-22T10:15:55+08:00[Asia/Singapore]
TimeZone : America/New_York
Date (New York) : 2015-01-21T21:15:55-05:00[America/New_York]
---DateTimeFormatter---
Date (Singapore) : 22-1-2015 10:15:55 AM
Date (New York) : 21-1-2015 09:15:55 PM
Заметка
Обратитесь к этому учебному пособию ZonedDateTime для получения дополнительных примеров часовых поясов, пользовательских смещений и летнего времени (DST).
2. Дата
Заметка
java.util.Date не имеет понятия часового пояса и представляет только количество секунд, прошедших с начала эпохи Unix — 1970-01-01T00: 00: 00Z. Но если вы печатаете объект Date напрямую, объект Date будет всегда печататься с системным часовым поясом по умолчанию. Проверить Date.toString() исходный код.
2.1 Установите часовой пояс на DateFormat и отформатировать java.util.Date
SimpleDateFormat sdfAmerica = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a");
sdfAmerica.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String sDateInAmerica = sdfAmerica.format(date);
2.2 Полный пример
DateExample.java
package com.csharpcoderr.date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class DateExample {
private static final String DATE_FORMAT = "dd-M-yyyy hh:mm:ss a";
public static void main(String[] args) throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
String dateInString = "22-01-2015 10:15:55 AM";
Date date = formatter.parse(dateInString);
TimeZone tz = TimeZone.getDefault();
// Из TimeZone Азия / Сингапур
System.out.println("TimeZone : " + tz.getID() + " - " + tz.getDisplayName());
System.out.println("TimeZone : " + tz);
System.out.println("Date (Singapore) : " + formatter.format(date));
// В TimeZone America / New_York
SimpleDateFormat sdfAmerica = new SimpleDateFormat(DATE_FORMAT);
TimeZone tzInAmerica = TimeZone.getTimeZone("America/New_York");
sdfAmerica.setTimeZone(tzInAmerica);
String sDateInAmerica = sdfAmerica.format(date); // Сначала преобразуем в строку
Date dateInAmerica = formatter.parse(sDateInAmerica); // Создать новый объект Date
System.out.println("nTimeZone : " + tzInAmerica.getID() + " - " + tzInAmerica.getDisplayName());
System.out.println("TimeZone : " + tzInAmerica);
System.out.println("Date (New York) (String) : " + sDateInAmerica);
System.out.println("Date (New York) (Object) : " + formatter.format(dateInAmerica));
}
}
Выход
TimeZone : Asia/Kuala_Lumpur - Malaysia Time
TimeZone : sun.util.calendar.ZoneInfo[id="Asia/Kuala_Lumpur",...]
Date (Singapore) : 22-1-2015 10:15:55 AM
TimeZone : America/New_York - Eastern Standard Time
TimeZone : sun.util.calendar.ZoneInfo[id="America/New_York",...]
Date (New York) (String) : 21-1-2015 09:15:55 PM
Date (New York) (Object) : 21-1-2015 09:15:55 PM
3. Календарь
3.1 Пример календаря для установки часового пояса:
Calendar calendar = new GregorianCalendar();
calendar.setTime(date);
calendar.setTimeZone(tzInAmerica);
Супер распространенная ошибка, чтобы получить java.util.Date прямо так:
// Неправильно, будет отображаться 22-1-2015 10:15:55, время все еще находится в часовом поясе системы по умолчанию!
Date dateInAmerican = calendar.getTime());
В приведенном выше примере, независимо от того, какой часовой пояс вы установили в Календаре, объект Date будет всегда печататься с системным часовым поясом по умолчанию. (Проверить Date.toString() исходный код)
3.2 Правильным способом должно быть использование DateFormat отформатировать это:
SimpleDateFormat sdfAmerica = new SimpleDateFormat("dd-M-yyyy hh:mm:ss a");
TimeZone tzInAmerica = TimeZone.getTimeZone("America/New_York");
sdfAmerica.setTimeZone(tzInAmerica);
sdfAmerica.format(calendar.getTime())
или получить дату через calendar.get() :
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH); // Jan = 0, dec = 11
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
int hour = calendar.get(Calendar.HOUR); // 12 часовые часы
int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY); // 24 часовые часы
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
int ampm = calendar.get(Calendar.AM_PM); // 0 = AM, 1 = PM
3.3 Полный пример
CalendarExample.java
package com.csharpcoderr.date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class CalendarExample {
private static final String DATE_FORMAT = "dd-M-yyyy hh:mm:ss a";
public static void main(String[] args) throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
String dateInString = "22-01-2015 10:15:55 AM";
Date date = formatter.parse(dateInString);
TimeZone tz = TimeZone.getDefault();
// Из TimeZone Азия / Сингапур
System.out.println("TimeZone : " + tz.getID() + " - " + tz.getDisplayName());
System.out.println("TimeZone : " + tz);
System.out.println("Date (Singapore) : " + formatter.format(date));
// В TimeZone America / New_York
SimpleDateFormat sdfAmerica = new SimpleDateFormat(DATE_FORMAT);
TimeZone tzInAmerica = TimeZone.getTimeZone("America/New_York");
sdfAmerica.setTimeZone(tzInAmerica);
Calendar calendar = new GregorianCalendar();
calendar.setTime(date);
calendar.setTimeZone(tzInAmerica);
System.out.println("nTimeZone : " + tzInAmerica.getID() + " - " + tzInAmerica.getDisplayName());
System.out.println("TimeZone : " + tzInAmerica);
//Неправильно! Будет напечатана дата с часовым поясом системы по умолчанию.
System.out.println("Date (New York) (Wrong!): " + calendar.getTime());
//Правильный! нужен форматер
System.out.println("Date (New York) (Correct!) : " + sdfAmerica.format(calendar.getTime()));
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH); // Jan = 0, dec = 11
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
int hour = calendar.get(Calendar.HOUR); // 12 часовые часы
int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY); // 24 часовые часы
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
int ampm = calendar.get(Calendar.AM_PM); // 0 = AM, 1 = PM
//Правильный
System.out.println("nyear tt: " + year);
System.out.println("month tt: " + month + 1);
System.out.println("dayOfMonth t: " + dayOfMonth);
System.out.println("hour tt: " + hour);
System.out.println("minute tt: " + minute);
System.out.println("second tt: " + second);
System.out.println("ampm tt: " + ampm);
}
}
Выход
TimeZone : Asia/Kuala_Lumpur - Malaysia Time
TimeZone : sun.util.calendar.ZoneInfo[id="Asia/Kuala_Lumpur",...]
Date (Singapore) : 22-1-2015 10:15:55 AM
TimeZone : America/New_York - Eastern Standard Time
TimeZone : sun.util.calendar.ZoneInfo[id="America/New_York",...]]
Date (New York) (Wrong!): Thu Jan 22 10:15:55 MYT 2015
Date (New York) (Correct!) : 21-1-2015 09:15:55 PM
year : 2015
month : 01
dayOfMonth : 21
hour : 9
minute : 15
second : 55
ampm : 1
4. Время Йода
4.1 Пример Joda Time для установки часового пояса:
DateTime dt = new DateTime(date);
DateTimeZone dtZone = DateTimeZone.forID("America/New_York");
DateTime dtus = dt.withZone(dtZone);
Опять же, распространенной ошибкой является прямое получение Даты, такой как часовой пояс будет потерян.
// Вывод: 22-1-2015 10:15:55
Date dateInAmerica = dtus.toDate();
Правильный путь преобразуется в Йода LocalDateTime первый.
// Вывод: 21-1-2015 09:15:55
Date dateInAmerica = dtus.toLocalDateTime().toDate();
4.2 Полный пример
JodaTimeExample.java
package com.csharpcoderr.date;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class JodaTimeExample {
private static final String DATE_FORMAT = "dd-M-yyyy hh:mm:ss a";
public static void main(String[] args) throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
String dateInString = "22-01-2015 10:15:55 AM";
Date date = formatter.parse(dateInString);
TimeZone tz = TimeZone.getDefault();
// Из TimeZone Азия / Сингапур
System.out.println("TimeZone : " + tz.getID() + " - " + tz.getDisplayName());
System.out.println("TimeZone : " + tz);
System.out.println("Date (Singapore) : " + formatter.format(date));
// В TimeZone America / New_York
SimpleDateFormat sdfAmerica = new SimpleDateFormat(DATE_FORMAT);
DateTime dt = new DateTime(date);
DateTimeZone dtZone = DateTimeZone.forID("America/New_York");
DateTime dtus = dt.withZone(dtZone);
TimeZone tzInAmerica = dtZone.toTimeZone();
Date dateInAmerica = dtus.toLocalDateTime().toDate(); // Сначала конвертируем в LocalDateTime
sdfAmerica.setTimeZone(tzInAmerica);
System.out.println("nTimeZone : " + tzInAmerica.getID() + " - " + tzInAmerica.getDisplayName());
System.out.println("TimeZone : " + tzInAmerica);
System.out.println("DateTimeZone : " + dtZone);
System.out.println("DateTime : " + dtus);
System.out.println("dateInAmerica (Formatter) : " + formatter.format(dateInAmerica));
System.out.println("dateInAmerica (Object) : " + dateInAmerica);
}
}
Выход
TimeZone : Asia/Kuala_Lumpur - Malaysia Time
TimeZone : sun.util.calendar.ZoneInfo[id="Asia/Kuala_Lumpur",...]
Date (Singapore) : 22-1-2015 10:15:55 AM
TimeZone : America/New_York - Eastern Standard Time
TimeZone : sun.util.calendar.ZoneInfo[id="America/New_York",...]
DateTimeZone : America/New_York
DateTime : 2015-01-21T21:15:55.000-05:00
dateInAmerica (Formatter) : 21-1-2015 09:15:55 PM
dateInAmerica (Object) : Wed Jan 21 21:15:55 MYT 2015
PS Протестировано с Joda-time 2.9.4
Рекомендации
- Манипуляции с датой и временем в Java с использованием JodaTime
- Мировой сервер времени
- Java 8 — примеры ZonedDateTime
- Java 8 — преобразование даты в LocalDate и LocalDateTime
- ZonedDateTime Javadoc
- Календарь JavaDoc
- Дата JavaDoc
- SimpledateFormat JavaDoc
календарная дата йода время время часовой пояс zoneddatetime
0.00 (0%) 0 votes






