Java Timestamp - Як я можу створити мітку часу з датою 23/09/2007?


Відповіді:


154

За 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 - yyyy-MM-dd, інакше чудово!
vidstige

1
нова мітка часу (час); даючи помилку, що жоден конструктор на зразок цього не приймає велике значення :(
Бхану Шарма

1
@Bhanu Документи показують, що це має велике значення і, здається, працює правильно: docs.oracle.com/javase/7/docs/api/java/sql/…
Hazok

FYI, жахливі старі класи дату, такі як java.util.Date, java.util.Calendarі java.text.SimpleDateFormatтепер застарілі , витіснені класами java.time, вбудованими в Java 8 та новіших версій. Дивіться Підручник від Oracle .
Василь Бурк

121

Як що до цього?

java.sql.Timestamp timestamp = java.sql.Timestamp.valueOf("2007-09-23 10:10:10.0");

1
Timestamp timestamp = Timestamp.valueOf ("2007-09-23 10: 10: 10,0"); показує метод valueOf не визначено для типу Timestamp в jDK 7
Ashish Ratan

нова мітка часу (час); даючи помилку, що жоден конструктор на зразок цього не приймає значення рядка :(
Bhanu Sharma

@Bhanu Конструктор займає час Unix в мілісекундах. Використовуйте статичний метод valueOf, якщо ви хочете отримати часову позначку з рядка.
Хазок

4
Здається, це найкраща відповідь на питання.
Hazok

1
Найкраща відповідь дати, яка застаріла, є поганою практикою її використання. Це відповіді краще. Дякую
Alberici

18

Що ви маєте на увазі часові позначки? Якщо ви маєте на увазі мілісекунди після епохи Unix:

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

Якщо ви хочете фактичний об’єкт java.sql.Timestamp:

Timestamp ts = new Timestamp(millis);

2
WRONG і не збирається! Помилка компіляції: 09 - восьмеричне число, але 9 - поза межами восьмери. Помилка логіки: місяць базується на 0, ви отримаєте 23 жовтня 2007 року
користувач85421

Я не можу отримати логічну помилку, якщо вона не компілюється. :) Серйозно, гарно ловить, Карлос. Восьмину я спіймав раніше, але все-таки приклеював неправильно. :(
Меттью Флашен

Насправді конструктор Timestamp депримірований, а ви можете використовувати метод Timestamp.valueOf ()
Shiva Komuravelly

@ShivaKomuravelly не всі конструктори часових позначок застаріли, і принаймні це не забирає довгих мілісекунд, конструктор, який приймає дату як аргумент, застарів
немає імені

І для цього є константа (замість місяця = 9):Calendar.SEPTEMBER
Гійом Хуста

11

тл; д-р

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.Timetamp представляє як дату, так і час дня. Тому ми мусимо ввести час дня, щоб пройти разом із датою. Ми припускаємо, що ви хочете, щоб перший момент дня був як час доби. Зауважте, що це не завжди час 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 . І шукайте переповнення стека за багатьма прикладами та поясненнями. Специфікація - JSR 310 .

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

Де отримати класи java.time?

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


3
Цікаво, як я можу отримати ОП або модників, щоб позначити вашу відповідь правильною. Прийнята відповідь настільки застаріла.
sttaq

Дуже приємно, крім помилки друку. asStartOfDay () має бути atStartOfDay ().
Tullochgorum

Виправлено @Tullochgorum. Дякую. FYI, в Stack Overflow ви можете самостійно вносити такі зміни, якщо ви настільки схильні.
Василь Бурк

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());

2
WRONG: спробуйте System.out.println результату! Ви отримаєте щось на зразок: "2009-10-23 15: 26: 56.171" Місяць заснований на 0, тому 9 жовтня!
користувач85421

Я знав, що одна з цих констант базується на нулі, дякую. Публікація оновлена.
Олексій

1
О, і я поставив "неперевірений" :)
Олексій

4

Згідно API, конструктор, який би приймав рік, місяць тощо, застарілий. Натомість слід використовувати конструктор, який приймає довго. Ви можете використовувати реалізацію календаря, щоб побудувати потрібну дату та отримати доступ до часового представлення як довгий, наприклад, методом getTimeInMillis .


1

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

new Timestamp(new DateTime(2007, 9, 23, 0, 0, DateTimeZone.forID( "America/Montreal" )).getMillis())

1
Хороша відповідь, але ви пропустили один важливий фрагмент: часовий пояс . Якщо опустити часовий пояс, до DateTimeоб’єкта застосується поточний часовий пояс JVM за замовчуванням . Це означає, що ваші результати залежать від різних комп’ютерів або конфігурації хост-ОС або налаштувань JVM. Для прогнозованих результатів передайте часовий пояс цьому DateTimeконструктору. Виберіть правильну назву часового поясу для свого наміру. Наприклад, DateTimeZone.forID( "America/Montreal" )або DateTimeZone.UTC.
Василь Борк

Цей код може бути коротшим. Не потрібно перетворюватися на java.util.Date, щоб отримати та пройти мілісекунди з моменту епохи . Просто запитайте DateTimeоб’єкт за його мілісекунди з часу епохи. Замініть .toDate().getTime()на .getMillis().
Василь Бурк

@BasilBourque Залежно від обставин, можливо, ви захочете залишити часовий пояс, щоб мати передбачувані результати. "У вашому поточному часовому поясі" може бути абсолютно розумним і передбачуваним результатом. Чому жорсткий код часового поясу чи просити користувачів вручну встановити часовий пояс, коли на їхньому комп’ютері вже встановлений часовий пояс? Звичайно, я був би дуже здивований, якби програма на моєму комп’ютері почала виводити дати, адаптовані до часового поясу Америка / Монреаль.
дан Картер

@dancarter Опускання необов'язкового часового поясу призводить до плутанини. Упущення викликає неоднозначність (a) чи планував програміст покладатися на неявний дефолт або (b) чи програміст не розглядав проблеми часового поясу (як це занадто часто). Якщо ви дійсно хочете використовувати поточний часовий пояс JVM за замовчуванням, скажіть це прямо , зателефонувавши DateTimeZone.getDefault()та передавши результат як необов'язковий аргумент. (До речі, про те Locale.getDefault()саме питання щодо неоднозначності необов'язкових аргументів.)
Василь Бурк

-1

Більш загальною відповіддю було б імпортувати java.util.Date, тоді, коли вам потрібно встановити timestampрівну поточній даті, просто встановіть його рівним new Date().


тому що ** Дата ("рядок"); ** застаріло
Ашіш Ратан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.