Java.util.Calendar - миллисекунды с 1 января 1970 г

Программа с последующим выводом. Кто-нибудь, пожалуйста, объясните мне, почему 10 000 000 миллисекунд с 1 января 1970 года равняются 31 ноября 1969 года. Кто-нибудь, пожалуйста, объясните, что не так с моим предположением о том, что первый тест должен дать время в 10 000 000 миллисекунд с 1 января 1970 года. Числа меньше 10 000 000 дают тот же результат.

public static void main(String[] args) {

    String x = "10000000";
    long l = new Long(x).longValue();
    System.out.println("Long value: " + l);

    Calendar c = new GregorianCalendar();
    c.setTimeInMillis(l);
    System.out.println("Calendar time in Millis: " + c.getTimeInMillis());

    String origDate = c.get(Calendar.YEAR) + "-" + c.get(Calendar.MONTH) + "-" + c.get(Calendar.DAY_OF_MONTH);  
    System.out.println("Date in YYYY-MM-DD format: " + origDate);

    x = "1000000000000";
    l = new Long(x).longValue();
    System.out.println("\nLong value: " + l);

    c.setTimeInMillis(l);
    System.out.println("Calendar time in Millis: " + c.getTimeInMillis());

    origDate = c.get(Calendar.YEAR) + "-" + c.get(Calendar.MONTH) + "-" + c.get(Calendar.DAY_OF_MONTH);  
    System.out.println("Date in YYYY-MM-DD format: " + origDate);
}

Long value: 10000000

Calendar time in Millis: 10000000

Date in YYYY-MM-DD format: 1969-11-31

Long value: 1000000000000

Calendar time in Millis: 1000000000000

Date in YYYY-MM-DD format: 2001-8-8

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
8
0
38 681
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Вы можете разобраться сами, если поменяете свой первый c.setTimeInMillis(l); на c.clear();

Ответ принят как подходящий

Даты, которые вы печатаете из Calendar, являются локальными для вашего часового пояса, тогда как эпоха определяется как полночь 01.01.1970 по всемирному координированному времени. Итак, если вы живете в часовом поясе к западу от UTC, тогда ваша дата будет отображаться как 1969-12-31, хотя (в UTC) это все еще 1970-01-01.

Во-первых, c.get(Calendar.MONTH) возвращает 0 для января, 1 для февраля и т. д.

Во-вторых, используйте DateFormat для вывода дат.

В-третьих, ваши проблемы - отличный пример того, насколько неудобен Java Date API. По возможности используйте Joda Time API. Это сделает вашу жизнь несколько проще.

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

public static void main(String[] args) {

    final DateFormat dateFormat = SimpleDateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);

    long l = 10000000L;
    System.out.println("Long value: " + l);
    Calendar c = new GregorianCalendar();
    c.setTimeInMillis(l);
    System.out.println("Date: " + dateFormat.format(c.getTime()));

    l = 1000000000000L;
    System.out.println("\nLong value: " + l);
    c.setTimeInMillis(l);
    System.out.println("Date: " + dateFormat.format(c.getTime()));
}

Очень полезно; Вы ответили на мой вопрос немного косвенно. Больше всего меня смутил часовой пояс. Мы очень ценим улучшенный код.

Nathan Spears 05.11.2008 03:42

Календарь # setTimeInMillis () устанавливает время календаря равным количеству миллисекунд после 1 января 1970 г. время по Гринвичу.

Календарь # get () возвращает запрошенное поле с поправкой на часовой пояс календаря, который по умолчанию равен часовой пояс вашего компьютера.

Это должно работать так, как вы ожидаете, если вы укажете часовой пояс «GMT» при создании календаря:

Calendar c = new GregorianCalendar(TimeZone.getTimeZone("GMT"));

Ваш часовой пояс, скорее всего, отстает от GMT (например, GMT-5), поэтому 10 000 000 мс от эпохи - это 31 декабря 1969 года в вашем часовом поясе, но поскольку в java.util.Calendar месяцы отсчитываются от нуля, преобразование Calendar в текст некорректно, и вы получаете 1969-11-31 вместо ожидаемого 1969-12-31.

К сожалению, java.util.Date и java.util.Calendar были плохо спроектированы, что привело к такого рода путанице.

Другие вопросы по теме