简体   繁体   English

如何将秒转换为java.sql.Timestamp?

[英]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: 但是然后我想将secondsValue转换为java.sql.Timestamp但是以下实现导致错误:

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 ? 我应该在实现中解决哪些问题,以将秒转换为时间戳,以使最终的时间戳看起来像2019-03-31 11:45:06

java.time java.time

I am assuming that you are asking for a java.sql.Timestamp for use with your SQL database. 我假设您正在要求将java.sql.Timestamp与SQL数据库一起使用。 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. Timestamp类的设计欠佳且已过时,因此现代JDBC驱动程序或JPA实现将很乐意接受来自Java.time(现代Java日期和时间API)的类型。

    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 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. 即使JDBC规范不要求将Instant传递给PreparedStatement.setObject (该方法的重载版本之一),某些JDBC驱动程序也会直接接受它。 If yours doesn't, use an OffsetDateTime instead. 如果不是,请改用OffsetDateTime Convert like this: 像这样转换:

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

2019-03-31T17:11:05Z 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 ? 我应该在实现中解决哪些问题,以将秒转换为时间戳,以使最终的时间戳看起来像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. 首先,就像我说的那样,您应该修复代码以免使用Timestamp ,但同时您也要问不可能的事情。 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 . 据我所知, Timestamp.toString总是会在秒上产生至少一个小数,因此至少看起来像是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: 如果您确实需要旧的API的Timestamp ,而您现在不能或不想更改,则可以从之前转换Instant

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

2019-03-31 19:11:05.0 2019-03-31 19:11:05.0

Don't be fooled by the time looking different (19:11 instead of 17:11). 不要被看起来与众不同的时间所迷惑(19:11而不是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. 自3月31日夏令时(DST)开始以来,时间Timestamp在我当地的时区(欧洲/哥本哈根)打印,比世界协调时间早2小时。因此,我们仍然有相同的时间点。

Link: Oracle tutorial: Date Time explaining how to use java.time. 链接: Oracle教程:Date Time说明如何使用java.time。

You can use SimpleDateFormat to format the date as per your requirement. 您可以根据需要使用SimpleDateFormat格式化日期。 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);

The error suggest that you are using Timestamp.valueOf(String) (possibly with secondsValue.toString() as the argument?). 该错误表明您正在使用Timestamp.valueOf(String) (可能使用secondsValue.toString()作为参数?)。

A java.sql.Timestamp is a special version of java.util.Date with nanosecond precision to serialize/deserialize SQL TIMESTAMP values. java.sql.Timestampjava.util.Date的特殊版本,具有纳秒级精度,可对SQL TIMESTAMP值进行序列化/反序列化。 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). Timestamp构造函数采用毫秒值,而不是秒值(对于纳秒精度,您需要将单独的setNanos与亚秒级纳秒一起使用)。

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). 除非使用JDBC在数据库中存储该值,否则根本不应该使用java.sql.Timestamp (即使使用JDBC时,也最好使用java.time.LocalDatetime )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM