Date.getTime() не включая время?

Не могу понять, почему происходит следующее:

String date = "06-04-2007 07:05";
SimpleDateFormat fmt = new SimpleDateFormat("MM-dd-yyyy HH:mm");
Date myDate = fmt.parse(date); 

System.out.println(myDate);  //Mon Jun 04 07:05:00 EDT 2007
long timestamp = myDate.getTime();
System.out.println(timestamp); //1180955100000 -- where are the milliseconds?

// on the other hand...

myDate = new Date();
System.out.println(myDate);  //Tue Sep 16 13:02:44 EDT 2008
timestamp = myDate.getTime();
System.out.println(timestamp); //1221584564703 -- why, oh, why?

9 ответов

Решение

Какие миллисекунды? В первом примере вы предоставляете информацию только по минутам, в то время как ваш второй пример захватывает текущую дату из системы за миллисекунды, что вы ищете?

String date = "06-04-2007 07:05:00.999";
SimpleDateFormat fmt = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss.S");
Date myDate = fmt.parse(date);

System.out.println(myDate); 
long timestamp = myDate.getTime();
System.out.println(timestamp);

Потому что указанный вами простой формат даты отбрасывает миллисекунды. Таким образом, полученный объект Date не имеет этой информации. Поэтому, когда вы распечатываете, все 0.

С другой стороны, объект Date сохраняет миллисекунды, когда вы присваиваете ему значение в миллисекундах (в этом случае, используя new Date()). Поэтому, когда вы распечатываете их, они также содержат миллисекунды.

Вместо использования библиотек Sun JDK Time/Date (которые оставляют желать лучшего), я рекомендую взглянуть на http://joda-time.sourceforge.net/.

Это очень зрелый и активный проект sourceforge и имеет очень элегантный API.

Согласен с вышесказанным, не должно быть никаких миллисекунд.,,

tl;dr

Принятый ответ Винко Врсаловича верен. Вы вводите целые минуты, поэтому миллисекунды для дробной секунды действительно должны быть равны нулю.

Используйте java.time.

LocalDateTime.parse
( 
    "06-04-2007 07:05" , 
    DateTimeFormatter.ofPattern( "MM-dd-uuuu HH:mm" ) 
)
.atZone
(
    ZoneId.of( "Africa/Casablanca" ) 
)
.toInstant()
.getEpochMilli()

java.time

Современный подход использует классы java.time, определенные в JSR 310, которые много лет назад вытеснили ужасные классы, которые вы используете.

Определите шаблон форматирования, соответствующий вашему вводу. К вашему сведению: научитесь использовать стандартные форматы ISO 8601 для обмена значениями даты и времени в виде текста.

String input = "06-04-2007 07:05" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM-dd-uuuu HH:mm" ) ;

Разберите ваш ввод как LocalDateTime, поскольку в нем отсутствует индикатор часового пояса или смещения от UTC.

LocalDateTime ldt = LocalDateTime.parse( input , f ) ;

Он представляет дату и время дня, но не имеет контекста часового пояса или смещения. Поэтому мы не знаем, имели ли вы в виду 7 утра в Токио, Япония, 7 утра в Тулузе, Франция, или 7 утра в Толедо, штат Огайо, США. Эта проблема часового пояса имеет решающее значение, потому что желаемое количество миллисекунд - это счетчик с первого момента 1970 года, как видно в UTC (смещение нуля часов-минут-секунд), 1970-01-01T00:00Z.

Итак, мы должны поместить ваше входное значение, LocalDateTime объект в контексте часового пояса или смещения.

Если ваш ввод был предназначен для представления даты и времени в формате UTC, используйте OffsetDateTime с ZoneOffset.UTC.

OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;  // Do this if your date and time represent a moment as seen in UTC. 

Если ваш ввод был предназначен для представления даты и времени, видимых через время настенных часов, используемое людьми определенного региона, используйте ZonedDateTime.

ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;

Затем мы хотим запросить количество миллисекунд с эпохи первого момента 1970 года по UTC. Либо сOffsetDateTime или ZonedDateTime объект в руке, извлеките Instant позвонив toInstant.

Instant instant = odt.toInstant() ;

â € ¦orâ € ¦

Instant instant = zdt.toInstant() ;

Теперь посчитайте миллисекунды.

long millisecondsSinceEpoch = instant.toEpochMilli() ;

Между прочим, я предлагаю вам не отслеживать время по миллисекундам. Вместо этого используйте текст в формате ISO 8601: его легко анализировать машиной, легко читать люди из разных культур. Количество миллисекунд - ни то, ни другое.



О java.time

Java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытесняют старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

Чтобы узнать больше, см. Oracle Tutorial. И поищите в stackru множество примеров и объяснений. Спецификация - JSR 310.

Проект Joda-Time, находящийся сейчас в режиме обслуживания, рекомендует перейти на классы java.time.

Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или новее. Нет необходимости в струнах, нет необходимости вjava.sql.*классы. Hibernate 5 и JPA 2.2 поддерживают java.time.

Где взять классы java.time?

Когда вы анализируете дату, она использует только предоставленную вами информацию. В этом случае он знает только MM-дд-гггг ЧЧ: мм.

Создание нового объекта даты возвращает текущую системную дату / время (количество миллисекунд с начала эпохи).

Date.getTime возвращает количество миллисекунд с 1 января 1970 года, 00:00:00 по Гринвичу, представленное объектом Date. Итак, "06-04-2007 07:05" - "01-01-1970 00:00" равно 1180955340000 миллисекунд. Поскольку ваш вопрос касается только временной части даты, грубый подход к этому вычислению - это число миллисекунд между 07:05 и 00:00, равное 25500000. Это делится на 1000, поскольку ни одно из этих времен есть миллисекунды.

Во второй дате используется текущее время выполнения этой строки кода. Это будет использовать то, что текущие миллисекунды после текущей секунды находятся в расчете. Поэтому Date.getTime, скорее всего, вернет число, которое не делится на 1000 равномерно.

import java.util.*;

public class Time {
    public static void main(String[] args) {
        Long l = 0L;
        Calendar c = Calendar.getInstance();
        //milli sec part of current time
        l = c.getTimeInMillis() % 1000;  
        //current time without millisec
        StringBuffer sb = new StringBuffer(c.getTime().toString());
        //millisec in string
        String s = ":" + l.toString();
        //insert at right place
        sb.insert(19, s);
        //ENJOY
        System.out.println(sb);
    }
}

toString() объекта Date не показывает миллисекунды... Но они есть

Таким образом, new Date() - это объект с разрешением в миллисекунды, что можно увидеть по:

  System.out.printf( "ms = %d\n", myDate.getTime() % 1000 ) ;

Однако, когда вы создаете дату с помощью SimpleDateFormat, ей не передаются миллисекунды.

Я пропускаю вопрос здесь?

[править] Хахаха... слишком медленно;)

getTime() метод Date возвращает количество миллисекунд с 1 января 1970 года (эта дата называется "эпохой", поскольку все компьютерные даты основаны на этой дате). Он не должен использоваться для отображения удобочитаемой версии вашей даты.

Использовать SimpleDateFormat.format() метод вместо. Вот пересмотренная версия части вашего кода, которая, я думаю, может решить вашу проблему:

String date = "06-04-2007 07:05:23:123";
SimpleDateFormat fmt = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss:S");
Date myDate = fmt.parse(date); 

System.out.println(myDate);  //Mon Jun 04 07:05:23 EDT 2007
String formattedDate = fmt.format(myDate);
System.out.println(formattedDate); //06-04-2007 07:05:23:123
Другие вопросы по тегам