Як конвертувати TimeStamp у Date в Java?


105

Як перетворити "timeStamp" на те, dateколи я отримаю підрахунок у Java?

Мій поточний код такий:

public class GetCurrentDateTime {

    public int data() {
        int count = 0;
        java.sql.Timestamp timeStamp = new Timestamp(System.currentTimeMillis());
        java.sql.Date date = new java.sql.Date(timeStamp.getTime()); 
        System.out.println(date);
        //count++;

        try {
            Class.forName("com.mysql.jdbc.Driver");
            Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/pro", "root", "");

            PreparedStatement statement = con.prepareStatement("select * from orders where status='Q' AND date=CURDATE()");
            ResultSet result = statement.executeQuery();
            while (result.next()) {
                // Do something with the row returned.
                count++; //if the first col is a count.
            }
        } catch (Exception exc) {
            System.out.println(exc.getMessage());
        }

        return count;
    }
}

Це моя база даних: введіть тут опис зображення

Ось результат, який я отримав, був 2012-08-07 0, але еквівалентний запит повертається 3. Чому я отримую 0?



Чи можете ви показати нам приклади того, як виглядають дані таблиці?
oldrinb

дата (1344255451,1344255537,1344312502) та статус мають (Q, Q, Q)
Крішна Вені


Назва цього питання - червона оселедець . Справжня проблема полягає в неправильному використанні а PreparedStatementз неправильним синтаксисом. Ви не можете вставляти змінні Java у текст рядка SQL. Натомість вбудуйте ?в рядок SQL, а потім викликайте setметоди передачі значень у PreparedStatement. Див. Правильний відповідь Суджая та Відповідь тенорсакса .
Василь Бурк

Відповіді:


188

Просто зробіть новий Dateоб'єкт зі значенням штампа getTime()в якості параметра.

Ось приклад (я використовую приклад часової позначки поточного часу):

Timestamp stamp = new Timestamp(System.currentTimeMillis());
Date date = new Date(stamp.getTime());
System.out.println(date);

@ vs06 Чому ви вважаєте, що це застаріло? Остання версія java 7 та 8 документу говорить інакше ( docs.oracle.com/javase/7/docs/api/java/util/Date.html#getTime () та docs.oracle.com/javase/8/docs/api /java/util/Date.html#getTime-- )
Алекс Коулман

4
Це призведе до неправильного результату, якщо часовий пояс Timestamp та часовий пояс JVM відрізняються.
Роберт Мугаттаров

Як отримати такий формат, наприклад, до 14.03.2014?
шуррок

6
Я ненавиджу, коли ppl використовує бібліотеки у своїх відповідях і чекаю, що всі знають, як їх імпортувати: /
Sodj

38
// timestamp to Date
long timestamp = 5607059900000; //Example -> in ms
Date d = new Date(timestamp );

// Date to timestamp
long timestamp = d.getTime();

//If you want the current timestamp :
Calendar c = Calendar.getInstance();
long timestamp = c.getTimeInMillis();

Чому ви помножили його на 1000?
Sharpless512

3
Оскільки ініціалізація дати відбувається в мілісекундах, а позначка часу - в секундах! Те саме подумайте про всі інші перетворення! Це добре ?
VincentLamoute


7

Я шукав це давно, виявляється, що конвертер Eposh робить це легко:

long epoch = new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse("01/01/1970 01:00:00").getTime() / 1000;

Або навпаки:

String date = new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new java.util.Date (epoch*1000));

6

тл; д-р

LocalDate.now( ZoneId.of( "Africa/Tunis" ) )
    .atStartOfDay( ZoneId.of( "Africa/Tunis" ) )
    .toEpochSecond()

LocalDate.now( ZoneId.of( "Africa/Tunis" ) )
    .plusDays( 1 )
    .atStartOfDay( ZoneId.of( "Africa/Tunis" ) )
    .toEpochSecond()

"SELECT * FROM orders WHERE placed >= ? AND placed < ? ; "

myPreparedStatement.setObject( 1 , start )
myPreparedStatement.setObject( 2 , stop )

java.time

Ви користуєтеся клопітними старими класами дати, які тепер застаріли, замінені сучасним java.time класи класами .

Мабуть, ви зберігаєте момент у своїй базі даних у стовпці якогось цілого типу. Це прикро. Натомість слід використовувати стовпець такого типу, як стандарт SQL TIMESTAMP WITH TIME ZONE. Але для цього відповіді ми будемо працювати з тим, що маємо.

Якщо ваші записи представляють моменти з роздільною здатністю мілісекунд, і ви хочете, щоб усі записи були за цілий день, тоді нам потрібен часовий діапазон. У нас повинен бути момент початку та зупинки. У вашому запиті є лише один критерій дати та часу, де він мав би мати пару.

LocalDateКлас являє собою дату тільки значення без часу доби і без часового поясу.

Часовий пояс має вирішальне значення при визначенні дати. Для будь-якого моменту дата змінюється по всьому світу за зоною. Наприклад, через кілька хвилин після півночі у Парижі Франція - це новий день, а ще «вчора» в Монреалі Квебек .

Якщо часовий пояс не вказаний, JVM неявно застосовує поточний часовий пояс за замовчуванням. Цей дефолт може змінитися в будь-який момент, тому результати можуть відрізнятися. Краще вказати бажаний / очікуваний часовий пояс як аргумент.

Вкажіть правильний час ім'я зони в форматі continent/region, наприклад America/Montreal, Africa/Casablancaабо Pacific/Auckland. Ніколи не використовуйте абревіатуру з 3–4 літер, наприклад, ESTабо ISTяк вони не є справжніми часовими поясами, не стандартизовані та навіть не унікальні (!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

Якщо ви хочете використовувати поточний часовий пояс JVM за замовчуванням, запитайте його та передайте як аргумент. Якщо пропущено, поточний дефолт JVM застосовується неявно. Краще бути явним, оскільки за замовчуванням може бути змінено будь-який момент під час виконання будь-яким кодом у будь-якому потоці будь-якої програми в рамках JVM.

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

Або вкажіть дату. Ви можете встановити місяць за числом, причому для січня-грудня число "розумне" буде 1-12.

LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ;  // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.

Або, краще, використовуйте Monthзаздалегідь визначені об’єкти enum, по одному на кожен місяць року. Порада: Використовуйте ці Monthоб'єкти у всій своїй кодовій базі, а не просто ціле число, щоб зробити свій код більш самодокументованим, забезпечити дійсні значення та забезпечити безпеку типу .

LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;

З LocalDateрукою нам далі потрібно перетворити це на пару моментів, початку та зупинки дня. Не припускайте, що день починається о 00:00 години часу. Через аномалії, такі як літній час (DST), день може розпочатися в інший час, наприклад, 01:00:00. Тож нехай java.time визначає перший момент дня. Ми передаємо ZoneIdаргумент, LocalDate::atStartOfDayщоб шукати будь-які подібні аномалії. Результат - а ZonedDateTime.

ZonedDateTime zdtStart = ld.atStartOfDay( z ) ;

Як правило, найкращим підходом до визначення проміжку часу є підхід "Напіврозкритий", де початок є інклюзивним, а закінчення є виключним . Отже день починається з першого моменту і закінчується, але не включаючи першого моменту наступного дня.

ZonedDateTime zdtStop = ld.plusDays( 1 ).atStartOfDay( z ) ;  // Determine the following date, and ask for the first moment of that day.

Наш запит протягом цілого дня не може використовувати команду SQL BETWEEN. Ця команда є повністю заповненою ( []) (починаючи з кінця і закінчуючи), де ми хочемо напіввідкрити ( [)). Ми використовуємо пару критеріїв >=і< .

Ваш стовпець погано названий. Уникайте будь-якого з тисяч слів, зарезервованих різними базами даних. Давайте скористаємося placedв цьому прикладі.

У вашому коді повинні бути використані ?заповнювачі, в яких можна вказати наші моменти.

String sql = "SELECT * FROM orders WHERE placed >= ? AND placed < ? ; " ;

Але у нас є ZonedDateTimeоб’єкти в руці, тоді як ваша база даних, очевидно, зберігає цілі числа, як обговорювалося вище. Якщо ви вже визначили свій стовпець правильно , ми могли б просто передатиZonedDateTime об'єкти з будь-яким драйвером JDBC з підтримкою JDBC 4.2 або новішої версії.

Але замість цього нам потрібно отримати цілі секунди відлік епохи. Я припускаю, що ваша дата відліку епохи - це перший момент 1970 року в UTC. Остерігайтеся можливих втрат даних, оскільки ZonedDateTimeклас здатний до наносекундної роздільної здатності. Будь-яка дробова секунда буде усічена в наступних рядках.

long start = zdtStart().toEpochSecond() ;  // Transform to a count of whole seconds since 1970-01-01T00:00:00Z.
long stop = zdtStop().toEpochSecond() ; 

Тепер ми готові передати ці цілі числа до нашого SQL-коду, визначеного вище.

PreparedStatement ps = con.prepareStatement( sql );
ps.setObject( 1 , start ) ;
ps.setObject( 2 , stop ) ;
ResultSet rs = ps.executeQuery();

Коли ви отримуєте цілі цілі значення з ResultSet, ви можете перетворитись на Instantоб'єкти (завжди в UTC) або в ZonedDateTimeоб'єкти (з призначеним часовим поясом).

Instant instant = rs.getObject(  , Instant.class ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

Про java.time

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

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

Щоб дізнатися більше, дивіться навчальний посібник Oracle . І шукайте переповнення стека за багатьма прикладами та поясненнями. Специфікація - JSR 310 .

Де отримати класи 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
    • Пізніші версії реалізації пакетів Android для класів java.time.
    • Для більш раннього Android, то ThreeTenABP проект адаптує ThreeTen-Backport (згаданий вище). Див. Як користуватися ThreeTenABP… .

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


4

Перш за все, ви не використовуєте перевагу використання PreparedStatement. Я спершу запропонував би вам змінити PreparedStatementнаступне:

PreparedStatement statement = con.prepareStatement("select * from orders where status=? AND date=?")

Потім можна використовувати statement.setXX(param_index, param_value)для встановлення відповідних значень. Для конвертації вtimestamp перегляньте наступні javadocs:

PreparedStatement.setTimeStamp ()
Timestamp

Сподіваюся, це допомагає!


4

В Android його дуже просто. Просто користуйтеся класом Calender, щоб отримати currentTimeMillis.

Timestamp stamp = new Timestamp(Calendar.getInstance().getTimeInMillis());
Date date = new Date(stamp.getTime());
Log.d("Current date Time is   "  +date.toString());

У Java просто використовуйте System.currentTimeMillis (), щоб отримати поточну мітку часу


3

Не впевнений, що ви намагаєтесь вибрати у запиті, але майте на увазі, що UNIX_TIMESTAMP()без аргументів повертається час зараз. Вам, ймовірно, слід надати дійсний час як аргумент або змінити умову.

Редагувати:

Ось приклад тимчасового запиту на основі запитання:

PreparedStatement statement = con
        .prepareStatement("select * from orders where status='Q' AND date > ?");
Date date = new SimpleDateFormat("dd/MM/yyyy").parse("01/01/2000");
statement.setDate(1, new java.sql.Date(date.getTime()));

EDIT: стовпець часових позначок

У разі використання мітки часу java.sql.Timestampта PreparedStatement.setTimestamp () , тобто:

PreparedStatement statement = con
        .prepareStatement("select * from orders where status='Q' AND date > ?");
Date date = new SimpleDateFormat("dd/MM/yyyy").parse("01/01/2000");
Timestamp timestamp = new Timestamp(date.getTime());
statement.setTimestamp(1, timestamp);

тепер мій стан - вибрати * від xcart_orders, де status = 'Q' І дата = CURDATE (). Тепер також відображається лише нуль
Krishna Veni

@krishnaveni, які записи ви намагаєтесь вибрати?
тенорсакс

дата (11111111,123456767,122333344) і статус = (Q, Q, Q) .. всі збережені в моїй базі даних. тепер мені потрібно перевірити запит і отримати значення підрахунку та відобразити на консолі (тобто) скільки Дані узгоджуються після повернення значення підрахунку
Крішна Вені

@krishnaveni Якщо ви хочете, щоб набір результатів був пов'язаний з певною датою, використовуйте цю дату в запиті, інакше видаліть умову дати.
тенорсакс

в моєму коді працює успішно, коли дата знаходиться у форматі yyyy-mm-dd, збереженому в моїй базі даних. Але тепер моя дата зберігається у часовій позначці у цьому форматі 1343469690. Як отримати значення підрахунку? Як я написав тут код
Крішна Вені,

3

new Date(timestamp.getTime())Потрібно працювати, але новий фантазійний спосіб Java 8 (який може бути більш елегантним і безпечнішим для типів, а також допоможе спонукати вас до використання нових часових класів) - це зателефонувати Date.from(timestamp.toInstant()).

(Не покладайтеся на те, що Timestampсам по собі є екземпляром Date; див. Пояснення в коментарях іншої відповіді .)


3
    Timestamp tsp = new Timestamp(System.currentTimeMillis());
   java.util.Date dateformat = new java.util.Date(tsp.getTime());

3

Я відчуваю обов’язок відповісти, оскільки інші відповіді, схоже, є агностиками часового поясу, чого не може дозволити собі реальна заявка у світі. Щоб зробити перетворення часових позначок правильним, коли часова марка та JVM використовують різні часові пояси, ви можете використовувати LocalDateTime Time Joda (або LocalDateTime в Java8) таким чином:

Timestamp timestamp = resultSet.getTimestamp("time_column");
LocalDateTime localDateTime = new LocalDateTime(timestamp);
Date trueDate = localDateTime.toDate(DateTimeZone.UTC.toTimeZone());

У наведеному нижче прикладі передбачається, що часова марка - UTC (як це зазвичай буває з базами даних). Якщо ваші часові позначки знаходяться в іншому часовому поясі, змініть параметр часового поясу toDateзаяви.


2

спробуйте використовувати цей код Java:

Timestamp stamp = new Timestamp(System.currentTimeMillis());
Date date = new Date(stamp.getTime());
DateFormat f = new SimpleDateFormat("yyyy-MM-dd");
DateFormat f1 = new SimpleDateFormat("yyyy/MM/dd");
String d = f.format(date);
String d1 = f1.format(date);
System.out.println(d);
System.out.println(d1);

0

Якщо припустимо, що у вас вже є java.util.Date date:

Timestamp timestamp = new Timestamp(long);
date.setTime( l_timestamp.getTime() );

0

Ви можете використовувати цей метод, щоб отримати дату із мітки часу та часової зони певної області.

public String getDayOfTimestamp(long yourLinuxTimestamp, String timeZone) {
    Calendar cal = Calendar.getInstance();
    cal.setTimeInMillis(yourLinuxTimestamp * 1000);
    cal.setTimeZone(TimeZone.getTimeZone(timeZone));
    Date date = cal.getTime();
}

-1
String timestamp="";
Date temp=null;
try {
    temp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(getDateCurrentTimeZone(Long.parseLong(timestamp)));
} catch (ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
int dayMonth=temp.getDate();
int dayWeek=temp.getDay();
int hour=temp.getHours();
int minute=temp.getMinutes();
int month=temp.getMonth()+1;
int year=temp.getYear()+1900;

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