Java8相当于Joda';s ISODateTimeFormat.dateTimeParser()?
我不知道如何让Java8的DateTime解析像我试图替换的Joda一样工作。问题是Joda的Java8相当于Joda';s ISODateTimeFormat.dateTimeParser()?,java,java-8,jodatime,Java,Java 8,Jodatime,我不知道如何让Java8的DateTime解析像我试图替换的Joda一样工作。问题是Joda的ISODateTimeFormat.dateTimeParser()允许我只输入YYYY,它仍然可以工作(例如,2016年将变成2016-01-01T00:00:00.000Z)。我如何从Java8获得相同的行为 代码很简单 import java.time.OffsetDateTime; import java.time.temporal.ChronoField; import org.joda.t
ISODateTimeFormat.dateTimeParser()代码>允许我只输入YYYY,它仍然可以工作(例如,2016年将变成2016-01-01T00:00:00.000Z)。我如何从Java8获得相同的行为
代码很简单
import java.time.OffsetDateTime;
import java.time.temporal.ChronoField;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
public class Java8OffsetDateTime {
public static void main(String[] args) {
String[] candidates =
{ "2016-11-21T17:54:51.841Z",
"2016-11-21T09:54:51.841-08:00",
"2016", // Java8 no can do?
"2016-11", // Java8 no can do?
"2016-11-21", // Java8 no can do?
"2016-11-21T01", // Java8 no can do?
"2016-11-21T01:02", // Java8 no can do?
"2016-11-21T01:02:03" // Java8 no can do?
};
DateTimeFormatter JodaDateTimeFormatter = ISODateTimeFormat.dateTimeParser();
for (String candidate : candidates) {
System.out.println("\ncandidate:\t\"" + candidate + "\"");
DateTime jodaDateTime = JodaDateTimeFormatter.parseDateTime(candidate);
System.out.println("Joda:\t" + jodaDateTime);
try {
OffsetDateTime java8OffsetDateTime = OffsetDateTime.parse(candidate);
System.out.println("Java8:\t" + java8OffsetDateTime);
long jodaMillis = jodaDateTime.getMillis();
long javaMillis = java8OffsetDateTime.toInstant().toEpochMilli();
System.out.printf("jodaMillis:%d %s javaMillis:%d\n",
jodaMillis,
(jodaMillis==javaMillis) ? "==" : "!=",
javaMillis);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
结果就是挑战
$ java -cp ~/work/joda-time-2.9.6/joda-time-2.9.6.jar:. Java8OffsetDateTime
candidate: "2016-11-21T17:54:51.841Z"
Joda: 2016-11-21T09:54:51.841-08:00
Java8: 2016-11-21T17:54:51.841Z
jodaMillis:1479750891841 == javaMillis:1479750891841
candidate: "2016-11-21T09:54:51.841-08:00"
Joda: 2016-11-21T09:54:51.841-08:00
Java8: 2016-11-21T09:54:51.841-08:00
jodaMillis:1479750891841 == javaMillis:1479750891841
candidate: "2016"
Joda: 2016-01-01T00:00:00.000-08:00
java.time.format.DateTimeParseException: Text '2016' could not be parsed at index 4
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1947)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1849)
at java.time.OffsetDateTime.parse(OffsetDateTime.java:402)
at java.time.OffsetDateTime.parse(OffsetDateTime.java:387)
at Java8OffsetDateTime.main(Java8OffsetDateTime.java:26)
candidate: "2016-11"
Joda: 2016-11-01T00:00:00.000-07:00
java.time.format.DateTimeParseException: Text '2016-11' could not be parsed at index 7
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1947)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1849)
at java.time.OffsetDateTime.parse(OffsetDateTime.java:402)
at java.time.OffsetDateTime.parse(OffsetDateTime.java:387)
at Java8OffsetDateTime.main(Java8OffsetDateTime.java:26)
candidate: "2016-11-21"
Joda: 2016-11-21T00:00:00.000-08:00
java.time.format.DateTimeParseException: Text '2016-11-21' could not be parsed at index 10
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1947)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1849)
at java.time.OffsetDateTime.parse(OffsetDateTime.java:402)
at java.time.OffsetDateTime.parse(OffsetDateTime.java:387)
at Java8OffsetDateTime.main(Java8OffsetDateTime.java:26)
candidate: "2016-11-21T01"
Joda: 2016-11-21T01:00:00.000-08:00
java.time.format.DateTimeParseException: Text '2016-11-21T01' could not be parsed at index 13
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1947)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1849)
at java.time.OffsetDateTime.parse(OffsetDateTime.java:402)
at java.time.OffsetDateTime.parse(OffsetDateTime.java:387)
at Java8OffsetDateTime.main(Java8OffsetDateTime.java:26)
candidate: "2016-11-21T01:02"
Joda: 2016-11-21T01:02:00.000-08:00
java.time.format.DateTimeParseException: Text '2016-11-21T01:02' could not be parsed at index 16
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1947)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1849)
at java.time.OffsetDateTime.parse(OffsetDateTime.java:402)
at java.time.OffsetDateTime.parse(OffsetDateTime.java:387)
at Java8OffsetDateTime.main(Java8OffsetDateTime.java:26)
candidate: "2016-11-21T01:02:03"
Joda: 2016-11-21T01:02:03.000-08:00
java.time.format.DateTimeParseException: Text '2016-11-21T01:02:03' could not be parsed at index 19
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1947)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1849)
at java.time.OffsetDateTime.parse(OffsetDateTime.java:402)
at java.time.OffsetDateTime.parse(OffsetDateTime.java:387)
at Java8OffsetDateTime.main(Java8OffsetDateTime.java:26)
如何从“Java8不行”中去掉那些java.time.format.DateTimeParseException
s?“案例?这将解析您的所有日期,除了有点时髦的2016-11-21T01。如果确实需要,请查看DateTimeFormatterBuilder
构造ISO\u-TIME
格式化程序的方式。它使用可选的秒字段。复制它并使分钟字段也成为可选字段
DateTimeFormatter isoDateParser = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.optionalStart()
.appendLiteral('T')
.append(DateTimeFormatter.ISO_TIME)
.toFormatter();
感谢@Tunaki提出了替代语法。这将帮助您解析您提供的输入值。相应地调整
OffsetDateTime java8OffsetDateTime = OffsetDateTime.parse(candidate, offsetDateTimeFormatter );
DateTimeFormatter customOffsetDateTimeFormatter = new DateTimeFormatterBuilder().appendPattern("yyyy[-MM][-dd['T'HH[:mm[:ss]]]][.SSSXXX]")
.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.parseDefaulting(ChronoField.NANO_OF_SECOND, 0)
.parseDefaulting(ChronoField.OFFSET_SECONDS, ZoneOffset.of("-08:00").getTotalSeconds())
.toFormatter();
测试用例:(-06:00偏移量)
输出:(-06:00偏移量)
DateTimeFormatter
是您的类。然而,需要一些时间来适应这个新的java.time包。我使用它,过了一段时间,我发现它非常灵活和强大。我写了一篇小文章,描述了如何尝试将未知格式的字符串解析为日期的一般想法。以下是链接:对于可选部件,使用[…]
语法将更简洁。看起来像是yyyy-MM-dd['T'HH[:MM[:ss]]][.SSSVV]
Hmmm.java.time.format.DateTimeParseException:Text'2016-11-21'在我试图通过此发送“2016-11-21”时无法在索引10处解析。我获取这个构建器中的DateTimeFormatter,并将其交给OffsetDateTime.parse(候选者,dtFmt)代码>,不是吗?我和你说的完全一样。在这里很好用。将测试用例添加回答案。@Veeram是的……我做错了什么。即使如此,在Java8中,如果没有大的backflip,我的用例看起来也不受支持。谢谢你的回复。我要再玩一些。也许乔达一开始帮了我太多place@Veeram您的DateTimeFormatterBuilder非常接近,但是对于通过的候选对象,除了第一个候选对象外,Java8 millis与Joda millis都不匹配(问题已经重新构造以显示这一点)。如果我能找出为什么你的格式生成器在这个案子上挣扎<代码>候选人:“2016-11-21T09:54:51.841-08:00”Joda:2016-11-21T09:54:51.841-08:00 Java8:2016-11-21T09:54:51.841Z jodaMillis:1479750891841!=javaMillis:1479722091841
我想我们赢了!“DateTimeFormatter
…需要一些时间来适应…”更真实的话还没有说出来。DateTimeFormatter是关键。
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
public class App
{
public static void main(String[] args) {
String[] candidates =
{"2016-11-21T15:54:51.841Z",
"2016-11-21T09:54:51.841-06:00",
"2016", // Java8 no can do?
"2016-11", // Java8 no can do?
"2016-11-21", // Java8 no can do?
"2016-11-21T01", // Java8 no can do?
"2016-11-21T01:02", // Java8 no can do?
"2016-11-21T01:02:03" // Java8 no can do?*/
};
DateTimeFormatter customOffsetDateTimeFormatter = new DateTimeFormatterBuilder().appendPattern("yyyy[-MM][-dd['T'HH[:mm[:ss]]]][.SSSXXX]")
.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.parseDefaulting(ChronoField.NANO_OF_SECOND, 0)
.parseDefaulting(ChronoField.OFFSET_SECONDS, ZoneOffset.of("-06:00").getTotalSeconds())
.toFormatter();
org.joda.time.format.DateTimeFormatter jodaDateTimeFormatter = ISODateTimeFormat.dateTimeParser();
for (String candidate : candidates) {
System.out.println("\ncandidate:\t\"" + candidate + "\"");
DateTime jodaDateTime = jodaDateTimeFormatter.parseDateTime(candidate);
System.out.println("Joda:\t" + jodaDateTime);
try {
OffsetDateTime java8OffsetDateTime = OffsetDateTime.parse(candidate,customOffsetDateTimeFormatter);
System.out.println("Java8:\t" + java8OffsetDateTime);
long jodaMillis = jodaDateTime.getMillis();
long javaMillis = java8OffsetDateTime.toInstant().toEpochMilli();
System.out.printf("jodaMillis:%d %s javaMillis:%d\n",
jodaMillis,
(jodaMillis == javaMillis) ? "==" : "!=",
javaMillis);
} catch (Exception e) {
e.printStackTrace();
}
}
}
candidate: "2016-11-21T15:54:51.841Z"
Joda: 2016-11-21T09:54:51.841-06:00
Java8: 2016-11-21T15:54:51.841Z
jodaMillis:1479743691841 == javaMillis:1479743691841
candidate: "2016-11-21T09:54:51.841-06:00"
Joda: 2016-11-21T09:54:51.841-06:00
Java8: 2016-11-21T09:54:51.841-06:00
jodaMillis:1479743691841 == javaMillis:1479743691841
candidate: "2016"
Joda: 2016-01-01T00:00:00.000-06:00
Java8: 2016-01-01T00:00-06:00
jodaMillis:1451628000000 == javaMillis:1451628000000
candidate: "2016-11"
Joda: 2016-11-01T00:00:00.000-05:00
Java8: 2016-11-01T00:00-06:00
jodaMillis:1477976400000 != javaMillis:1477980000000
candidate: "2016-11-21"
Joda: 2016-11-21T00:00:00.000-06:00
Java8: 2016-11-21T00:00-06:00
jodaMillis:1479708000000 == javaMillis:1479708000000
candidate: "2016-11-21T01"
Joda: 2016-11-21T01:00:00.000-06:00
Java8: 2016-11-21T01:00-06:00
jodaMillis:1479711600000 == javaMillis:1479711600000
candidate: "2016-11-21T01:02"
Joda: 2016-11-21T01:02:00.000-06:00
Java8: 2016-11-21T01:02-06:00
jodaMillis:1479711720000 == javaMillis:1479711720000
candidate: "2016-11-21T01:02:03"
Joda: 2016-11-21T01:02:03.000-06:00
Java8: 2016-11-21T01:02:03-06:00
jodaMillis:1479711723000 == javaMillis:1479711723000