Правильный номер Answer by Erwin Smout.
Вот пример кода для всех трех ваших случаев и обсуждения.
Тип базы данных TIMESTAMP WITH TIME ZONE
Ваша база данных столбец таблицы должен быть определен в качестве стандартного SQL типа TIMESTAMP WITH TIME ZONE
(не WITHOUT
). Или что-то подобное в зависимости от вашей базы данных. Поддержка даты-времени варьируется от до между слабыми (SQLite) и надежными (Postgres).
Практически все базы данных фактически сохраняют значения даты и времени в UTC (если они вообще соблюдают часовые пояса). Некоторые сохраняют информацию о часовом поясе, переданную с входными значениями, в то время как некоторые, такие как Postgres, отбрасывают эту информацию после ее использования для настройки значения в формате UTC.
Думают, работа и магазин в UTC
Ваш бизнес-логики и хранения данных должны быть в формате UTC. Таким образом, в UTC есть только одно фактическое время полета. Для различных представительств в Мексике, Сингапуре и Великобритании мы применяем различные временные зоны для перехода на/из значения UTC.
Сервер Ненужные
Расположение сервера в центральной части США должны быть неуместны. Во-первых, серверы должны быть всегда настроены на UTC (или Исландия) для своего часового пояса.Во-вторых, вы должны никогда не зависеть от этого параметра, так как это внешность вне вашего контроля и слишком жутко легко меняться - даже во время работы! Вместо этого всегда указывайте желаемый/ожидаемый часовой пояс в качестве аргументов в коде.
java.time
Всегда используйте java.time классы, никогда java.util.Date
/.Calendar
/java.text.SimpleDateFormat
классы.
java.sql
Получить время полета из базы данных в качестве java.sql.Timestamp
, которая находится в UTC по определению.
java.sql.Timestamp ts = myResultSet.getTimestamp(…);
В рамках старых проблемных классов даты и времени, свести к минимуму использование типов java.sql. Немедленно конвертируйте в классы java.time. Instant
- это момент на временной шкале в UTC с разрешением наносекунды.
Instant instant = ts.toInstant();
Обратите внимание, что все движущиеся части находятся в формате UTC: хранение базы данных, JDBC, java.sql.Timestamp
и Instant
. Никаких часовых поясов вообще не возникает.
Adjust для México
Для клиента в Мексике, применить часовой пояс, они выбирают или что вы предполагаете, является целесообразным.
ZoneId zdt_America_MexicoCity = ZoneId.of("America/Mexico_City");
ZonedDateTime zdt_America_MexicoCity = ZonedDateTime.ofInstant(instant , zdt_America_MexicoCity);
Поиск Переполнение стека для получения информации о генерации строк, которые автоматически локализованы на человеческий язык и культурные нормы, используя DateTimeFormatter
класс и его ofLocalized…
методы.
Adjust для Сингапура
Ditto для клиента в Сингапуре.
ZoneId zdt_Asia_Singapore = ZoneId.of("Asia/Singapore");
ZonedDateTime zdt_Asia_Singapore = ZonedDateTime.ofInstant(instant , zdt_Asia_Singapore);
Все три объекта, наша instant
и пара ZonedDateTime
объектов, представляют собой же одновременно момент на временной шкале.
Adjust для UTC
Для лица сотрудников авиакомпании, работающих в формате UTC, используйте Instant
если все, что нужно для текстового представления является ISO 8601 с 0, 3, 6 или 9 знака после запятой цифры для доли второй.
String output = instant.toString();
Если вам нужны другие форматы, как текстовое представление, используйте java.time.format пакет после преобразования Instant
к более гибко отформатированный OffsetDateTime
класса. Обратите внимание на использование constant for UTC, хранящегося в подклассе ZoneId
, ZoneOffset
.
OffsetDateTime odt = OffsetDateTime.ofInstant(instant , ZoneOffset.UTC);
Настройка входных данных
Если пользователь ввода полетного времени в часовом поясе Великобритании, подстраиваться UTC впоследствии. Кстати, не путайте время Великобритании с UTC. Лондонское время изменилось по истории, в настоящее время меняется с летним временем, в то время как UTC никогда не меняется (кроме leap seconds).
ZoneId zoneId_Europe_London = ZoneId.of("Europe/London");
ZonedDateTime zdt = ZonedDateTime(2016 , 1 , 3 , 9 , 0 , 0 , 0 , zoneId_Europe_London);
Instant instant = zdt.toInstant();
java.sql.Timestamp ts = java.sql.Timestamp.from(instant);
Местный
Этот ответ относится к конкретным моментам, на определенную дату и время-день. Если вы имели в виду время полета в смысле «9 AM» на часах на стене, которые могут перемещаться из-за аномалий, включая летнее время (DST), тогда это будет другое обсуждение. В вопросе говорится, что пользователь вводит определенную дату и определенное время, поэтому применяется вышеприведенное обсуждение.
См. Подобные вопросы [здесь] (http://stackoverflow.com/q/33343893/642706) и [здесь] (http://stackoverflow.com/q/2532729/642706). –