Преобразование LocalDate в LocalDateTime или java.sql.Timestamp
Я использую JodaTime 1.6.2.
У меня есть LocalDate
, который мне нужно преобразовать либо в (Joda) LocalDateTime
, либо в java.sqlTimestamp
для ormapping.
Причиной этого является то, что я выяснил, как преобразовать между LocalDateTime
и a java.sql.Timestamp
:
LocalDateTime ldt = new LocalDateTime();
DateTimeFormatter dtf = DateTimeFormatter.forPattern("yyyy-MM-dd HH:mm:ss");
Timestamp ts = Timestamp.valueOf(ldt.toString(dtf));
Итак, если я могу просто преобразовать между LocalDate
и LocalDateTime
, тогда я могу сделать непрерывное преобразование в java.sql.Timestamp
. Спасибо за любые подталкивания в правильном направлении!
Ответы
Ответ 1
JodaTime
Чтобы преобразовать JodaTime org.joda.time.LocalDate
в java.sql.Timestamp
, просто сделайте
Timestamp timestamp = new Timestamp(localDate.toDateTimeAtStartOfDay().getMillis());
Чтобы преобразовать JodaTime org.joda.time.LocalDateTime
в java.sql.Timestamp
, просто сделайте
Timestamp timestamp = new Timestamp(localDateTime.toDateTime().getMillis());
JavaTime
Чтобы преобразовать Java8 java.time.LocalDate
в java.sql.Timestamp
, просто сделайте
Timestamp timestamp = Timestamp.valueOf(localDate.atStartOfDay());
Чтобы преобразовать Java8 java.time.LocalDateTime
в java.sql.Timestamp
, просто сделайте
Timestamp timestamp = Timestamp.valueOf(localDateTime);
Ответ 2
Лучший способ использовать Java 8 time API:
LocalDateTime ldt = timeStamp.toLocalDateTime();
Timestamp ts = Timestamp.valueOf(ldt);
Для использования с JPA введите вашу модель (https://weblogs.java.net/blog/montanajava/archive/2014/06/17/using-java-8-datetime-classes-jpa):
@Converter(autoApply = true)
public class LocalDateTimeConverter implements AttributeConverter<LocalDateTime, Timestamp> {
@Override
public Timestamp convertToDatabaseColumn(LocalDateTime ldt) {
return Timestamp.valueOf(ldt);
}
@Override
public LocalDateTime convertToEntityAttribute(Timestamp ts) {
return ts.toLocalDateTime();
}
}
Так что теперь это относительное время, зависящее от времени. Кроме того, это легко сделать:
LocalDate ld = ldt.toLocalDate();
LocalTime lt = ldt.toLocalTime();
Форматирование:
DateTimeFormatter DATE_TME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
String str = ldt.format(DATE_TME_FORMATTER);
ldt = LocalDateTime.parse(str, DATE_TME_FORMATTER);
UPDATE: postgres 9.4.1208, HSQLDB 2.4.0 и т.д. Понимают Java 8 Time API без каких-либо разговоров!
Ответ 3
ТЛ; др
Проект Joda-Time находится в режиме обслуживания, теперь вытесняется классами java.time.
- Просто используйте
java.time.Instant
класс. - Нет необходимости:
-
LocalDateTime
-
java.sql.Timestamp
- Струны
Захватить текущий момент в UTC.
Instant.now()
Чтобы сохранить этот момент в базе данных:
myPreparedStatement.setObject( … , Instant.now() ) // Writes an 'Instant' to database.
Чтобы извлечь этот момент из базы данных:
myResultSet.getObject( … , Instant.class ) // Instantiates a 'Instant'
Чтобы отрегулировать время настенных часов по отношению к конкретному часовому поясу.
instant.atZone( z ) // Instantiates a 'ZonedDateTime'
LocalDateTime
- неправильный класс
Другие ответы верны, но они не указывают, что LocalDateTime
- неправильный класс для вашей цели.
Как в java.time, так и в Joda-Time, LocalDateTime
преднамеренно лишена какой-либо концепции часового пояса или смещения от UTC. Таким образом, это не представляет собой момент и не является точкой на временной шкале. LocalDateTime
представляет собой приблизительное представление о потенциальных моментах в диапазоне около 26-27 часов.
Используйте LocalDateTime
для либо, когда зона/смещение неизвестна (не очень хорошая ситуация), либо когда неопределенность зоны является неопределенной. Например, "Рождество начинается в первый момент 25 декабря 2018 года" будет представлено как LocalDateTime
.
Используйте ZonedDateTime
чтобы представить момент в определенном часовом поясе. Например, Рождество, начинающееся в любой конкретной зоне, такой как Pacific/Auckland
или America/Montreal
, будет представлено объектом ZonedDateTime
.
На мгновение всегда в UTC используйте Instant
.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
Применение часового пояса. Тот же момент, та же точка на временной шкале, но просматривается с другим временем настенных часов.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, different wall-clock time.
Итак, если я могу просто конвертировать между LocalDate и LocalDateTime,
Нет, неверная стратегия. Если у вас есть значение только для даты, и вы хотите ввести дату-время, вы должны указать время суток. Это время суток может быть недействительным в эту дату для определенной зоны - в этом случае класс ZonedDateTime
автоматически корректирует время суток по мере необходимости.
LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 ) ;
LocalTime lt = LocalTime.of( 14 , 0 ) ; // 14:00 = 2 PM.
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
Если вы хотите, чтобы первый момент дня был вашим временем дня, пусть java.time определит этот момент. Не думайте, что день начинается в 00:00:00. Аномалии, такие как переход на летнее время (DST), означают, что день может начаться в другое время, например, 01:00:00.
ZonedDateTime zdt = ld.atStartOfDay( z ) ;
java.sql.Timestamp
- это неправильный класс
java.sql.Timestamp
является частью проблемных старых классов времени, которые теперь являются устаревшими, полностью вытесняются классами java.time. Этот класс использовался для представления момента в UTC с разрешением наносекунд. Эта цель теперь используется с java.time.Instant
.
JDBC 4.2 с getObject
/setObject
Начиная с JDBC 4.2 и более поздних версий, ваш JDBC-драйвер может напрямую обменивать java.time-объекты с базой данных, вызывая:
Например:
myPreparedStatement.setObject( … , instant ) ;
… а также …
Instant instant = myResultSet.getObject( … , Instant.class ) ;
Преобразование наследия ⬌ современных
Если вы должны взаимодействовать со старым кодом, который еще не обновлен до java.time, конвертируйте туда и обратно, используя новые методы, добавленные в старые классы.
Instant instant = myJavaSqlTimestamp.toInstant() ; // Going from legacy class to modern class.
…а также…
java.sql.Timestamp myJavaSqlTimestamp = java.sql.Timestamp.from( instant ) ; // Going from modern class to legacy class.
О java.time
Рамка java.time встроена в Java 8 и более поздние версии. Эти классы вытесняют неприятные старые устаревшие классы времени, такие как java.util.Date
, Calendar
и SimpleDateFormat
.
Проект Joda-Time, теперь в режиме обслуживания, советует перейти на классы java.time.
Чтобы узнать больше, ознакомьтесь с учебным пособием Oracle. И поиск Qaru для многих примеров и объяснений. Спецификация - JSR 310.
Вы можете обменивать объекты java.time непосредственно с вашей базой данных. Используйте JDBC-драйвер, совместимый с JDBC 4.2 или новее. Нет необходимости в строках, нет необходимости в java.sql.*
.
Где можно получить классы java.time?
- Java SE 8, Java SE 9 и более поздние версии
- Встроенный.
- Часть стандартного Java API с интегрированной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и Java SE 7
- Большая часть функциональных возможностей java.time включена обратно в Java 6 и 7 в ThreeTen-Backport.
- Android
Проект ThreeTen-Extra расширяет java.time с дополнительными классами. Этот проект является доказательством возможных будущих дополнений к java.time. Здесь вы можете найти полезные классы, такие как Interval
, YearWeek
, YearQuarter
и другие.
Ответ 4
В зависимости от вашего часового пояса вы можете потерять несколько минут (1650-01-01 00:00:00 станет 1649-12-31 23:52:58)
Используйте следующий код, чтобы избежать этого.
new Timestamp(localDateTime.getYear() - 1900, localDateTime.getMonthOfYear() - 1, localDateTime.getDayOfMonth(), localDateTime.getHourOfDay(), localDateTime.getMinuteOfHour(), localDateTime.getSecondOfMinute(), fractional);
Ответ 5
С тех пор, как Джода угасает, кто-то может захотеть преобразовать LocaltDate
в LocalDateTime
в Java 8. В Java 8 LocalDateTime
он даст возможность создать экземпляр LocalDateTime
используя LocalDate
и LocalTime
. Проверьте здесь.
public static LocalDateTime (дата LocalDate, время LocalTime)
Образец будет,
// just to create a sample LocalDate
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate ld = LocalDate.parse("20180306", dtf);
// convert ld into a LocalDateTime
// We need to specify the LocalTime component here as well, it can be any accepted value
LocalDateTime ldt = LocalDateTime.of(ld, LocalTime.of(0,0)); // 2018-03-06T00:00
Для справки, для того, чтобы использовать эпоху секунд ниже,
ZoneId zoneId = ZoneId.systemDefault();
long epoch = ldt.atZone(zoneId).toEpochSecond();
// If you only care about UTC
long epochUTC = ldt.toEpochSecond(ZoneOffset.UTC);
Ответ 6
Java8 +
import java.time.Instant;
Instant.now().getEpochSecond(); //timestamp in seconds format (int)
Instant.now().toEpochMilli(); // timestamp in milliseconds format (long)