Временная метка Java - как я могу создать временную метку с датой 23.09.2007?

Ответы:

156

По Timestamp, я полагаю , вы имеете в виду java.sql.Timestamp. Вы заметите, что у этого класса есть конструктор, который принимает longаргумент. Вы можете проанализировать это с помощью DateFormatкласса:

DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
Date date = dateFormat.parse("23/09/2007");
long time = date.getTime();
new Timestamp(time);
Адам Пэйнтер
источник
1
Нормальный формат даты ISO - гггг-ММ-дд, в остальном отлично!
vidstige
1
новая отметка времени (время); дает ошибку, что нет такого конструктора, который принимает длинное значение :(
Бхану Шарма
1
@Bhanu Документы показывают, что это действительно длинное значение и, похоже, работает правильно: docs.oracle.com/javase/7/docs/api/java/sql/…
Hazok
К вашему сведению, ужасно неприятные старые классы даты и времени, такие как java.util.Date, java.util.Calendarи java.text.SimpleDateFormat, теперь унаследованы , вытеснены классами java.time, встроенными в Java 8 и новее. См. Учебник Oracle .
Basil
121

Как насчет этого?

java.sql.Timestamp timestamp = java.sql.Timestamp.valueOf("2007-09-23 10:10:10.0");
Pigouina
источник
1
Отметка времени timestamp = Timestamp.valueOf ("2007-09-23 10: 10: 10.0"); показывает, что метод valueOf не определен для типа Timestamp в jDK 7
Ашиш Ратан,
новая отметка времени (время); дает ошибку, что нет такого конструктора, который принимает строковое значение :(
Бхану Шарма
@Bhanu Конструктор берет время unix в миллисекундах. Используйте статический метод valueOf, если вы хотите получить метку времени из строки.
Hazok
4
Кажется, это лучший ответ на вопрос.
Hazok
1
Лучший ответ - Date, который устарел, это плохая практика. Этот ответ лучше. Спасибо
Альберичи
18

Что значит метка времени? Если вы имеете в виду миллисекунды с эпохи Unix:

GregorianCalendar cal = new GregorianCalendar(2007, 9 - 1, 23);
long millis = cal.getTimeInMillis();

Если вам нужен фактический объект java.sql.Timestamp:

Timestamp ts = new Timestamp(millis);
Мэтью Флашен
источник
2
НЕПРАВИЛЬНО и не компилируется! Ошибка компиляции: 09 - восьмеричное число, но 9 выходит за рамки восьмеричного числа. Логическая ошибка: месяц
отсчитывается
Я не могу получить логическую ошибку, если она не компилируется. :) Серьезно, хорошие уловы, Карлос. Восьмеричный, который я ловил раньше, но все равно вставил неправильно. :(
Мэтью Флашен
На самом деле конструктор Timestamp является устаревшим, вместо этого вы можете использовать метод Timestamp.valueOf ()
Шива Комуравелли
@ShivaKomuravelly не все конструкторы отметок времени устарели и, по крайней мере, не занимают много миллисекунд, конструктор, который принимает дату в качестве аргумента, устарел
без названия
И для этого есть константа (вместо month = 9):Calendar.SEPTEMBER
Гийом Хуста
12

tl; dr

java.sql.Timestamp.from (
    LocalDate.of ( 2007 , 9 , 23 )
             .atStartOfDay( ZoneId.of ( "America/Montreal" ) )
             .toInstant()
)

java.time

Давайте обновим эту страницу, показав код с использованием инфраструктуры java.time, встроенной в Java 8 и новее.

Эти новые классы созданы на основе Joda-Time , определены в JSR 310 и расширены проектом ThreeTen-Extra . Они вытесняют заведомо неудобные старые классы времени и даты, связанные с ранними версиями Java.

В java.time это Instantмомент на шкале времени в формате UTC. A ZonedDateTime- это момент времени, настроенный на часовой пояс ( ZoneId).

Часовой пояс здесь имеет решающее значение. Дата September 23, 2007не может быть переведена в момент на шкале времени без применения часового пояса. Учтите, что новый день в Париже начинается раньше, чем в Монреале, где он еще «вчера».

Кроме того, java.sql.Timestamp представляет как дату, так и время дня. Поэтому мы должны ввести время дня, чтобы соответствовать дате. Мы предполагаем, что вы хотите, чтобы время суток было первым моментом дня. Обратите внимание, что это не всегда время 00:00:00.0из-за перехода на летнее время и, возможно, других аномалий.

Обратите внимание, что в отличие от старого класса java.util.Date и в отличие от Joda-Time типы java.time имеют разрешение наносекунды, а не миллисекунды. Это соответствует разрешению java.sql.Timestamp.

Обратите внимание, что java.sql.Timestamp имеет неприятную привычку неявно применять текущий часовой пояс JVM по умолчанию к его значению даты и времени при генерации строкового представления с помощью его toStringметода. Здесь вы видите, что мой America/Los_Angelesчасовой пояс применен. Напротив, классы java.time более разумны и используют стандартные форматы ISO 8601 .

LocalDate d = LocalDate.of ( 2007 , 9 , 23 ) ;
ZoneId z = ZoneId.of ( "America/Montreal" ) ;
ZonedDateTime zdt = d.atStartOfDay( z ) ;
Instant instant = zdt.toInstant() ;
java.sql.Timestamp ts = java.sql.Timestamp.from ( instant ) ;

Выгрузить в консоль.

System.out.println ( "d: " + d + " = zdt: " + zdt + " = instant: " + instant + " = ts: " + ts );

При запуске.

d: 2007-09-23 = zdt: 2007-09-23T00: 00-04: 00 [Америка / Монреаль] = мгновенно: 2007-09-23T04: 00: 00Z = ts: 2007-09-22 21:00: 00.0

Кстати, начиная с JDBC 4.2, вы можете напрямую использовать типы java.time. Нет необходимости в java.sql.Timestamp.

  • PreparedStatement.setObject
  • ResultSet.getObject

О java.time

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

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

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

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

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

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательной площадкой для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь , такие как Interval, YearWeek, YearQuarter, и более .

Василий Бурк
источник
3
Интересно, как я могу получить OP или моды, чтобы пометить ваш ответ как правильный. Принятый ответ настолько устарел.
sttaq
Очень красиво, если не считать опечатки. asStartOfDay () должен быть atStartOfDay ().
Tullochgorum
@Tullochgorum Исправлено. Спасибо. К вашему сведению, в Stack Overflow вы можете сами вносить такие правки, если хотите.
Basil
5

Вы также можете сделать следующее:

// untested
Calendar cal = GregorianCalendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 23);// I might have the wrong Calendar constant...
cal.set(Calendar.MONTH, 8);// -1 as month is zero-based
cal.set(Calendar.YEAR, 2009);
Timestamp tstamp = new Timestamp(cal.getTimeInMillis());
Alex
источник
2
НЕПРАВИЛЬНО: попробуйте System.out.println результата! Вы получите что-то вроде: "2009-10-23 15: 26: 56.171" Месяц отсчитывается от 0, поэтому 9 - октябрь!
user85421
Я знал, что одна из этих констант отсчитывается от нуля, спасибо. Сообщение обновлено.
Alex
1
Да, и я поставил «непроверенный» :)
Alex
4

Согласно API конструктор, принимающий год, месяц и т. Д., Устарел. Вместо этого вы должны использовать конструктор, который принимает long. Вы можете использовать реализацию Calendar для создания нужной даты и доступа к представлению времени в виде длинного числа, например, с помощью метода getTimeInMillis .

Филипп
источник
1

Для полноты картины также решение с Joda-Time версии 2.5 и его DateTimeклассом:

new Timestamp(new DateTime(2007, 9, 23, 0, 0, DateTimeZone.forID( "America/Montreal" )).getMillis())
user152468
источник
1
Хороший ответ, но вы упустили одну важную деталь: часовой пояс . Если вы опускаете часовой пояс, к DateTimeобъекту применяется текущий часовой пояс JVM по умолчанию . Это означает, что ваши результаты будут отличаться для разных компьютеров или конфигурации ОС хоста или настроек JVM. Для получения предсказуемых результатов передайте часовой пояс этому DateTimeконструктору. Выберите подходящее название часового пояса для вашего намерения. Например, DateTimeZone.forID( "America/Montreal" )или DateTimeZone.UTC.
Basil Bourque
Этот код мог быть короче. Нет необходимости преобразовывать в java.util.Date, чтобы получить и передать миллисекунды с начала эпохи . Просто спросите DateTimeобъект в миллисекундах с начала эпохи. Заменить .toDate().getTime()на .getMillis().
Basil Bourque
@BasilBourque В зависимости от обстоятельств вы можете не учитывать часовой пояс, чтобы получить предсказуемые результаты. «В вашем текущем часовом поясе» может быть вполне разумным и предсказуемым результатом. Зачем жестко кодировать часовой пояс или просить пользователей вручную установить часовой пояс, если на их компьютере уже установлен часовой пояс? Конечно, я был бы очень удивлен, если бы приложение на моем компьютере начало выводить даты, скорректированные по часовому поясу Америки / Монреаля.
Дэн Картер
@dancarter Пропуск необязательного часового пояса приводит к путанице. Упущение вызывает двусмысленность: (а) намерен ли программист полагаться на неявное значение по умолчанию или (б) не учел ли программист проблемы часового пояса (что слишком часто). Если вы действительно хотите использовать текущий часовой пояс JVM по умолчанию, скажите об этом явно , вызвав DateTimeZone.getDefault()и передав результат в качестве необязательного аргумента. (Между прочим, то Locale.getDefault()же самое для , такая же проблема с двусмысленностью необязательных аргументов.)
Basil Bourque
-1

Более общий ответ - импортировать java.util.Date, тогда, когда вам нужно установить timestampравное текущей дате, просто установите его равным new Date().

CSquid
источник
потому что ** Дата ("строка"); ** устарело
Ашиш Ратан