转换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
,如果发生意外输入,您还应该编写检查支票。