TimeStamp.valueOf()方法 [英] TimeStamp.valueOf() method
问题描述
public static void main(String[] args) {
Timestamp ts = new Timestamp(116, 02, 12, 20, 45, 0, 0);
Date d = new Date();
d.setTime(ts.getTime());
System.out.println(d);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
//System.out.println(ts.getTime());
System.out.println(simpleDateFormat.format(ts));
System.out.println(Timestamp.valueOf(simpleDateFormat.format(ts)));
}
在上面的代码中,最后两行显示不同的值。当前时区是CST,我想将其转换为UTC。当我进行转换时,最后两行在一小时内打印不同的值,即最后一次打印3月13日凌晨2:45和最后一次打印3月13日凌晨3:45。它们为何不同,我该如何纠正。
In above code last two lines print different values. Current time zone is CST, I wanted to convert it into UTC. When I convert it Last two lines print different values by one hour i.e., last but one print 13 mar 2:45 am and last print 13 Mar 3:45 am. Why they are different and How can I correct it.
推荐答案
Java 8
Java 8
Instant inst = LocalDateTime.of(2016, Month.MARCH, 12, 20, 45)
.atZone(ZoneId.of("America/Chicago"))
.toInstant();
System.out.println(inst);
此打印文件
2016-03-13T02:45:00Z
2016-03-13T02:45:00Z
今天,您(通常)不需要 Timestamp
对象。 java.sql.Timestamp
类早已过时。一旦我们将其用于与SQL数据库之间以纳秒级精度传输时间戳值。今天,我们为此使用 Instant
类。 Instant
是 java.time
的一类,现代Java日期和时间API(有时我们使用 LocalDateTime
来自同一API,这取决于您的确切要求和数据库列的数据类型。
Today you should not (normally) have a need for a Timestamp
object. The java.sql.Timestamp
class is long outdated. Once we used it for transferring timestamp values with nanosecond precision to and from SQL databases. Today we use the Instant
class for this instead. Instant
is one of the classes of java.time
, the modern Java date and time API (sometimes we use LocalDateTime
from the same API, it depends on your exact requirements and the datatype of your database column).
code>时间戳或 Instant
都有一个时区。与 Timestamp
不同, Instant
始终以UTC打印(以 Z $ c $表示c>在上述输出的末尾)。如您所见,上面的代码段已将世界标准时间第二天20:45 CST的时间正确转换为02:45。
Neither a Timestamp
nor an Instant
have a time zone in them. Unlike Timestamp
the Instant
always prints in UTC (denoted by the Z
at the end of the above output). As you can see, the above snippet has correctly converted your time of 20:45 CST to 02:45 the next day UTC.
如果确实需要时间戳,通常对于您现在无法更改或不想更改的旧版API,转换很容易:
If you do need a timestamp, typically for a legacy API that you cannot change or don’t want to change just now, conversion is easy:
Timestamp ts = Timestamp.from(inst);
System.out.println(ts);
2016-03-12 20:45:00.0
2016-03-12 20:45:00.0
Timestamp.toString
使用JVM的时区设置来生成字符串,因此您可以识别我们开始的时间。因此,时间戳
包含正确的时间点。无需以任何方式进行转换。如果错误地将其插入数据库,则问题出在JDBC驱动程序,数据库或其他地方,如果可以的话,您应该宁愿在此进行更正。
Timestamp.toString
uses the JVM’s time zone setting for generating the string, so you recognize the time we started out from. So the Timestamp
contains the correct point in time. There is no need to convert it in any way. If it gets inserted incorrectly into your database, the problem is with your JDBC driver, your database or somewhere else, and you should prefer to correct it there if you can.
如果将ThreeTen Backport添加到项目中,则与上述代码非常相似的代码将在Java 7中运行。这是 java.time
类到Java 6和7的反向端口,我在底部包括一个链接(对于JSR-310,它是ThreeTen,现代的API是
Code very similar to the above will work in Java 7 if you add ThreeTen Backport to your project. This is the backport of the java.time
classes to Java 6 and 7, and I include a link at the bottom (it’s ThreeTen for JSR-310, where the modern API was first described).
Instant inst = LocalDateTime.of(2016, Month.MARCH, 12, 20, 45)
.atZone(ZoneId.of("America/Chicago"))
.toInstant();
Timestamp ts = DateTimeUtils.toSqlTimestamp(inst);
您注意到与Java 8的唯一区别是我们转换的方式即时
到时间戳
。当然,结果是一样的。
You notice that the only difference from Java 8 is the way we convert the Instant
to a Timestamp
. The result is the same, of course.
如果您不希望依赖ThreeTen Backport,当然还有一些方法可以获取时间戳
。我不会像代码中那样使用已弃用的构造函数,即使只要没有人篡改JVM的时区设置,它也能正常工作。如果您知道要让 Timestamp
等于世界标准时间02:45,则一个选择是
I you don’t want a dependency on ThreeTen Backport, there are of course still ways to obtain a Timestamp
. I wouldn’t use the deprecated constructor, as you do in your code, even though it works as long as no one tampers with your JVM’s time zone setting. If you know you want a Timestamp
equal to 02:45 UTC, one option is
Timestamp ts = Timestamp.valueOf("2016-03-12 20:45:00");
不过,这仍然取决于您的JVM的时区设置。
It still depends on your JVM’s time zone setting, though.
如前所述,时间戳
没有时区,因此将 Timestamp
转换为UTC没有意义。
As mentioned a Timestamp
hasn’t got a time zone in it, so converting a Timestamp
to UTC does not make sense.
代码中会发生什么:
- 不推荐使用的
Timestamp
构造函数使用JVM的时区设置(美国/芝加哥,我假设)用于构造一个Timestamp
,该时间戳对应于2016年3月12日您所在时区(与UTC 3月13日凌晨2:45相同的时间)。 >
- 您的
SimpleDateFormat
正确将其格式化为2016-03-13 02:45:00
(UTC)。 -
Timestamp.valueOf()
也使用美国/芝加哥时区。但是,在3月12日至13日之间的夜晚,夏季时间(夏令时)在该时区开始。凌晨2点,时钟向前移动到3点。因此,今晚没有2:45。时间戳
改为选择3:45。
- The deprecated
Timestamp
constructor uses your JVM’s time zone setting (America/Chicago, I presume) for constructing aTimestamp
corresponding 12 March 2016 at 8.45 PM in your time zone (the same point in time as 13 March 2:45 AM UTC). - Your
SimpleDateFormat
correctly formats this into2016-03-13 02:45:00
(UTC). Timestamp.valueOf()
too uses America/Chicago time zone. However, on the night between 12 and 13 March summer time (daylight saving time) begins in this time zone. At 2 AM the clock is moved forward to 3. So there is no 2:45 this night.Timestamp
picks 3:45 instead.
- Oracle教程:日期时间解释如何使用
java.time
。 - Java规范请求(JSR)310 ,其中首先描述了
java.time
。 - ThreeTen Backport项目,<$ c $的Backport c> java.time 到Java 6和7。
- ThreeTenABP ,ThreeTen Backport的Android版
- 问题:如何在Android Project中使用ThreeTenABP ,并有非常详尽的解释。
- Oracle tutorial: Date Time explaining how to use
java.time
. - Java Specification Request (JSR) 310, where
java.time
was first described. - ThreeTen Backport project, the backport of
java.time
to Java 6 and 7. - ThreeTenABP, Android edition of ThreeTen Backport
- Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
这篇关于TimeStamp.valueOf()方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!