【问题标题】:issue with date/timezone in JavaJava中的日期/时区问题
【发布时间】:2014-02-17 13:33:56
【问题描述】:

我需要在我的 java 应用程序中显示 CET 中的时区。 我正在使用以下代码来实现这一点。

String OLD_FORMAT = "yyyyMMdd HH:mm:ss";
String NEW_FORMAT = "dd.MM.yyyy HH:mm:ss";
String date = "20140217 14:45:28";

SimpleDateFormat sdf = new SimpleDateFormat(OLD_FORMAT);

TimeZone zone = TimeZone.getTimeZone("GMT+1");
sdf.setTimeZone(zone);

Date d = null;
d = sdf.parse(date);
sdf.applyPattern(NEW_FORMAT);
date = sdf.format(d);

我正在使用日期对象在 UI 上打印日期。

    TimeZone zone = TimeZone.getTimeZone("CET");
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
    sdf.setTimeZone(zone);

但使用上述任一代码,我得到的 GMT 时间比 CET 晚一小时。

例如,如果我现在执行代码,我将得到 1:32:50 PM 其中的 2:32:50 PM 根据http://wwp.greenwichmeantime.com/time-zone/europe/european-union/central-european-time/

有人知道这里可能出了什么问题吗?

更新:我发现了问题。我犯了一个愚蠢的错误,因为我必须先将时间设置为格林威治标准时间(我得到的日期时间是格林威治标准时间),然后将其更改为 CET。它现在工作。非常感谢大家的回复。

【问题讨论】:

  • 你能显示你的代码吗,打印时间?
  • 看起来不错 - 您究竟如何使用 SimpleDateFormat 对象?
  • 我对其进行了测试,在 Date 上调用 sdf.format 并使用您的 2 代码 sn-p 获得适当的时间。
  • 我已经更新了整个代码。请立即查看
  • 您输入的日期时间20140217 14:45:28 已经在 CET 中了吗?或者是 UTC/GMT 的日期时间,您想将其调整一小时以比 UTC 提前一小时?

标签: java jakarta-ee datetime timezone timezone-offset


【解决方案1】:

也许您将错误的日期传递给 SimpleDateFormat 实例。我写了一个小测试你的代码,它似乎工作:

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;

    public class Test {
        public static void main(String[] args) {
            TimeZone zone = TimeZone.getTimeZone("GMT+1");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
            sdf.setTimeZone(zone);

            TimeZone zone2 = TimeZone.getTimeZone("CET");
            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
            sdf2.setTimeZone(zone2);

            Calendar c = Calendar.getInstance();
            c.set(Calendar.HOUR_OF_DAY, 15);
            c.set(Calendar.MINUTE, 0);
            c.set(Calendar.SECOND, 0);
            c.setTimeZone(TimeZone.getTimeZone("GMT+3"));

            System.out.println(sdf.format(c.getTime()));
            System.out.println(sdf2.format(c.getTime()));

        }
    }

【讨论】:

    【解决方案2】:

    java.util.Date 没有 TimeZone,它本质上很长(自纪元以来的毫秒数)。如果要保留时区,必须使用java.util.Calendar,甚至更好,使用joda-time

    【讨论】:

      【解决方案3】:

      第二段代码应该可以解决问题。

      请注意,Java 中的 CET 实际上意味着冬季的 CET 和夏季的 CEST,这就是我所假设的。 GMT+1 实际上不会切换到夏令时,所以如果你使用它,你会被困在冬令时。

      如果输出的值仍然是错误的,那么你给它的格式化日期是错误的。

      也许您在解析日期时犯了同样的时区错误?

      【讨论】:

        【解决方案4】:

        避免使用 3 字母代码

        这些三个字母的时区代码既不标准化也不唯一。他们对夏令时(DST)感到困惑。而是使用正确的time zone names

        +01:00 有几十个这样的名称。选择一个代表适用于 DST 和其他异常情况的规则。我的示例代码任意选择了巴黎时区。

        令人困惑的问题

        我无法理解您的输入字符串是表示 UTC 的日期时间还是已经在 +01:00 时区。下面的示例代码有两种变体,涵盖了这两种情况。

        此外,如果您进行搜索,您会发现您的问题已经在 StackOverflow 上被多次询问和回答。

        乔达时间

        捆绑的 java.util.Date 和 Calendar 类是出了名的麻烦。避开他们。使用任一:

        • Joda-Time
        • java.time.* package,Java 8 中的新功能
          (由 Joda-Time 提供信息,由 JSR 310 定义,取代旧的 Date/Calendar 类)

        示例代码

        String input = "20140217 14:45:28";
        
        // Formatters
        DateTimeFormatter formatterInput = DateTimeFormat.forPattern( "yyyyMMdd HH:mm:ss" );
        DateTimeFormatter formatterOutput = DateTimeFormat.forPattern( "dd.MM.yyyy HH:mm:ss" );
        
        // Use a proper time zone name rather than 3-letter codes.
        DateTimeZone timeZoneParis = DateTimeZone.forID( "Europe/Paris" );
        
        // If that input was meant to be in UTC, and then adjusted to +01:00.
        DateTime dateTimeAsUtc = formatterInput.withZone( DateTimeZone.UTC ).parseDateTime( input );
        DateTime dateTimeAdjustedToParis = dateTimeAsUtc.withZone( timeZoneParis );
        
        // Or, if that input was already in +01:00.
        DateTime dateTimeAsParis = formatterInput.withZone( timeZoneParis ).parseDateTime( input );
        

        转储到控制台...

        System.out.println( "input: " + input );
        System.out.println( "dateTimeAsUtc: " + dateTimeAsUtc );
        System.out.println( "dateTimeAdjustedToParis: " + dateTimeAdjustedToParis );
        System.out.println( "dateTimeAdjustedToParis thru formatter: " + formatterOutput.print( dateTimeAdjustedToParis ) );
        System.out.println( "dateTimeAsParis: " + dateTimeAsParis );
        

        运行时……

        input: 20140217 14:45:28
        dateTimeAsUtc: 2014-02-17T14:45:28.000Z
        dateTimeAdjustedToParis: 2014-02-17T15:45:28.000+01:00
        dateTimeAdjustedToParis thru formatter: 17.02.2014 15:45:28
        dateTimeAsParis: 2014-02-17T14:45:28.000+01:00
        

        【讨论】:

          【解决方案5】:

          我使用以下代码获取我所在国家/地区的日期和时间;

          String TIME_SERVER = "time-a.nist.gov";   
          NTPUDPClient timeClient = new NTPUDPClient();
          InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
          TimeInfo timeInfo = timeClient.getTime(inetAddress);
          long returnTime = timeInfo.getMessage().getTransmitTimeStamp().getTime();
          Date time = new Date(returnTime);
          

          也许它对你有帮助,如果没有,只需发表评论,我将删除我的答案。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-10-25
            • 1970-01-01
            • 1970-01-01
            • 2018-03-21
            • 2016-12-14
            • 2015-05-24
            相关资源
            最近更新 更多