Java - SimpleDateFormat无法解析的日期

时间:2014-02-26 23:57:02

标签: java json date

使用Java的SimpleDateFormat和Google的Gson库,我正在尝试从Minecraft库目录下载的Json文件中解析日期。使用以下SimpleDateFormat解析日期时似乎存在问题:yyyy-MM-dd'T'HH:mm:ssZ

我也尝试了以下内容:

yyyy-MM-dd'T'HH:mm:ssX
yyyy-MM-dd'T'HH:mm:ssz
yyyy-MM-dd'T'HH:mm:ssx

由于文件实际上是从网上下载的,我无法更改它。所以解决方案必须在于改变我的代码,以便不包括日期,或者从我的源代码中删除有问题的代码。这恰好是一个问题,因为我的应用程序在解析日期时死亡,并且似乎是一个解析问题,而不是文件的问题。

日期格式如下:

2013-12-18T00:41:38-0500
2013-10-25T15:00:00+02:00

上述两个日期都让它崩溃了。它们都来自不同的文件。我已经浏览了网络以获得多种解决方案,而且似乎都没有解决它。

我甚至在#technic频道上询问并浏览了TechnicLauncher源代码,但几乎找不到任何帮助。因为我使用的课程实际上与Technic Launcher完全相同,所以令我感到困惑。如果您想仔细阅读源代码,可以在这里查看:GitHub :: LauncherCore

3 个答案:

答案 0 :(得分:0)

Java 7 - 使用格式代码X

import java.text.SimpleDateFormat;

public class Test {
  public static void main(String[] args) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
    String date1 = "2013-12-18T00:41:38-0500";
    String date2 = "2013-10-25T15:00:00+08:00";

    try {
      System.out.println(dateFormat.parse(date1));      
      System.out.println(dateFormat.parse(date2));
    } catch (Exception e ) {
      System.out.println(e);
    }     
  }
}

产生输出

Wed Dec 18 05:41:38 GMT 2013
Fri Oct 25 08:00:00 BST 2013

冬天在爱尔兰跑步时。

答案 1 :(得分:0)

Java日期/时间是一个令人头疼的问题。无论如何,诀窍是我使用,似乎工作,两个xml日历解析器与SimpleDateFormat结合。我还在我的blog: a simple trick for date format上发布了一段时间,也可能是你可以使用的东西。但无论如何,这是答案。只需使用此方法并发一些小推文并插入(替换)该DateTypeAdapter类上的deserializeToDate()方法:

   private Date deserializeToDate(/*JsonElement*/String json) /*Json*/ParseException {
      Date d = null;
      String date = json; // json.getAsString();
      try {
         d = javax.xml.bind.DatatypeConverter.parseDateTime(date).getTime();
      } catch (Exception e) {} // ignore
      if (d == null) {
         SimpleDateFormat dateFormat = 
                  new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
         d = dateFormat.parse(date);      
      }
      return d;
   }

   @Test
   public void shouldParseXmlDateTime() {
      String date1 = "2013-12-18T00:41:38-0500";
      String date2 = "2013-10-25T15:00:00+08:00";

      try {
        System.out.println(deserializeToDate(date1));      
      } catch (Exception e ) {
        System.out.println(e);
      }     
      try {
         System.out.println(parse(date2));      
       } catch (Exception e ) {
         System.out.println(e);
       }     
   }

这应该产生:

Wed Dec 18 00:41:38 EST 2013
Fri Oct 25 03:00:00 EDT 2013

答案 2 :(得分:0)

TL;博士

直到错误修复:

OffsetDateTime.parse( 
    "2013-12-18T00:41:38-0500" , 
    DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ssX" )
)

当错误修复时:

OffsetDateTime.parse( "2013-12-18T00:41:38-0500" )

java.time

现代方法使用 java.time 类。

OffsetDateTime odt = OffsetDateTime.parse( "2013-10-25T15:00:00+02:00" ) ;

应该也适用于2013-12-18T00:41:38-0500。不幸的是,事实并非如此。 OffsetDateTime类有一个错误,当来自UTC的偏移部分在小时和分钟之间缺少可选的冒号时会发生错误。因此2013-12-18T00:41:38-05:00可行,但2013-12-18T00:41:38-0500无效。

作为解决方法,请定义格式设置模式。

String input = "2013-12-18T00:41:38-0500" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ssX" ) ;
OffsetDateTime odt = OffsetDateTime.parse( input , f ) ;
  

odt.toString():2013-12-18T00:41:38-05:00

有关更多讨论,请参阅类似的问题:


约达时间

更新: Joda-Time项目现在位于maintenance mode,团队建议迁移到java.time课程。这部分原封不动。

仅供参考,如果您使用Joda-Time而不是臭名昭着的java.util.Date/Calendar类,您可以直接将ISO 8601字符串直接传递给DateTime构造函数而无需麻烦格式化程序。 Joda-Time使用ISO 8601作为默认值。

DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTime = new DateTime( "2007-03-01T13:00:00Z", timeZone );

如果你想在不调整时区的情况下使用UTC,只需省略上面代码中的timeZone内容。

如果您需要java.util.Date对象用于其他目的,请从Joda-Time转换。

java.util.Date date = dateTime.toDate();

关于 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