Java 解析ISO 8601字符串本地日期时间,就像在UTC中一样

Java 解析ISO 8601字符串本地日期时间,就像在UTC中一样,java,calendar,Java,Calendar,在java中,我需要使用以下格式的字符串创建日历对象: yyyy-MM-dd'T'HH:mm:ss 此字符串将始终设置为GMT时间。这是我的代码: public static Calendar dateDecode(String dateString) throws ParseException { TimeZone t = TimeZone.getTimeZone("GMT"); Calendar cal = Calendar.getInstance(t);

在java中,我需要使用以下格式的字符串创建日历对象:

yyyy-MM-dd'T'HH:mm:ss
此字符串将始终设置为GMT时间。这是我的代码:

    public static Calendar dateDecode(String dateString) throws ParseException
{
    TimeZone t = TimeZone.getTimeZone("GMT");
    Calendar cal = Calendar.getInstance(t);
    date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    Date d = date.parse(dateString);
    cal.setTime(d);
    return cal;
}
然后:

Calendar cal = Calendar.getInstance();
    try
    {
        cal = dateDecode("2002-05-30T09:30:10");
    } catch (ParseException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    int month =  cal.get(Calendar.MONTH)+1;
我得到以下输出:

Timezone: GMT+00:00 date: 2002-5-30 time: 7:30:10
你可以看出这是错误的,因为提供的时间是GMT而不是CET。我认为所发生的事情是,它认为提供的时间是在CET(这是我当前的时区)中,因此将时间从CET转换为GMT,从而从最终结果中扣除两个小时

有人能帮我吗

谢谢


顺便说一句:出于不同的原因,我不想使用JodaTime。

以下是一些代码,可以帮助您在解析TimZone之前设置TimZone:

// sdf contains a Calendar object with the default timezone.
Date date = new Date();
String formatPattern = ....;
SimpleDateFormat sdf = new SimpleDateFormat(formatPattern);

TimeZone T1;
TimeZone T2;
....
....
// set the Calendar of sdf to timezone T1
sdf.setTimeZone(T1);
System.out.println(sdf.format(date));

// set the Calendar of sdf to timezone T2
sdf.setTimeZone(T2);
System.out.println(sdf.format(date));

// Use the 'calOfT2' instance-methods to get specific info
// about the time-of-day for date 'date' in timezone T2.
Calendar calOfT2 = sdf.getCalendar();
我发现另一个类似的问题也可能有所帮助:

编辑:

这里有一个关于Java和Dates的很好的教程:

ISO 8601 您的字符串格式恰好符合标准

如果您确定日期时间值的字符串是UTC的,而不是UTC或时区的其他偏移量,则它的末尾应带有一个
Z
Z
Zulu
的缩写,意思是

在解析/生成字符串时,java.time类默认使用标准ISO 8601格式。因此,无需指定格式化模式

Instant
该类表示时间线上的一个时刻,分辨率为(小数点的九(9)位)

instant.toString():2002-05-30T09:30:10Z

ZoneDateTime
如果要查看与特定区域的挂钟时间相同的时刻,请应用
ZoneId
以获取
zoneDateTime
对象

大陆/地区
的格式指定,例如,或
太平洋/奥克兰
。切勿使用3-4个字母的缩写,如
CET
EST
IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)

zdt.toString():2002-05-30T11:30:10+02:00[欧洲/巴黎]

看这个


关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

该项目现已启动,建议迁移到类

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

从哪里获得java.time类

  • 后来
    • 内置的
    • 标准JavaAPI的一部分,带有捆绑实现
    • Java9添加了一些次要功能和修复
    • 大部分java.time功能都在中向后移植到Java6和Java7
    • 该项目专门为Android采用了ThreeTen Backport(如上所述)

该项目使用其他类扩展了java.time。这个项目是java.time将来可能添加的一个试验场。您可以在这里找到一些有用的课程,如、、和。

谢谢您帮助我进行学习。在查看SimpleDataFormat文档时,我一定是瞎了眼,没有看到您可以在那里设置时间格式。
String input = "2002-05-30T09:30:10" + "Z" ;
Instant instant = Instant.parse( "2002-05-30T09:30:10" + "Z" );
ZoneId z = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = instant.atZone( z );