samba
samba

Reputation: 3091

How to convert seconds to java.sql.Timestamp?

I needed to truncate milliseconds to seconds and implemented it in this way:

private static Long millisToSeconds(Long millisValue) {
    return TimeUnit.MILLISECONDS.toSeconds(millisValue);
}

So now it truncates millis as expected, for example:

Long secondsValue = millisToSeconds(1554052265830L);
System.out.println("millisToSeconds ---> " + toSeconds); 
// Prints millisToSeconds ---> 1554052265

But then I want to convert secondsValue to java.sql.Timestamp but the following implementation results in an error:

java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]

What should I fix in my implementation to convert seconds to timestamp so that the resulting timestamp looks like 2019-03-31 11:45:06 ?

Upvotes: 0

Views: 3755

Answers (3)

Anonymous
Anonymous

Reputation: 86148

java.time

I am assuming that you are asking for a java.sql.Timestamp for use with your SQL database. In most cases you shouldn’t ask for that. The Timestamp class is poorly designed and long outdated, and a modern JDBC driver or JPA implementation will be happy to accept a type from java.time, the modern Java date and time API, instead.

    long millisValue = 1_554_052_265_830L;
    Instant i = Instant.ofEpochMilli(millisValue);
    i = i.truncatedTo(ChronoUnit.SECONDS);
    System.out.println(i);

2019-03-31T17:11:05Z

I don’t know why you wanted to truncate to seconds, but you can see that it has been done (or it’s easy to leave that line out).

Some JDBC drivers accept an Instant directly when you pass it to PreparedStatement.setObject (one of the overloaded versions of that method) even though the JDBC specification doesn’t require this. If yours doesn’t, use an OffsetDateTime instead. Convert like this:

    OffsetDateTime odt = i.atOffset(ZoneOffset.UTC);
    System.out.println(odt);

2019-03-31T17:11:05Z

You can see that the value is still the same, only the type is different.

What should I fix in my implementation to convert seconds to timestamp so that the resulting timestamp looks like 2019-03-31 11:45:06 ?

First, as I said, you should fix your code not to require a Timestamp, but also you are asking the impossible. As far as I know, Timestamp.toString would always produce at least one decimal on the seconds, so it would at least look like 2019-03-31 11:45:06.0.

If you do indispensably need a Timestamp for a legacy API that you cannot or don’t want to change just now, convert the Instant from before:

    Timestamp ts = Timestamp.from(i);
    System.out.println(ts);

2019-03-31 19:11:05.0

Don’t be fooled by the time looking different (19:11 instead of 17:11). Timestamp prints in my local time zone, which is Europe/Copenhagen, 2 hours ahead of UTC since summer time (DST) began on March 31. So we have still got the same point in time.

Link: Oracle tutorial: Date Time explaining how to use java.time.

Upvotes: 1

Mark Rotteveel
Mark Rotteveel

Reputation: 108939

The error suggest that you are using Timestamp.valueOf(String) (possibly with secondsValue.toString() as the argument?).

A java.sql.Timestamp is a special version of java.util.Date with nanosecond precision to serialize/deserialize SQL TIMESTAMP values. It is not a second value at all.

The constructor of Timestamp take a millisecond value, not a second value (for nanosecond precision, you need to use the separate setNanos with the sub-second nanoseconds).

In any case the proper way would be to use:

long milliseconds = ...; 
long seconds = TimeUnit.MILLISECONDS.toSeconds(milliseconds);
long truncatedMilliseconds = TimeUnit.SECONDS.toMillis(seconds);
// or truncatedMilliseconds = (milliseconds / 1000) * 1000;
Timestamp value = new Timestamp(truncatedMilliseconds);

However, since you are talking about needing a specific string format, I'm not sure you need this at all. Unless you are using JDBC to store this value in a database, you should not be using java.sql.Timestamp at all (and even when using JDBC, then it would probably be better to use java.time.LocalDatetime instead).

Upvotes: 0

Vishal
Vishal

Reputation: 714

You can use SimpleDateFormatto format the date as per your requirement. See below

    Long secondsValue = millisToSeconds(1554052265830L);
    System.out.println("millisToSeconds ---> " + secondsValue);
    Timestamp timeStamp = new Timestamp(secondsValue);
    String formattedDate = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").format(timeStamp.getTime());
    System.out.println(formattedDate);

Upvotes: 0

Related Questions