如何仅使用@DateTimeFormat 将日期@ConfigurationProperties 与时间绑定?

Posted

技术标签:

【中文标题】如何仅使用@DateTimeFormat 将日期@ConfigurationProperties 与时间绑定?【英文标题】:How to bind date @ConfigurationProperties with time only using @DateTimeFormat? 【发布时间】:2021-06-13 19:11:01 【问题描述】:

spring-boot 新手。

我正在尝试使用注释 @ConfigurationProperties 解析文件中的属性。我能够解析日期字段以外的字段。

问题是我的属性文件只有时间没有日期。即日期=09:30:00。

我可以用@DateTimeFormat(pattern = "HH:mm:ss") 解析它。但问题是,它给出的日期为 date=Thu Jan 01 09:30:00 GST 1970。

我想将日期设为今天的日期,时间为 09:30:00。有可能吗?

@ConfigurationProperties
public class Config 

    private int id;
    
    private int version;
        
    @DateTimeFormat(pattern = "HH:mm:ss")
    private Date date;
    

房产

id=12
version=2
date=09:30:00

【问题讨论】:

没有。当您在没有日期的情况下进行解析时,它会这样做。如果只是时间表示,为什么不直接使用LocalTime 而不是Date 感谢您的回复。因为我还需要一个日期来进行一些计算,比如加 1 个工作日等等。 然后使用LocalDateTime 执行此操作,并在需要时使用给定的时间作为输入。 【参考方案1】:

为什么不使用只代表时间的类型?

    @DateTimeFormat(pattern = "HH:mm:ss")
    private LocalTime time;

    public LocalDateTime getDate() 
        return LocalDateTime.of(LocalDate.now(), time);
     

【讨论】:

似乎是一个干净的解决方案。谢谢【参考方案2】:

您得到的输出与预期的一样,因为使用SimpleDateFormat 将字符串解析为java.util.Date,默认日期时间为January 1, 1970, 00:00:00 GMT

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Main 
    public static void main(String[] args) throws ParseException 
        String text = "09:30:00";
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        Date date = sdf.parse(text);
        System.out.println(date);
    

我的时区(欧洲/伦敦)的输出:

Thu Jan 01 09:30:00 GMT 1970

注意java.util.Date 对象不是像modern date-time types 那样的真实日期时间对象;相反,它表示自称为“纪元”的标准基准时间以来的毫秒数,即January 1, 1970, 00:00:00 GMT(或 UTC)。当您打印java.util.Date 的对象时,它的toString 方法会返回JVM 时区中的日期时间,从这个毫秒值计算得出。如果您需要在不同的时区打印日期时间,则需要将时区设置为 SimpleDateFormat 并从中获取格式化字符串。 java.util 日期时间 API 及其格式化 API SimpleDateFormat 不仅已过时,而且由于许多此类事情而容易出错。建议完全停止使用,改用modern date-time API1

以下是几个选项:

    推荐:使用真正代表时间的LocalTime
    @DateTimeFormat(pattern = "HH:mm:ss")
    private LocalTime time;
    肮脏的方式:将您的字段声明为String,并在您的业务逻辑中对其进行解析,使其容易出错且很脏。
    private String time;

我强烈建议选择第二个选项。

使用LocalTime的快速演示:

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main 
    public static void main(String[] args) 
        String text = "9:30:00";

        // The optional part can be put inside square bracket
        DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("H:m[:s]", Locale.ENGLISH);
        LocalTime time = LocalTime.parse(text, dtfInput);

        // Default implementation of LocalTime#toString omits the seconds part if it is zero
        System.out.println(time);

        // Custom output
        DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("HH:mm:ss", Locale.ENGLISH);
        String formatted = dtfOutput.format(time);
        System.out.println(formatted);
    

输出:

09:30
09:30:00

Trail: Date Time 了解有关现代日期时间 API 的更多信息。


1.出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7。如果您正在为android 项目和您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。

【讨论】:

【参考方案3】:

不要使用旧的和过时的类 Date。查看包java.time,特别是在您的情况下 - 类LocalTime。

将您的代码更改为: @ConfigurationProperties 公共类配置

private int id;

private int version;
    
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm:ss")
private LocalTime date;

这应该可行。您可能需要添加以下依赖项:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.6.0</version>
</dependency>

这是这个问题的修改答案:Spring Data JPA - ZonedDateTime format for json serialization

【讨论】:

我认为 @DateTimeFormat(pattern = "HH:mm:ss") 会做同样的事情。为什么要通过添加额外的依赖来使其复杂化? @Kuldeep.b - 我不知道 @DateTimeFormat(pattern = "HH:mm:ss") 是否有效。找出答案的最简单方法是尝试。我知道我在回答中写的内容肯定有效。至于依赖,无论如何你都需要它。可能在某些更高版本的 JDK 中它已经在里面,所以您可能不需要显式添加它。无论如何,我很想知道最后哪一个对你有用。因此,如果您愿意,请写评论。 感谢您的评论,crizzis (***.com/a/66656415/10673161) 给出的答案对我有用。

以上是关于如何仅使用@DateTimeFormat 将日期@ConfigurationProperties 与时间绑定?的主要内容,如果未能解决你的问题,请参考以下文章

使用@DateTimeFormat 的日期时间解析问题

日期格式化时注解@DateTimeFormat无效的问题分析

日期格式化时注解@DateTimeFormat无效的问题分析

如何使用 Joda Time 解析包含时区的日期

日期Date操作的优化

日期格式化时注解@DateTimeFormat无效的问题分析