TimeStamp.valueOf()方法 [英] TimeStamp.valueOf() method

查看:823
本文介绍了TimeStamp.valueOf()方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 在上述输出的末尾)。如您所见,上面的代码段已将世界标准时间第二天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 a Timestamp 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 into 2016-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 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.timeto 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆