AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / user-13115701

Paul Marcelin Bejan's questions

Martin Hope
Paul Marcelin Bejan
Asked: 2023-10-08 05:16:31 +0800 CST

如何正确使用java.time类?

  • 7

我知道经过 3 年的软件开发后这可能听起来很尴尬,但我正在尝试更好地理解 java.time 类以及如何使用它们来避免错误和不良实践。

在我参与的第一个项目中,使用的 java 版本是 8,但日期值存储在遗留类 java.util.Date 上

两年后,新公司、新项目使用 java 版本 17,但日期值仍然存储在遗留类 java.util.Date 中

当我看到项目上有一个 DateUtils ,其方法如下:

public static String toString_ddMMyyyy_dotted(Date date){
    LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefualt()).toLocalDateTime();
    DateTimeFormatter.ofPattern("dd.MM.yyyy").format(localDateTime);
}

public static Date getBeginOfTheYear(Date date){
    LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefualt()).toLocalDate();
    LocalDate beginOfTheYear = localDate.withMonth(1).withDayOfMonth(1);
    return Date.from(beginOfTheYear.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
}

所以我的问题是,为什么不直接使用具有非常好的 API 的 java.time 类,而不是在需要对日期进行操作时将变量转换为 LocalDate/LocalDateTime ?

我们的想法是尽快重构项目,将 Date/DateTime/Time 值存储到 java.time 类中。我从一个简单的模块开始,它将一些数据保存到 MongoDB 中。我应用了以下字段类型转换:

  • 将日期值转换为 LocalDate
  • 日期和时间值转换为 LocalDateTime

在测试过程中我立即发现一个问题,值为 2023-10-07 12:00:00 的 localDateTime 变量在 MongoDB 上保存为 2023-10-07 10:00:00 只要当数据被取回到java中,该值又回到了2023-10-07 12:00:00,但是这并没有发生,所以这是一个大问题。

首先,这种情况是仅在使用LocalDateTime时发生,还是在使用LocalDate时也会发生?

在实体/文档类上存储日期/日期时间值的最佳实践是什么?我应该使用 ZonedDateTime 而不是 LocalDateTime 吗?

java
  • 1 个回答
  • 120 Views
Martin Hope
Paul Marcelin Bejan
Asked: 2023-08-17 19:49:54 +0800 CST

自定义 SpringBoot Bean 验证

  • 6

我正在创建一个注释来验证开始/结束日期,我想确保它们不重叠。

注解:

@Documented
@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = { NonOverlappingDatesValidator.class })
public @interface NonOverlappingDates {

    String start();
    String end();

    String message() default "OVERLAPPING_OF_DATES";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
    
}

验证器:

public class NonOverlappingDatesValidator implements ConstraintValidator<NonOverlappingDates, Object> {

    private String start;

    private String end;

    /**
     * Initialize.
     */
    @Override
    public void initialize(NonOverlappingDates nonOverlappingDates) {
        start = nonOverlappingDates.start();
        end = nonOverlappingDates.end();
    }

    /**
     * Checks if is valid.
     */
    @Override
    public boolean isValid(Object instanceToValidate, ConstraintValidatorContext constraintValidatorContext) {
        Class<?> classToValidate = instanceToValidate.getClass();
        
        LocalDateTime startDate;
        LocalDateTime endDate;
        
        try {
            startDate = getLocalDateTimeFromFieldName(classToValidate, instanceToValidate, start);
            endDate = getLocalDateTimeFromFieldName(classToValidate, instanceToValidate, end);
        } catch (ReflectionException e) {
            throw new RuntimeException(e);
        }
        
        return DateTimeUtils.isBefore(startDate, endDate);
    }
    
    private LocalDateTime getLocalDateTimeFromFieldName(Class<?> classToValidate, Object instanceToValidate, String fieldName) throws ReflectionException {
        Method getter = ReflectionUtils.getPublicGetterOfFieldName(classToValidate, fieldName);
        Object value = ReflectionUtils.invokeMethod(instanceToValidate, getter);
        if (value instanceof LocalDateTime localDateTime) {
            return localDateTime;
        } else {
            throw new RuntimeException(fieldName+" is not a LocalDateTime");
        }
    }

}

待验证的DTO:

@Data
@NonOverlappingDates(start = "startDate", end = "endDate")
public class IdentityCardDTO {

    @JsonProperty
    private Long id;

    @JsonProperty
    private String name;

    @JsonProperty
    private String surname;

    @JsonProperty
    @JsonSerialize(using = LocalDateSerializer.class)
    @JsonDeserialize(using = LocalDateDeserializer.class)
    private LocalDate dateOfBirth;

    @JsonProperty
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    private LocalDateTime startDate;

    @JsonProperty
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    private LocalDateTime endDate;
    
}

我想知道是否可以直接传递我想要验证的字段的值,而不是传递字段名称然后使用反射来检索值。

java
  • 1 个回答
  • 45 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve