
使用@DateTimeFormat注解转换ZondDateTime
coding四月 18, 20161mins
SpringFramework
概述H2
JSR310的基于@DateTimeFormat注解的转换器实在DefaultFormattingConversionService中注册的
bash
public static void addDefaultFormatters(FormatterRegistry formatterRegistry) {...if (jsr310Present) {// just handling JSR-310 specific date and time typesnew DateTimeFormatterRegistrar().registerFormatters(formatterRegistry);}}
bash
DateTimeFormatterRegistrar#registerFormatters {...registry.addFormatterForFieldAnnotation(new Jsr310DateTimeFormatAnnotationFormatterFactory());}
分析H2
但是使用@DateTimeFormat并不能说随意的指定格式,这依赖这注解的字段类型,比如说如果像下面这样使用是不行的
bash
@DateTimeFormat(pattern = "yyyy年MM月dd日")private ZonedDateTime endTime;
因为ZonedDateTime转换的时候还需要时间以及时区信息
下面是获取Parse的逻辑
bash
AnnotationParserConverter#convertpublic Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {Annotation ann = targetType.getAnnotation(this.annotationType);if (ann == null) {throw new IllegalStateException("Expected [" + this.annotationType.getName() + "] to be present on " + targetType);}AnnotationConverterKey converterKey = new AnnotationConverterKey(ann, targetType.getObjectType());GenericConverter converter = cachedParsers.get(converterKey);if (converter == null) {Parser<?> parser = this.annotationFormatterFactory.getParser(converterKey.getAnnotation(), converterKey.getFieldType());converter = new ParserConverter(this.fieldType, parser, FormattingConversionService.this);cachedParsers.put(converterKey, converter);}return converter.convert(source, sourceType, targetType);}Jsr310DateTimeFormatAnnotationFormatterFactory#getParserpublic Parser<?> getParser(DateTimeFormat annotation, Class<?> fieldType) {DateTimeFormatter formatter = getFormatter(annotation, fieldType);return new TemporalAccessorParser((Class<? extends TemporalAccessor>) fieldType, formatter);}/*** Factory method used to create a {@link DateTimeFormatter}.* @param annotation the format annotation for the field* @param fieldType the declared type of the field* @return a {@link DateTimeFormatter} instance*/protected DateTimeFormatter getFormatter(DateTimeFormat annotation, Class<?> fieldType) {DateTimeFormatterFactory factory = new DateTimeFormatterFactory();factory.setStylePattern(resolveEmbeddedValue(annotation.style()));factory.setIso(annotation.iso());factory.setPattern(resolveEmbeddedValue(annotation.pattern()));return factory.createDateTimeFormatter();}
下面是转换的逻辑
bash
ZonedDateTime#parsepublic static ZonedDateTime parse(CharSequence text, DateTimeFormatter formatter) {Objects.requireNonNull(formatter, "formatter");return formatter.parse(text, ZonedDateTime::from);}DateTimeFormatter#parsepublic <T> T parse(CharSequence text, TemporalQuery<T> query) {Objects.requireNonNull(text, "text");Objects.requireNonNull(query, "query");try {return parseResolved0(text, null).query(query);} catch (DateTimeParseException ex) {throw ex;} catch (RuntimeException ex) {throw createError(text, ex);}}ZonedDateTime#frompublic static ZonedDateTime from(TemporalAccessor temporal) {if (temporal instanceof ZonedDateTime) {return (ZonedDateTime) temporal;}try {ZoneId zone = ZoneId.from(temporal);if (temporal.isSupported(INSTANT_SECONDS)) {long epochSecond = temporal.getLong(INSTANT_SECONDS);int nanoOfSecond = temporal.get(NANO_OF_SECOND);return create(epochSecond, nanoOfSecond, zone);} else {LocalDate date = LocalDate.from(temporal);LocalTime time = LocalTime.from(temporal);return of(date, time, zone);}} catch (DateTimeException ex) {throw new DateTimeException("Unable to obtain ZonedDateTime from TemporalAccessor: " +temporal + " of type " + temporal.getClass().getName(), ex);}}
如果没有时区信息ZoneId zone = ZoneId.from(temporal)会报错,如果没有时间信息LocalTime time = LocalTime.from(temporal);会报错
结论H2
所以上讲,@DateTimeFormat配合ZonedDateTime使用,指定的格式至少是包含时区和时间信息的,例如yyyy-MM-dd HH:mm:ss.SSSZ
评论
新的评论
上一篇
用gulp来构建后台模板
痛点 Java的后台模板引擎有几个痛点一直比较困扰我。一是模板功能对其一些引擎(swig、jinjia、pugjs)比较弱,单是一个模板继承很多引擎都需要第三方扩展,而且功能也非常的受限。二是从HTML静态页面到模板页面的转换以及后期修改的维护非常麻烦。针对这两个问题,一直希望…
下一篇
使用@DateTimeFormat注解转换ZondDateTime
Zsh 是一款功能强大的终端(shell)软件,既可以作为一个交互式终端,也可以作为一个脚本解释器。它在兼容 Bash 的同时 (默认不兼容,除非设置成 emulate sh) 还有提供了很多改进,例如: 更高效 更好的自动补全 更好的文件名展开(通配符展开) 更好的数组处理 …
