转换ldap日期


问题内容

我正在以编程方式从ldap导出用户。因此,我正在从ldap检索用户。属性之一是whenCreated

我必须转换的值之一是:20090813145607.0Z直接将其拆分成以下格式:yyyyMMddHHmmss+
.0Z。问题在于应用程序正在CET时区运行,并且存储的时间是UTC,这可能由表示.0Z。是14:56 UTC,并且本地表示形式是16:56。夏季似乎是2个小时,而冬季是1个小时。

我检查了SimpleDateFormat,发现时区有一个占位符,但是它是不同的格式。

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
sdf.parse("20090813145607.0Z");

由于忽略日期时区,将显示错误的日期。

有没有办法直接转换它?


问题答案:

ISO 8601

作为提到的其他两个答案,有问题的日期时间格式由RFC 4517
轻型目录访问协议(LDAP):语法和匹配规则定义
。请参见第3.3.13节“
通用时间”

该部分说明了该LDAP格式是ISO
8601
定义的日期时间格式之一的受限版本。这种使用最少分隔符的样式在ISO
8601中被称为“基本”。

在这些格式中,Z最后是的缩写Zulu,表示UTC(与GMT基本相同)。

小数点和末尾的数字代表一秒的分数。请注意,在RFC 4517和ISO 8601中都可以使用逗号代替点(句点)。实际上,建议在ISO
8601中在点上使用逗号。RFC4517规范仅允许使用一位数字(分数的十分之一) )或完全没有点号/逗号和数字。请注意,与此相反:(a)ISO
8601允许使用任意数量的小数位,并且(b)java.time对象具有纳秒级的分辨率,最长为9位小数秒。

java.time

java.time框架是建立在Java
8和更高版本。这些类取代旧的麻烦日期时间类,如java.util.Date.Calendar,和java.text.SimpleDateFormat

现在处于维护模式Joda-
Time
项目还建议迁移到java.time。

要了解更多信息,请参见Oracle教程。并在Stack
Overflow中搜索许多示例和说明。

多的java.time功能后移植到Java 6和7在ThreeTen-
反向移植
和在进一步适于到Android
ThreeTenABP

ThreeTen-额外项目与其他类扩展java.time。该项目是将来可能向java.time添加内容的试验场。

解析中

定义一种格式样式以适合RFC4517。研究DateTimeFormatter用于模式编码的类。这应该工作:uuuuMMddHHmmss[,S][.S]X。方括号表示
可选 。我们可以容纳点或逗号。请注意秒的小数位数。该X对端允许为任何一个Z或一个偏移从-
UTC
如-08或-0830或-08:30或-083015或-08:30:15。

String input = "20090813145607.0Z";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "uuuuMMddHHmmss[,S][.S]X" );
OffsetDateTime odt = OffsetDateTime.parse ( input , f );
Instant instant = odt.toInstant ();

转储到控制台。

System.out.println ( "input: " + input + " | odt: " + odt + " | instant: " + instant );

输入:20090813145607.0Z | odt:2009-08-13T14:56:07Z | 即时:2009-08-13T14:56:07Z

当然java.time.format.DateTimeParseException,如果发生意外输入,您还应该编写检查支票。