DateTimeFormatter(datetimeformatter注解用法)

http://www.itjxue.com  2023-01-29 05:56  来源:未知  点击次数: 

在Java中,以下哪种定义,可以得到4位年2位月2位日,24小时制的格式()(2分?)?

LocalDateTime dateTime = LocalDateTime.now();

String str = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

System.out.println(str);

jdk1.8中DateTimeFormatter.ofPattern线程安全问题

你将Date对象和模板对象都做为参数传进静态方法就没有线程安全问题了

java 判断一个时间是不是今天的时间范围内

public?class?Test?{

????/**

?????*?java?判断一个时间是不是今天的时间范围内

?????*?@param?args

?????*/

????public?static?void?main(String[]?args)?{

????????String?time?=?"2017-09-27?11:20:45";

????????DateTimeFormatter?dtf?=?DateTimeFormatter.ofPattern("uuuu-MM-dd?HH:mm:ss");

????????LocalDateTime?localTime?=?LocalDateTime.parse(time,?dtf);

????????LocalDateTime?startTime?=?LocalDate.now().atTime(0,?0,?0);

????????LocalDateTime?endTime?=?LocalDate.now().atTime(23,?59,?59);

????????//如果小于今天的开始日期

????????if?(localTime.isBefore(startTime))?{

????????????System.out.println("时间是过去");

????????}

????????//如果大于今天的开始日期,小于今天的结束日期

????????if?(localTime.isAfter(startTime)??localTime.isBefore(endTime))?{

????????????System.out.println("时间是今天");

????????}

????????//如果大于今天的结束日期

????????if?(localTime.isAfter(endTime))?{

????????????System.out.println("时间是未来");

????????}

????}

}

怎样用DateTimeFormatter解决数据库中查询时间多了一个.0

数据库表add中有一个入住时间字段(如rf)。

入住时间与现在的时间差=datediff("h",rs("rf"),now())'入住到现在的时间,其中H为小时数

spring类型转换器(三)

Converter用来将源数据类型转换目标数据类型,不过有时候一个数据类型会对应不同格式的字符串,如日期类型在不同国家显示的字符是不一样的,需要根据Locale进行转换,或者需要将日期类型转换为不同格式化的字符串,spring针对这种情况提供了Formatter接口来针对格式化进行处理。

格式化Formatter其实也是一种Converter,只是两个互转类型之间, 有一个固定是String类型 ,Formatter实现了不同格式的String类型与其他类型的类型互转

Formatter主要针对的是Number类型和日期类型。Spring对这两种类型的子类和字符串之间的转换提供了格式化实现,下面以日期类型的转换为例说明。

Formatter接口继承了Printer和Parser接口,一个用于将对象格式化为本地化的字符串,一个将字符串转换为对象。

AnnotationFormatterFactory集成了注解和Formatter。可以创建带有Annotation性质的Printer和Parser对象。

在上章节的继承图中可以看到FormattingConversionService继承了GenericConversionService。同时实现了FormatterRegistry和ConverterRegistry接口

FormatterRegistry扩展了ConverterRegistry接口,额外提供了注册Formatter、AnnotationFormatterFactory的功能

FormatterRegistrar接口用于批量注册Formatter的接口

spring提供了FormattingConversionService的默认实现DefaultFormattingConversionService,使用的时候一般都是直接使用这个类。

首先来看DefaultFormattingConversionService,在BeanFactory中只接收一个ConversionService变量,所以只能给spring容易配置一个ConversionService。那么到底应该用DefaultFormattingConversionService还是用DefaultConversionService?让我们来看DefaultFormattingConversionService中的实现

从源码可以看出,DefaultFormattingConversionService完全是对DefaultConversionService的扩展,在构造函数中调用了DefaultConversionService的addDefaultConverters完全拥有了DefaultConversionService所有的功能,所以只需要使用DefaultFormattingConversionService就可以

DefaultFormattingConversionService创建完成之后除了添加Converters,还注册了一些Formatters,这些Formaters主要是spring提供的用于针对 日期类型 、 Number类型 、 货币金额 进行格式化转换

接下来分析下Formater的注册功能。通过上述分析我们可以知道,Formater实质上是Class?和String之间的互转,所以在注册的时候,只需要提供Class?、Printer和Parser。来看FormattingConversionService类中的实现

可以看到的是注册Formater的过程,就是注册了一对Converter。注册Converter的过程已经在前文分析过,在这里我们来一起看下PrinterConverter和ParserConverter类。

可以看出PrinterConverter类型实现GenericConverter,用于实现传入类型到字符串的转换,具体的转换功能委托给参数Printer实现类对象实现。这里相当于是一个插件类保留。可以通过Printer实现任何类型到String类型的转换。

再来看ParserConverter

ParserConverter跟PrinterConverter实现了一个反方向的转换,至此注册通过一个Formater接口实现类,就可以完成Formater实现类中泛型到String类型之间的互转。

例如注册 LocalDateTime的转换器,实现LocalDateTime和String类型的互转

可以看到使用一个类TemporalAccessorPrinter和TemporalAccessorParser,并都传入了一个参数DateTimeFormatter,众所周知LocalDateTime和String格式化就是通过DateTimeFormatter来实现。那么我们猜测TemporalAccessorParser其实就是对DateTimeFormatter的封装调用

可以看到TemporalAccessorPrinter就是调用的DateTimeFormatter完成格式化的,不过这里使用到了ThreadLocal,可以先不管,TemporalAccessorParser中同理也会使用DateTimeFormatter完成String到日期的转换

Formatter的注册最终是注册了一对Converter,所以格式化转换完全就是Converter逻辑的实现,在前文已经分析过了,这里就不再赘述。

分析完了Formatter的注册和转换过程,一起来看下FormatConversionService提供了另外一种注册。前文提到了可以通过在对象字段上声明一个注解,在注解中指定格式化后字符串格式。这个功能就是通过AnnotationFormatterFactory来实现的。来看FormatConversionService的 addFormatterForFieldAnnotation() 方法

AnnotationFormatterFactory的注册,首先需要获取的就是AnnotationFormatterFactory泛型中的注解类型。然后通过 getFieldTypes() 获取所有声明的可以进行转换类型集合,然后循环注册了两个类型转换器AnnotationPrinterConverter和AnnotationParserConverter。那么来看一下AnnotationPrinterConverter到底如何完成可配置的类型转换的

可以看到的是,AnnotationPrinterConverter实现了ConditionalGenericConverter接口,在 matches() 方法中声明了该转换器只会作用于Class?上有指定的注解的类型。在convert方法中最终创建了一个PrinterConverter对象,使用PrinterConverter完成格式化的功能,这个在上面已经分析过了。唯一的不同就是Printer的获取。使用annotationFormatterFactory获取printer,并将注解作为参数传递进去。所以可以我们可以实现AnnotationFormatterFactory的 getPrinter() 方法提供转换为字符串的功能即可,通过看以通过参数annotation获取用户配置的格式。实现格式的可配置。

同样在AnnotationParserConverter中实现String到Class?的转换,调用AnnotationFormatterFactory获取Parser然后创建一个ParserConverter来实现类型转化。需要注意的是 注解只能添加在非String类型那一方上。

通过封装封装注册AnnotationPrinterConverter和AnnotationParserConverter,用户需要做的就只有是实现AnnotationFormatterFactory,在泛型中指定注解,然后实现了 getPrinter() 和 getParser() 来实现Class?和String之间的转换,其他的调用直接走Converter流程。来看Date类型格式化的实现

在DateFormatterRegistrar中,在注册Formatters之前,先注册了日期类型的一些converter,这里先不去管这个。最主要的是 addFormatterForFieldAnnotation 方法,通过这个方法完成对Formater的注册

来看下DateTimeFormatAnnotationFormatterFactory实现了AnnotationFormatterFactory。并指定注解为DateTimeFormat。

可以看到的是在 getFieldType() 声明了支持转换的有Date、Calendar、Long。可以看到 getPrinter() 和 getFormatter() 方法返回了一个DateFormatter对象,并将用户配置的注解信息注入到这个DateFormatter对象中

接下来就是最终的格式化实现就是这个DateFormatter对象了。大家想一下,一般针对Date类型的格式化都会用什么呢?想必大家都猜到了,没错就是SimpleDateFormat。在DateFormatter中就是创建了一个SimpleDateFormat来实现类型和字符串的转换的

至此就实现了Formatter的注册和使用。那么在spring中是如何使用的呢?

没错就注册一个id为conversionService的FormattingConversionServiceFactoryBean对象。使用这个就可以了,不需要再注册ConversionServiceFactoryBean了。

timeformat怎么改成localtime

如何将String解析/转换为LocalTime对象? Java中是否有任何内置函数可以使我做到这一点?

推荐答案

只需使用java.time.format.DateTimeFormatter:

DateTimeFormatter parser = DateTimeFormatter.ofPattern("h[:mm]a");

LocalTime localTime = LocalTime.parse("10AM", parser);

解释模式:

h:一天中的上午/下午(从1到12),用1或2位数字

[]:可选节的定界符(其中的所有内容都是可选的)

:mm:一个:字符,后跟两位数字的分钟数

a:AM/PM的代号

(责任编辑:IT教学网)

更多

相关XML/XSLT文章

推荐XML/XSLT文章