Java如何解析LDAP时间戳并转为dd.MM.yyyy HH:mm格式
解决方案
基础解析实现(Java 8+)
你遇到的20210908094049.884Z是LDAP标准的modifyTimestamp属性格式,属于UTC时区的ISO 8601变种格式,直接用JDK自带的java.time包即可完成解析转换,不需要引入额外依赖:
import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Locale; public class LdapTimeParser { // 匹配LDAP时间格式的解析器 private static final DateTimeFormatter LDAP_TIMESTAMP_PARSER = DateTimeFormatter .ofPattern("yyyyMMddHHmmss.SSSX") .withLocale(Locale.ROOT); // 目标格式输出器,可按需调整时区 private static final DateTimeFormatter TARGET_FORMATTER = DateTimeFormatter .ofPattern("dd.MM.yyyy HH:mm") .withZone(ZoneId.systemDefault()); // 如需固定时区比如东八区可写 ZoneId.of("Asia/Shanghai") public static String parseLdapTimestamp(String ldapTimestamp) { Instant instant = Instant.from(LDAP_TIMESTAMP_PARSER.parse(ldapTimestamp)); return TARGET_FORMATTER.format(instant); } // 测试用例 public static void main(String[] args) { String ldapTime = "20210908094049.884Z"; System.out.println(parseLdapTimestamp(ldapTime)); // 东八区环境输出示例:08.09.2021 17:40 } }
Spring LDAP 实体映射集成方案
如果你的项目使用Spring LDAP的ODM对象映射能力,可以直接注册自定义转换器实现自动解析,不需要每次手动处理字段:
import org.springframework.ldap.odm.annotations.Attribute; import org.springframework.ldap.odm.annotations.Entry; import org.springframework.ldap.odm.annotations.Id; import javax.naming.Name; import java.time.Instant; import java.time.format.DateTimeFormatter; import org.springframework.core.convert.converter.Converter; import org.springframework.context.annotation.Bean; import org.springframework.ldap.core.support.BaseLdapPathContextSource; import org.springframework.ldap.odm.core.impl.DefaultObjectDirectoryMapper; import org.springframework.ldap.core.LdapTemplate; // 自定义字符串转Instant转换器 public class LdapTimestampToInstantConverter implements Converter<String, Instant> { private static final DateTimeFormatter PARSER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss.SSSX").withLocale(Locale.ROOT); @Override public Instant convert(String source) { return Instant.from(PARSER.parse(source)); } } // LDAP实体类 @Entry(objectClasses = {"person", "top"}) public class LdapUser { @Id private Name dn; @Attribute(name = "modifyTimestamp") private Instant modifyTime; // 自动映射为Instant类型,后续格式化即可 // 省略getter、setter } // 注册转换器到Spring LDAP容器 @Bean public DefaultObjectDirectoryMapper objectDirectoryMapper() { DefaultObjectDirectoryMapper mapper = new DefaultObjectDirectoryMapper(); mapper.addConverter(new LdapTimestampToInstantConverter()); return mapper; } @Bean public LdapTemplate ldapTemplate(BaseLdapPathContextSource contextSource, DefaultObjectDirectoryMapper objectDirectoryMapper) { LdapTemplate ldapTemplate = new LdapTemplate(contextSource); ldapTemplate.setObjectDirectoryMapper(objectDirectoryMapper); return ldapTemplate; }
注意事项
- 禁止使用老旧的
SimpleDateFormat处理该格式,该类存在线程安全问题,且对UTC后缀的解析容错性极差 - 时区请根据业务需求显式配置,默认用
ZoneId.systemDefault()会读取服务运行环境的时区,如需全局统一建议指定固定值 - 如果你的LDAP服务返回的时间戳没有毫秒段,只需要将解析规则的pattern修改为
yyyyMMddHHmmssX即可兼容
内容的提问来源于stack exchange,提问作者SenNoRikyu
相关产品推荐
相关产品推荐

