Arhn - архитектура программирования

Поле ДАТА календаря не обновляется

Я работаю над кодом, учитывающим разницу в часовых поясах (в данном случае — преобразование даты из UTC в EST/EDT), и заметил, что получаю неверное поле DATE из переменной Calendar.

Вот выдержки из журнала смены часового пояса:

UTC time: Fri Nov 15 00:28:44 EST 2013
America/New_York time: Thu Nov 14 19:28:44 EST 2013

Код правильно обновляет время до 14-го, основываясь на том, что отображается с Calendar.getTime(), но когда я вызываю Calendar.get(Calendar.DATE), я все еще получаю 15 в качестве даты.

Почему поля не обновляются, когда само время?


Выдержка из кода:

Calendar cal = Calendar.getInstance();
cal.setTime(new Date());

TimeZone fromTz = TimeZone.getTimeZone("UTC");
TimeZone toTz = TimeZone.getTimeZone("America/New_York");

jlog.info(fromTz.getID() + " time: " + cal.getTime().toString());

cal.setTimeZone(fromTz);
// Finds the difference between the two timezones based on their offset from UTC (in the case of the system timezone changing in the future).
long currentTime = System.currentTimeMillis();
int timeDifference = toTz.getOffset(currentTime) - fromTz.getOffset(currentTime);

cal.add(Calendar.MILLISECOND, timeDifference);

if (dst) { // Logic for determining whether or not the extra hour for DST is needed.
  cal.add(Calendar.MILLISECOND, fromTz.getDSTSavings());
}

jlog.info(toTz.getID() + " time: " + cal.getTime().toString());

jlog.info(cal.getTime().toString() + " - " + cal.get(Calendar.DATE));

Вывод приведенного выше кода:

UTC time: Fri Nov 15 00:28:44 EST 2013
America/New_York time: Thu Nov 14 19:28:44 EST 2013
Thu Nov 14 19:28:44 EST 2013 - 15

ПРИМЕЧАНИЕ. Пожалуйста, не предлагайте мне использовать Joda-time. Я просто ищу ответ на этот вопрос как есть.

Если это не разрешимо, потому что Calendar/Date - ужасные пакеты, это нормально - я просто сам проанализирую дату, чтобы получить правильные значения. Заранее спасибо.

12.05.2014

Ответы:


1

Вы не показали нам достаточно кода, чтобы понять, что происходит, но ваш вывод очень легко объяснить: вы вызываете Date.toString(), который всегда форматирует момент времени, используя локальный системный часовой пояс. Часовой пояс в объекте Calendar значения не имеет.

Таким образом, похоже, что ваш Calendar может быть, например, в формате UTC, и в этом случае день будет 15.

Обратите внимание, что первая строка вашего журнала явно ерунда:

UTC time: Fri Nov 15 00:28:44 EST 2013

Это либо UTC, либо EST. Не может быть и того, и другого.

Непонятно, откуда берутся ваши данные или как именно вы с ними работаете, но если вы вручную корректируете дату/время, добавляя или вычитая части, вы почти наверняка делаете это неправильно. . Очень важно понимать, что java.util.Date не имеет представления о часовом поясе как части своих данных — это просто момент времени.

Чтобы отформатировать Date в определенном часовом поясе, вы обычно используете SimpleDateFormat и указываете на нем часовой пояс. Например:

DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
format.setTimeZone(TimeZone.getTimeZone("America/New_York"));
System.out.println("The time in New York is " + format.format(new Date()));

РЕДАКТИРОВАТЬ: теперь, когда мы увидели ваш код, вы определенно не должны не делать что-то таким образом. Вы настраиваете момент времени, а это не то, что вам нужно — вы просто хотите изменить свое представление в один и тот же момент времени, что может быть достигнуто с помощью Calendar.setTimeZone, чтобы изменить то, что возвращает Calendar.get. , и используя DateFormat.setTimeZone для изменения часового пояса, используемого для синтаксического анализа/форматирования текста.

12.05.2014
  • Извините за отсутствие разъяснений. Код тестируется в среде по американскому/нью-йоркскому времени, но я установил TimeZone в UTC, чтобы посмотреть, как он будет выглядеть, когда он будет развернут в среде по времени UTC. Вот почему в выходных данных Date.toString() указано EST, но преобразование все равно происходит. Я обновлю вопрос с дополнительной информацией. 12.05.2014
  • @LeMazing: Какая конверсия? Вы не рассказали нам подробностей о том, что вы пытаетесь сделать, и не показали нам код, который вы используете для этого. 12.05.2014
  • Добавил код и подробности. Я не знал, что DateFormat позаботится о часовых поясах сам по себе, иначе я бы просто использовал это. Но я попробовал, и это работает, так что я уберу текущий код. Спасибо за вашу помощь. Мне все еще интересно, почему Calendar.getTime() и Calendar.get(Calendar.DATE) конфликтуют, но это не имеет значения, когда DateFormat.format() работает так хорошо. 12.05.2014
  • @LeMazing: Это потому, что Calendar.get(Calendar.DATE()) использует часовой пояс календаря, тогда как Calendar.getTime() возвращает момент времени, который затем форматируется с учетом вашего местного часового пояса. Вот и все. Вы не должны абсолютно использовать свой текущий код, настраивая часовой пояс вручную. Вы в основном меняете базовый момент времени. 12.05.2014

  • 2

    java.время

    API даты и времени java.util и их API форматирования SimpleDateFormat устарели и подвержены ошибкам. Рекомендуется полностью прекратить их использование и перейти на современный API даты и времени*.

    Решение с использованием java.time, современного API даты и времени:

    import java.time.LocalDate;
    import java.time.LocalTime;
    import java.time.ZoneId;
    import java.time.ZonedDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.Locale;
    
    public class Main {
        public static void main(String[] args) {
            ZonedDateTime zdtUtc = ZonedDateTime.of(LocalDate.of(2013, 11, 15), LocalTime.of(0, 28, 44),
                    ZoneId.of("Etc/UTC"));
    
            ZonedDateTime zdtNewYork = zdtUtc.withZoneSameInstant(ZoneId.of("America/New_York"));
    
            System.out.println(zdtNewYork);
    
            // Custom format
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z uuuu", Locale.ENGLISH);
            System.out.println(zdtNewYork.format(dtf));
        }
    }
    

    Вывод:

    2013-11-14T19:28:44-05:00[America/New_York]
    Thu Nov 14 19:28:44 EST 2013
    

    ОНЛАЙН-ДЕМО

    Узнайте больше о современном API Date-Time на странице Trail: Date Time< /а>.


    * По какой-либо причине, если вам нужно придерживаться Java 6 или Java 7, вы можете использовать ThreeTen-Backport, который переносит большую часть функций java.time на Java 6 и 7. Если вы работаете над проектом Android и ваш уровень Android API по-прежнему не соответствует Java-8, проверьте Java 8+ API доступно через дешугаринг и Как использовать ThreeTenABP в Android Project.

    04.07.2021

    3

    Если я понимаю ваш вопрос, вы можете сделать это примерно так:

    Calendar c = Calendar.getInstance();
    DateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy",
            Locale.ENGLISH);
    formatter.setTimeZone(TimeZone.getTimeZone("UTC")); // <-- Set the timezone on the
                                                        // DateFormat
    /* Your input date/time */
    c.setTime(new GregorianCalendar(2013, 10, 15, 0, 28, 44).getTime());
    
    System.out.println(formatter.format(c.getTime()));
    c.setTimeZone(TimeZone.getTimeZone("EST"));
    System.out.println(c.getTime());
    

    Вывод этого кода

    Fri Nov 15 05:28:44 UTC 2013
    Fri Nov 15 00:28:44 EST 2013
    
    12.05.2014
  • Привет, Эллиот Фриш. Пожалуйста, внесите два изменения в свой ответ: (1) Замените YYYY на yyyy (2) Используйте Locale.ENGLISH на SimpleDateFormat, например. этот ответ объясняет, почему это важно. 04.07.2021
  • @ArvindKumarAvinash Отредактировано. Солидный совет. 7-летний ответ, хотя. 04.07.2021
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..


    © 2024 arhn.ru, Arhn - архитектура программирования