Java中的日期/时区问题

Java中的日期/时区问题,java,jakarta-ee,datetime,timezone,timezone-offset,Java,Jakarta Ee,Datetime,Timezone,Timezone Offset,我需要在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.getTimeZo

我需要在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);
我使用date对象在UI上打印日期

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

例如,如果我现在执行代码,我将得到1:32:50 PM,其中2:32:50 PM根据

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


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

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

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);

也许这对你有帮助,如果没有,就发表评论,我会删除我的答案

可能您向SimpleDataFormat实例传递了错误的日期。我编写了一个小程序来测试您的代码,它似乎可以工作:

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()));

        }
    }

java.util.Date没有时区,它本质上是从epoch开始的一个很长的毫秒。如果要保留时区,必须使用java.util.Calendar,或者更好的方法,使用

第二段代码就可以了

注意,java中的CET实际上是指冬季的CET和夏季的CEST,我假设这是您想要的。GMT+1实际上不会切换到夏季,所以如果您使用它,您将被困在冬季

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

解析日期时可能出现了相同的时区错误?

避免使用三字母代码 这三个字母的时区代码既不是标准的,也不是唯一的。他们对夏令时DST感到困惑。取而代之的是使用适当的方法

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

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

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

乔达时间 捆绑的java.util.Date和Calendar类是出了名的麻烦。避开它们。使用以下任一选项:

,在Java 8中新增,由Joda Time通知,由JSR 310定义,并取代旧的日期/日历类 示例代码 转储到控制台

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 );
当运行时

输入:201402714:45:28 日期时间ASUTC:2014-02-17T14:45:28.000Z 日期时间调整日期:2014-02-17T15:45:28.000+01:00 dateTimeAdjustedToParis通过格式化程序:17.02.2014 15:45:28 日期时间:2014-02-17T14:45:28.000+01:00
你能展示你的代码吗,它正在打印时间?看起来还可以-你到底是如何使用SimpleDateFormat对象的?我测试了它,在某个日期调用sdf.format,并用你的2个代码片段获得了正确的时间。我已经更新了整个代码。请现在检查您的输入日期时间20140217 14:45:28是否已经在CET中?或者该日期时间是UTC/GMT,您希望将其调整一小时,使其比UTC提前一小时?
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 );