0

我必须说,使用时区是我的克星!

在我的数据库(PostGres)中,我有一个类型为“没有时间的时间戳”区域的字段。

我保存在其中的值是 UTC 时间。

我想要做的是根据我机器的默认时区显示值。

因此,当我从数据库中检索值时,我首先必须“说”这是一个 UTC 时间,因此我将其时区设置为 UTC:

private Date lastUpdateToUTC( Date myDate)
{
    if ( myDate!= null )
    {
        SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
        dateFormat.setTimeZone( TimeZone.getTimeZone( "UTC" ) );

        System.out.println("orig: " + dateFormat.format(myDate));

        try
        {
            Date convertedDate = dateFormat.parse( dateFormat.format( myDate) );

            dateFormat.setTimeZone( TimeZone.getDefault( ) );

            System.out.println("converted: " + dateFormat.format(convertedDate));

            return dateFormat.parse( dateFormat.format( convertedDate ) );
            ....

假设 myDate 是 2013-08-05 10:44:08。

我期待的是第一个输出是 2013-08-05 10:44:08 和第二个 2013-08-05 12:44:08。

相反,我得到 2013-08-05 08:44:08 和 2013-08-05 10:44:08 ......

我的推理错误在哪里?我应该怎么做才能得到我所期望的?

4

2 回答 2

1

java.util.Date 不支持时区。

对于第一个输出,您将 dateFormat 设置为 UTC。当您提供 Date to dateFormat 时,它会将其转换为 UTC。它无法知道您的 Date 是哪个时区,它假定它是本地时区。因此,在您的情况下,它看起来像是 GMT+2,dateFormat 减去 2 以使其成为 UTC。然后你做格式化 - 解析,这不应该有任何影响,然后你将时区更改为你的本地时区并打印你的原始日期值。(这次没有任何转换)。

于 2013-08-07T03:00:25.670 回答
1

您当前的本地时区是GMT+2,这就是为什么第一个输出是T+2小时。
为了在 UTC 时区打印日期,由于+2小时偏移,日期将减去 2 小时。

intput: 2013-08-05 10:44:08      // GMT+2 timezone
orig: 2013-08-05 08:44:08        // UTC timezone
converted: 2013-08-05 10:44:08   // default timezone: GMT+2 timezone

您可以使用打印当前本地时区来了解偏移量dateFormat.getTimeZone()
以我自己为例,我的本地时区是GMT+8,偏移量是8 * 60 * 60 * 1000 = 28800000毫秒。

System.out.println("My Current Timezone: " + dateFormat.getTimeZone());
// My Current Timezone: sun.util.calendar.ZoneInfo[id="Asia/Taipei",offset=28800000,dstSavings=0,useDaylight=false,transitions=42,lastRule=null]
于 2013-08-06T14:52:24.287 回答