繁体   English   中英

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。 它们为何不同,我该如何纠正。

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

今天,您(通常)不需要使用Timestamp对象。 java.sql.Timestamp类早已过时。 一旦我们将其用于与SQL数据库之间来回传输纳秒精度的时间戳值。 今天,我们改为使用Instant类。 Instant是现代Java日期和时间API java.time的类之一(有时我们使用同一API中的LocalDateTime ,这取决于您的确切要求和数据库列的数据类型)。

TimestampInstant都没有时区。 Timestamp不同, Instant始终以UTC打印(在上述输出的末尾以Z表示)。 如您所见,以上代码段已将您的CST时间20:45 CST时间正确转换为第二天UTC。

如果确实需要时间戳,通常是对于无法更改或现在不想更改的旧版API,则转换很容易:

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

2016-03-12 20:45:00.0

Timestamp.toString使用JVM的时区设置来生成字符串,因此您可以识别我们开始的时间。 因此, Timestamp包含正确的时间点。 无需以任何方式进行转换。 如果错误地将其插入数据库,则问题出在JDBC驱动程序,数据库或其他地方,如果可以的话,您应该更正此错误。

Java 6和7

如果将ThreeTen Backport添加到项目中,则与上述代码非常相似的代码将在Java 7中运行。 这是java.time类向Java 6和7的java.time移植,并且在底部包括一个链接(它是JSR-310的ThreeTen,是最早描述现代API的地方)。

    Instant inst = LocalDateTime.of(2016, Month.MARCH, 12, 20, 45)
            .atZone(ZoneId.of("America/Chicago"))
            .toInstant();
    Timestamp ts = DateTimeUtils.toSqlTimestamp(inst);

您会注意到,与Java 8的唯一区别是我们将Instant转换为Timestamp 结果当然是一样的。

我不希望依赖ThreeTen Backport,当然还有获取Timestamp 我不会像代码中那样使用不推荐使用的构造函数,即使只要没有人篡改JVM的时区设置,它就可以工作。 如果您知道想要的Timestamp等于世界标准时间02:45,则一种选择是

    Timestamp ts = Timestamp.valueOf("2016-03-12 20:45:00");

但是,它仍然取决于JVM的时区设置。

您的代码出了什么问题?

如前所述, Timestamp中没有时区,因此将Timestamp转换为UTC没有意义。

您的代码中发生了什么:

  • 不建议使用的Timestamp构造函数使用JVM的时区设置(美国/芝加哥,我认为)来构造与您的时区中的2016年3月12日晚上8.45(与UTC 3月13日下午2:45相同的时间点)对应的Timestamp
  • 您的SimpleDateFormat正确格式化为2016-03-13 02:45:00 (UTC)。
  • Timestamp.valueOf()也使用美国/芝加哥时区。 但是,在3月12日至13日之间的夜晚,夏季时间(夏令时)在该时区开始。 凌晨2时,时钟向前移动到3.因此,有没有 2:45这个夜晚。 Timestamp选择3:45。

链接

暂无
暂无

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

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