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

时间:2012-07-03 10:44:34

标签: java calendar

在java中,我需要以String格式从String中创建一个Calendar对象:

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,因此从最终结果中减去两个小时。

有人可以帮我吗?

由于

Btw:我不希望因为不同的原因而使用JodaTime。

2 个答案:

答案 0 :(得分:4)

以下是一些代码可以帮助您在解析它们之前设置timzones:

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

我发现的另一个类似问题也可能有所帮助:How to set default time zone in Java and control the way date are stored on DB?

编辑:

这是一篇关于Java& amp;日期:http://www.tutorialspoint.com/java/java_date_time.htm

答案 1 :(得分:0)

ISO 8601

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

如果您确定日期时间值的字符串是针对UTC而不是某个其他偏离UTC或时区的字符串,那么它最后应该带有ZZZulu的缩写,表示UTC

String input = "2002-05-30T09:30:10" + "Z" ;

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

Instant

Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。

Instant instant = Instant.parse( "2002-05-30T09:30:10" + "Z" );
  

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

ZonedDateTime

如果您希望看到与特定区域的挂钟时间相同的时刻,请应用ZoneId来获取ZonedDateTime对象。

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用诸如CETESTIST之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的( !)。

ZoneId z = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = instant.atZone( z );
  

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

请参阅此code run live at IdeOne.com

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore