Я пытаюсь вставить тот же формат даты из java. Я использую это:
Из-за этого формата он идет с ошибкой. Как я могу изменить формат в точности, что хочу?
Ответ 1
Для Java 7 вы можете использовать:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
System.out.println(df.format(new Date()));
В этом случае используется символ шаблона XXX, который также печатает двоеточие внутри смещения. Однако для Java-6 эта функция не предлагается. И точность всегда ограничена миллисекундами.
Для Java-8 вы также можете использовать:
DateTimeFormatter dtf = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
System.out.println(OffsetDateTime.now().format(dtf)); // 2016-03-10T08:46:44.849+01:00
Это позволяет наносекундную точность, если такие часы доступны (начиная с Java-9).
Для Java-6 примените хак на основе SimpleDateFormat
или используйте внешние библиотеки:
// Java-6 (SimpleDateFormat)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
String text = sdf.format(new Date());
text = text.substring(0, text.length() - 2) + ":" + text.substring(text.length() - 2);
System.out.println(text);
// Joda-Time
DateTime now = DateTime.now();
System.out.println(DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZZ").print(now));
// Time4J
Moment now = SystemClock.currentMoment();
System.out.println(Iso8601Format.EXTENDED_DATE_TIME_OFFSET.withStdTimezone().format(now));
Ответ 3
Ответ Мено Хохшильда. Я просто добавлю еще несколько комментариев и код, специфичный для SQL.
Избегать старых классов времени
Старые классы времени-времени, java.util.Date/.Calendar и java.text.SimpleDateFormat, плохо разработаны, запутываются и неприятны. Избегайте их.
Старые кланы были вытеснены рамкой java.time, встроенной в Java 8 и более поздних версий.
Для использования перед Java 8 ознакомьтесь с проектом ThreeTen-Backport.
наносекунд
Классы java.time имеют наносекундное разрешение. Таким образом, у вас не будет проблемы с потерей данных, если 2016-03-10T11:24:59.7862749+04:00
будет усечен до 2016-03-10 11:24:59.786
из-за разрешения в миллисекундах, используемого старыми классами.
Получение текущего момента в Java 8 ограничено миллисекундами, три цифры десятичной доли секунды, из-за устаревшей проблемы. Java 9 получит текущий момент в наносекундах, до девяти цифр десятичной доли (если ваши аппаратные часы вашего компьютера могут обеспечить такое точное разрешение).
ISO 8601
Стандарт ISO 8601 определяет разумные текстовые форматы для значений даты и времени. Например, 2016-03-09T23:24:33Z
или 2016-03-09T22:24:33-01:00
. Классы java.time используют их по умолчанию, поэтому нет необходимости определять шаблоны разбора.
Instant
An Instant
- момент на временной шкале в UTC.
Instant instant = Instant.now();
Вызвать Instant::toString
для создания строки в стандартном формате.
String output = instant.toString();
2016-03-09T23: 24: 33.123Z
OffsetDateTime
Примените ZoneOffset
, чтобы получить OffsetDateTime
.
ZoneOffset zoneOffset = ZoneOffset.ofHoursMinutes( -5 , 30 );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );
ZonedDateTime
Если вы знаете полный часовой пояс, а не только offset-from-UTC, примените ZoneId
, чтобы получить ZonedDateTime
.
Используйте правильные названия часовых поясов.
ZoneId zoneId = ZoneId.of( "Asia/Kolkata" ); // "Europe/Paris", "America/Montreal", etc.
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
java.sql.Timestamp
Будем надеяться, что драйверы JDBC будут обновлены, чтобы напрямую использовать типы java.time. До этого мы конвертируем в java.sql типы для передачи данных в/из базы данных.
Как отмечалось выше, java.time может обрабатывать наносекунды. Таким образом, java.sql.Timestamp
. Но ваша база данных не может. Некоторые базы данных ограничены целыми секундами, миллисекундами или микросекундами. Когда данные передаются через JDBC в базу данных, база данных может усекаться.
java.sql.Timestamp ts = java.sql.Timestamp.from( instant );
... и идя в другом направлении...
Instant instant = ts.toInstant();
Обратите внимание, что Instant
всегда находится в UTC по определению. Поэтому нет необходимости выполнять код, который был предпринят в конце Вопроса.
Рабочий поток
Вы должны минимизировать использование строк при работе с датой. Максимизируйте использование полезных классов/объектов даты и времени, а именно классов java.time. Прекратите думать о строках в качестве значений даты и времени - они представляют собой текстовое представление значения даты и времени.
Не вставлять/извлекать значения даты и времени в/из вашей базы данных в виде строк. Использовать объекты java.sql, такие как java.sql.Timestamp
и java.sql.Date
. Используйте PreparedStatement
и методы "set/get", такие как setTimestamp
/getTimestamp
. И фактически всегда определяет ваши столбцы в базе данных как TIMESTAMP WITH TIME ZONE
, а не "без часового пояса".
При получении данных из базы данных используйте типы java.sql. Но как только это возможно, конвертируйте в типы java.time. Типы java.sql - это беспорядок, грязный взлом и должны использоваться только для передачи данных, а не для бизнес-логики.
Как правило, лучше всего использовать UTC в вашей бизнес-логике, хранении данных, обмене данными, вызовах API и т.д. Отрегулируйте в часовом поясе только тогда, когда это ожидается пользователем или требуется для приемника данных.