2008-11-04 4 views
8

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

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 Значение: 10000000

Календарное время в Millis: 10000000

Дата в формате YYYY-MM-DD Формат: 1969-11-31

Long значение: 1000000000000

Календарное время в Миллис: 1000000000000

Дата в формате YYYY-MM-DD: 2001-8-8

ответ

12

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

+2

Спасибо! Я думал, что сойду с ума. – 2008-11-05 00:39:48

0

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

6

Во-первых, 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())); 
} 
+0

Очень полезно; вы ответили на мой вопрос немного косвенно. Вещь часового пояса вызывала у меня большую путаницу.Улучшенный код очень ценится. – 2008-11-05 00:42:44

5

Calendar#setTimeInMillis() устанавливает время календаря на количество миллисекунд после 1 января 1970 GMT.

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

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

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

Спасибо за пример кода. – 2008-11-05 00:40:37

1

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

3

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

 Смежные вопросы

  • Нет связанных вопросов^_^