Java 8 如何在一个DateTimeFormat Java 8中处理所有区域偏移
我需要为以下有效日期创建一个Java 8 如何在一个DateTimeFormat Java 8中处理所有区域偏移,java-8,java-time,datetime-parsing,zoneddatetime,Java 8,Java Time,Datetime Parsing,Zoneddatetime,我需要为以下有效日期创建一个DateTimeFormatter String date1 = "2017-06-20T17:25:28"; String date2 = "2017-06-20T17:25:28.477777"; String date3 = "2017-06-20T17:25:28.477777Z"; String date4 = "2017-06-20T17:25:28.477777UTC"; String date5 = "2017-06-20T17:2
DateTimeFormatter
String date1 = "2017-06-20T17:25:28";
String date2 = "2017-06-20T17:25:28.477777";
String date3 = "2017-06-20T17:25:28.477777Z";
String date4 = "2017-06-20T17:25:28.477777UTC";
String date5 = "2017-06-20T17:25:28.477777-05";
String date6 = "2017-06-20T17:25:28.477777+05";
String date7 = "2017-06-20T17:25:28.477777+05:30";
String date8 = "2017-06-20T17:25:28.477777-05:30";
String date9 = "2017-06-20T17:25:28.477777+0530";
String date10 = "2017-06-20T17:25:28.477777-0530";
我尝试了以下日期-时间格式化程序,但在最后两个日期(date9
,date10
)都失败了
从date1
到date8
的所有日期都可以正常工作,但我在尝试解析最后两个日期时遇到了DateTimeParseException
:
线程“main”java.time.format.DateTimeParseException中的异常:无法分析文本“2017-06-20T17:25:28.477777+0530”,在索引29中找到未分析的文本
用于解析我正在使用的日期,如下所示
LocalDateTime.parse(date1, DATE_TIME_FORMATTER);
偏移距offsetidParser
的有效模式:
static final class OffsetIdPrinterParser implements DateTimePrinterParser {
static final String[] PATTERNS = new String[] {
"+HH", "+HHmm", "+HH:mm", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS",
}; // order used in pattern builder
当我使用有效的区域偏移模式时,我无法理解我最近两次约会失败的原因。只需颠倒可选部分的顺序即可:
private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd'T'HH:mm:ss")
.appendFraction(ChronoField.MICRO_OF_SECOND, 0, 6, true)
.optionalStart().appendZoneId().optionalEnd()
.optionalStart().appendOffset("+HHmm", "+0000").optionalEnd()
.optionalStart().appendOffset("+HH:mm", "+00:00").optionalEnd()
.optionalStart().appendOffset("+HH", "+00").optionalEnd()
.toFormatter();
这将解析所有10个示例日期时间字符串
我不太清楚它为什么有效。我假设它现在尝试在
+HH
之前使用+HHmm
,这确保它在有四个数字时得到所有四个数字,而不是保留最后两个未解析的数字。另一种选择是使用可选部分,由[]
分隔,以及相应的(VV
和x
):
每对[]
相当于一个可选开始
和可选结束
部分。请注意,我还必须将大写的S
(秒的分数)作为可选项,以解析不存在此字段的情况
其他模式(VV
和x
)对应于您需要的各种偏移。从:
模式计数等效生成器方法
------- ----- --------------------------
VV 2 appendZoneId()
x 1附件偏移量(“+HHmm”,“+00”)
xx 2附录偏移量(“+HHMM”、“+0000”)
xxx 3附录偏移量(“+HH:MM”,“+00:00”)
这适用于所有输入日期
唯一的区别是
[.SSSSSS]
在秒数字段中准确地接受6位数字(或零位数字,因为它是可选部分),而appendFraction
接受从0到6位的任何数量。要获得完全相同的行为,必须使用DateTimeFormatterBuilder
:
static final class OffsetIdPrinterParser implements DateTimePrinterParser {
static final String[] PATTERNS = new String[] {
"+HH", "+HHmm", "+HH:mm", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS",
}; // order used in pattern builder
DATE\u TIME\u FORMATTER=new DateTimeFormatterBuilder()
//日期和时间
.appendPattern(“yyyy-MM-dd'T'HH:MM:ss”)
//秒的分数,从0到6位
.appendFraction(ChronoField.MICRO_/u秒,0,6,真)
//可选偏移模式
.appendPattern(“[VV][x][xx][xxx]”)
.toFormatter();
@Eugene但我们仍然需要找到Java为什么这么做。顺序中有一点逻辑在起作用。正则表达式没有直接的可比性,仍然是“猫”。replaceFirst(“cat | cats”,“bird”)产生鸟,而相反的顺序是“cats”。replaceFirst(“cat | cat”,“bird”)
,只产生鸟。日期时间格式化程序甚至没有给我们一个或,就像在正则表达式中一样,只是一系列的部分,每个部分都是可选的,所以我想除了按顺序尝试它们之外别无选择。
DATE_TIME_FORMATTER = DateTimeFormatter
// pattern with optional sections: fraction of seconds and offsets
.ofPattern("yyyy-MM-dd'T'HH:mm:ss[.SSSSSS][VV][x][xx][xxx]");