我将不胜感激任何帮助查找此异常的错误:
java.text.ParseException: Unparseable date: "2007-09-25T15:40:51.0000000Z"
以及以下代码:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
Date date = sdf.parse(timeValue);
long mills = date.getTime();
this.point.time = String.valueOf(mills);
它用< code > Date Date = SDF . parse(time value)抛出expcetion。
timeValue = “2007-09-25T15:40:51.0000000Z”;
,如例外情况。
谢谢
我建议您使用 java.time,即现代 Java 日期和时间 API,用于您的日期和时间工作。您的字符串采用 ISO 8601 格式,可以直接由 java.time.Instant
类解析,而无需我们指定任何格式化程序:
String timeValue = "2007-09-25T15:40:51.0000000Z";
Instant i = Instant.parse(timeValue);
long mills = i.toEpochMilli();
String time = String.valueOf(mills);
System.out.println(time);
输出:
1190734851000
如果我们知道毫秒值永远不会为负, java.time 可以为我们将其格式化为字符串。这首先节省了显式转换为毫秒。
private static final DateTimeFormatter EPOCH_MILLI_FORMATTER
= new DateTimeFormatterBuilder().appendValue(ChronoField.INSTANT_SECONDS)
.appendValue(ChronoField.MILLI_OF_SECOND, 3)
.toFormatter(Locale.ROOT);
现在格式化很简单:
assert ! i.isBefore(Instant.EPOCH) : i;
String time = EPOCH_MILLI_FORMATTER.format(i);
而且输出还是一样的:
1190734851000
特别是如果您需要将Instant
对象格式化为程序中更多位置的字符串,我建议使用后一种方法。
首先,SimpleDateFormat
无法正确解析秒的 7 位小数。只要分数为零,结果无论如何都会正确,但想象一下一整秒后只有十分之一秒的时间,例如 2007-09-25T15:40:51.1000000Z
。在这种情况下,SimpleDateFormat
会将分数解析为一百万毫秒,而您的结果将超过一刻钟。对于较大的分数,误差可能是几个小时。
其次,正如其他人所说,格式模式字母 Z 与表示 UTC 的
Z
偏移量或与 UTC 的偏移量零不匹配。这导致了您观察到的异常。按照接受答案中的建议将 Z
放在引号中也是错误的,因为它会导致您错过字符串中的这些关键信息,再次导致几个小时的错误(在大多数时区)。
Oracle教程:Date Time,解释如何使用java.Time。
(答案现已广泛修改,感谢评论中的更正)
在Java 7中,可以使用< code>X模式来匹配ISO8601时区,其中包括特殊的< code>Z (UTC)值。
X
模式还支持显式时区,例如 01:00
这种方法正确地尊重时区指示符,并避免了仅将其视为字符串的问题,从而错误地解析了本地时区中的时间戳,而不是UTC或其他格式。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
Date date = sdf.parse("2007-09-25T15:40:51Z");
Date date2 = sdf.parse("2007-09-25T15:40:51+01:00");
这也可以用于毫秒:
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
Date date3 = sdf2.parse("2007-09-25T15:40:51.500Z");
然而,正如其他人所指出的,你的格式有7位小数秒,大概是10微秒。如果是这样,SimpleDateFormat
将无法处理此问题,并且您将得到不正确的结果,因为每0.1微秒将被解释为一毫秒,从而产生高达10000秒(数小时)的潜在总体错误。
在极端情况下,如果小数秒值为0.9999999秒,则会被错误地解释为9999999毫秒,即大约167分钟或2.8小时。
// Right answer, error masked for zero fractional seconds
Date date6 = sdf2.parse("2007-09-25T15:40:51.0000000Z");
// Tue Sep 25 15:40:51 GMT 2007
// Error - wrong hour
// Should just half a second different to the previous example
Date date5 = sdf2.parse("2007-09-25T15:40:51.5000000Z");
// Tue Sep 25 17:04:11 GMT 2007
当秒的小数部分为零时,此错误是隐藏的,如您的示例所示,但只要它们不为零,就会显现出来。
在许多情况下,通过关闭“宽松”解析,可以检测到该错误,并减少其影响,默认情况下,该解析将接受超过1秒的小数部分,并将其转换为秒/分钟/小时部分:
sdf2.setLenient(false);
sdf2.parse("2007-09-25T15:40:51.5000000Z");
// java.text.ParseException: Unparseable date: "2007-09-25T15:40:51.5000000Z"
这将捕获 millis 值大于 999 的情况,但不检查位数,因此它只是针对毫秒/微秒不匹配的部分和间接保护措施。但是,在许多实际数据集中,这将捕获大量错误,从而指示根本问题,即使某些值漏掉也是如此。
我建议总是禁用宽松的解析,除非您有特殊的需要,因为它会捕获大量错误,否则这些错误会被悄悄隐藏并传播到下游数据中。
如果你的分数秒总是零,那么你可以在这里使用其中一个解决方案,但是如果代码稍后被用于非零分数秒,那么它们将无法工作。您可能希望对此进行记录和/或断言该值为零,以避免以后的错误。
否则,您可能需要将小数秒转换为毫秒,以便SimpleDateFormat
可以正确解释它们。或者使用更新的日期时间API之一。
< code>Z代表时区字符。需要引用一下:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
问题内容: 如果能找到有关此异常的错误的帮助,我将不胜感激: 和以下代码: 它用引发异常。 ,作为例外。 谢谢。 问题答案: 代表时区字符。需要引用:
问题内容: 我正在获取以下代码 如果我注释掉该行,那么我会在输出中看到时差 我究竟做错了什么?? 问题答案: “ S”为毫秒。每秒有1000毫秒(0到999)。389362大于999。多余的389000毫秒将转换为389秒或6分29秒,并添加到时间中。
当我将格式的字符串对象转换为时,它会给我 我试着这样做:
问题内容: 当我将格式的字符串对象转换为它给我时 我正在尝试这样做: 问题答案: 这里有几个潜在的问题: 您未指定格式 您未指定语言环境 您未指定时区 您正在尝试将返回值(将是引用)转换为-,否则将失败 您想要类似:
问题内容: 我收到以下错误:“ java.text.ParseException:无法解析的日期:“ 2011年8月31日09:53:19””具有以下格式: 有人看到这个问题吗? 问题答案: 确保您使用正确的语言环境。(构造函数使用 系统默认的语言环境 ,它可能不是您要使用的 语言环境 。) 这在我的机器上工作正常: (例如,使用时会产生。)
问题内容: 我正在尝试解析以下日期时间字符串 2018-01-30T23:59:59.000 我无法理解它是哪种标准格式,例如UTC或ISO_8601 同时以以下方式进行解析: 但是它抛出以下异常: 任何帮助表示赞赏。 问题答案: 打印: 2018-01-30T23:59:59 您的字符串为ISO 8601格式。UTC或协调世界时不是一种格式,它是一种标准时间,用于定义我们各自时区中其余时间的使用
问题内容: 当我在下面的代码下运行时,出现Unparseable错误。如何将dd MMM yyyy格式转换为dd / MM / yyyy格式? 问题答案: 假设您修复了明显的语法错误,则: 您要做的就是为您需要解析的格式创建一个解析器,并为您想要的格式创建一个格式化器:
问题内容: 我收到日期这样的字符串:。我写了这样的解析代码 我得到这样的输出: 为什么它读错了?我的代码有问题还是Java无法识别此日期格式? 问题答案: 您的/ 的输入方法错误,用于“小时分钟”和“年度月份” 是用于“毫秒”(或,表示无意义) 我也建议使用,而不是作为是“白天小时(0-23)” 因此,使用… 它为我输出