这个日期格式是什么?2011-08-12T20:17:46.384Z

666
我有以下日期:2011-08-12T20:17:46.384Z。这是什么格式?我正在尝试通过DateFormat.getDateInstance().parse(dateStr)在Java 1.4中解析它,但我收到了“java.text.ParseException:无法解析的日期:“2011-08-12T20:17:46.384Z” ”的错误信息。
我认为我应该使用SimpleDateFormat进行解析,但我必须先知道格式字符串。到目前为止,我只有yyyy-MM-dd,因为我不知道此字符串中的T是什么意思——与时区相关的东西吗?这个日期字符串来自Files CMIS下载历史媒体类型上显示的lcmis:downloadedOn标记。

95
这是ISO 8601标准。 - Tomasz Nurkiewicz
5
@TomaszNurkiewicz,不是这样的。ISO8601结尾没有Z。 - t1gor
8
ISO8601允许在结尾加上一个Z。请参考上面的链接,查找UTC。 - Jonathan Rosenne
8
@t1gor,末尾的“Z”代表“Zulu”,意思是协调世界时(UTC)。这种格式当然是ISO 8601标准日期时间文本格式的一种。顺便说一下,这些标准格式默认在java.time类中使用。 - Basil Bourque
5
FYI,旧日期时间类(如java.util.Datejava.util.Calendarjava.text.SimpleDateFormat)现在已经不再使用,已被集成到Java 8和Java 9中的Java.time类所取代。请参阅Oracle的教程 - Basil Bourque
12个回答

-1

这种技术将java.util.Date转换为UTC格式(或其他任何格式),然后再转换回来。

定义一个类,如下所示:

import java.util.Date;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class UtcUtility {

public static DateTimeFormatter UTC = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withZoneUTC();


public static Date parse(DateTimeFormatter dateTimeFormatter, String date) {
    return dateTimeFormatter.parseDateTime(date).toDate();
}

public static String format(DateTimeFormatter dateTimeFormatter, Date date) {
    return format(dateTimeFormatter, date.getTime());
}

private static String format(DateTimeFormatter dateTimeFormatter, long timeInMillis) {
    DateTime dateTime = new DateTime(timeInMillis);
    String formattedString = dateTimeFormatter.print(dateTime);
    return formattedString;
}

}

然后像这样使用它:

Date date = format(UTC, "2020-04-19T00:30:07.000Z")

或者

String date = parse(UTC, new Date())

如果需要,您还可以定义其他日期格式(不仅限于UTC)


java.util.DateJoda-Time项目早在多年前就被现代的JSR 310中定义的java.time类所取代。这里的建议早已过时。 - Basil Bourque
java.time是在Java 8中引入的。这个问题特别涉及到Java 1.4,因此我故意避免使用较新的类。这个解决方案适用于旧的代码库。我想作者可以将他的代码库移植到Java 8,但这并不总是简单、高效或必要的。 - Gapmeister66

-2

@John-Skeet 给了我解决这个问题的线索。作为一个年轻的程序员,这个小问题很容易被忽略,也很难诊断。所以我分享它,希望能帮助到别人。

我的问题是我想解析以下包含时间戳的字符串,来自我无法控制的 JSON,并将其放入更有用的变量中。但我一直在遇到错误。

因此,考虑以下内容(请注意 Pattern() 内部的字符串参数);

String str = "20190927T182730.000Z"

LocalDateTime fin;
fin = LocalDateTime.parse( str, DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss.SSSZ") );

错误:

Exception in thread "main" java.time.format.DateTimeParseException: Text 
'20190927T182730.000Z' could not be parsed at index 19

问题出在哪里呢?Pattern结尾的Z需要像T一样用'Z'包裹起来。将"yyyyMMdd'T'HHmmss.SSSZ"改为"yyyyMMdd'T'HHmmss.SSS'Z'"即可解决。从Pattern中完全删除Z也会导致错误。
坦白说,我认为Java类应该已经预料到了这一点。

2
这个问题已经在这里这里得到了回答。而且你的解决方案是错误的。虽然T是一个字面量并需要加引号,但Z是一个偏移量(为零)并需要被解析为这样,否则你将得到错误的结果。我不知道你所说的它没有被预料到是什么意思,我相信它已经被预料到了。 - Ole V.V.
2
不,不,不要忽略 Z。你正在丢弃有价值的信息。在忽略时区或UTC偏移量的情况下处理日期时间值就像在忽略货币的情况下处理金额一样! - Basil Bourque
2
T 只是将日期部分与时间部分分开,没有任何含义。另一方面,Z 确实添加了含义。 - Basil Bourque
Ole,感谢提供的链接。我一定会阅读它们。我承认作为一个年轻人,我肯定可能是错的。我只是想说,将Z用单引号括起来,就像在模式中的char一样,解决了错误。我的批评是,设计类“pattern”部分的人本可以编写代码以处理'Z'(或不同的时区?)和'T'是否被包含在''中。因为他们没有这样做,所以这是独特的。我正在处理的格式来自商业API的JSON,已解析为字符串。但我需要将所有内容解析为日期时间日历等,以使它们更有用。 - spencemw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接