java中的日期时区转换?

java中的日期时区转换?,java,datetime,timezone,Java,Datetime,Timezone,我在寻找一种最简单的方法,将日期和时间从格林尼治标准时间转换为我的本地时间。当然,要尽可能考虑到合适的DST日期和标准 我能想到的最直接的代码是: SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String inpt = "2011-23-03 16:40:44"; Date inptdate = null; try { inptdate = sdf.parse(inpt); } catch (Pa

我在寻找一种最简单的方法,将日期和时间从格林尼治标准时间转换为我的本地时间。当然,要尽可能考虑到合适的DST日期和标准

我能想到的最直接的代码是:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String inpt = "2011-23-03 16:40:44";
Date inptdate = null;
try {
    inptdate = sdf.parse(inpt);
} catch (ParseException e) {e.printStackTrace();}   
Calendar tgmt = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
tgmt.setTime(inptdate);

Calendar tmad = new GregorianCalendar(TimeZone.getTimeZone("Europe/Madrid"));
tmad.setTime(inptdate);

System.out.println("GMT:\t\t" + sdf.format(tgmt.getTime()));
System.out.println("Europe/Madrid:\t" + sdf.format(tmad.getTime()));

但是我认为我没有得到正确的概念来理解
getTime
将返回什么。

您需要在
SimpleDateFormat
上使用设置
时区。

这里的关键是DateFormat类有一个时区。请尝试以下示例:

    SimpleDateFormat sdfgmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sdfgmt.setTimeZone(TimeZone.getTimeZone("GMT"));

    SimpleDateFormat sdfmad = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sdfmad.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));

    String inpt = "2011-23-03 16:40:44";
    Date inptdate = null;
    try {
        inptdate = sdfgmt.parse(inpt);
    } catch (ParseException e) {e.printStackTrace();}

    System.out.println("GMT:\t\t" + sdfgmt.format(inptdate));
    System.out.println("Europe/Madrid:\t" + sdfmad.format(inptdate));

对于输入,只需将时区添加到字符串中(请注意格式中的“z”):


最简单的方法是使用合适的日期时间库,而不是众所周知的麻烦的java.util.date和.Calendar类。而是使用Joda Time或Java8中的java.Time包

乔达时间
以下是2017年的答案

    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    String inpt = "2011-03-23 16:40:44";

    ZonedDateTime madridTime = LocalDateTime.parse(inpt, dtf)
            .atOffset(ZoneOffset.UTC)
            .atZoneSameInstant(ZoneId.of("Europe/Madrid"));

    System.out.println("GMT:\t\t" + inpt);
    System.out.println("Europe/Madrid:\t" + madridTime.format(dtf));
请欣赏这段代码表达意图的自然程度

代码打印出来了

GMT:        2011-03-23 16:40:44
Europe/Madrid:  2011-03-23 17:40:44
(制表符大小为8时,它很好地对齐,但StackOverflow似乎应用了4的制表符大小)

我在您的输入字符串中交换了
23
03
,我相信您是有意的。顺便说一句,不是我发现了你的错误,是
LocalDateTime.parse()
抛出了一个异常,因为没有23个月。在这方面,现代阶级比过时的阶级更有帮助


Joda Time?提到并推荐了我正在使用的
java.Time
,以及Joda Time。虽然Joda Time已经大大改进了问题中使用的过时类(
SimpleDateFormat
Calendar
GregorianCalendar
),但它现在处于维护模式;预计不会有更大的进一步发展
java.time
深受Joda time的启发。对于新代码,我看没有理由不喜欢
java.time

你如何让
TimeZone.getTimeZone(“Europe/Madrid”)
工作?我得到了错误
类型TimeZone的getTimeZone(String)方法没有定义。。。这是一段实际工作的代码片段:每天在Java 1.5上运行几次。啊,很抱歉,写这篇文章后,我发现我使用的是GWT版本的时区,而且它不允许字符串作为参数!您的日期可能是2011年第23个月的第3天??您是否打算
2011-03-23 16:40:44
?没有意识到DateFormat类有自己的时区。Java中的日期很混乱。很抱歉,答复太晚;)但是DateFormat类有一个时区,而不知道时区,这有点道理。表示某种形式日期的字符串实际上没有意义(至少没有包含在字符串中的时区信息),因此为了从简单的datetime字符串转换为日期,需要指定一个时区。同样适用于java7(这是2021年令人难以置信的事情)
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    String inpt = "2011-03-23 16:40:44";

    ZonedDateTime madridTime = LocalDateTime.parse(inpt, dtf)
            .atOffset(ZoneOffset.UTC)
            .atZoneSameInstant(ZoneId.of("Europe/Madrid"));

    System.out.println("GMT:\t\t" + inpt);
    System.out.println("Europe/Madrid:\t" + madridTime.format(dtf));
GMT:        2011-03-23 16:40:44
Europe/Madrid:  2011-03-23 17:40:44