MapStruct Date 转 LocalDate 偏差一天问题

当使用 MapStruct 将 java.util.Date 转换为 java.time.LocalDate 时出现日期偏差一天的问题,通常是由时区处理引起的。

问题原因

  1. 时区差异Date 对象内部存储的是 UTC 时间戳,而 LocalDate 是无时区概念的本地日期
  2. 隐式转换:MapStruct 在转换时会使用系统默认时区
  3. 时间点问题:UTC 时间与本地时区时间可能存在日期差异(例如 UTC 时间 00:00 在某些时区可能是前一天的晚上)

解决方案

1. 明确指定时区

@Mapper
public interface MyMapper {
    default LocalDate dateToLocalDate(Date date) {
        return date.toInstant()
                  .atZone(ZoneId.systemDefault()) // 或指定特定时区 ZoneId.of("Asia/Shanghai")
                  .toLocalDate();
    }
}

2. 使用自定义映射方法

@Mapper
public interface MyMapper {
    @Mapping(target = "localDateProperty", source = "dateProperty", dateFormat = "yyyy-MM-dd")
    Target map(Source source);
    
    default LocalDate map(Date date) {
        if (date == null) {
            return null;
        }
        return date.toInstant().atZone(ZoneId.of("UTC")).toLocalDate();
    }
}

3. 全局配置(MapStruct 1.5+)

@MapperConfig
public interface CentralConfig {
    default LocalDate map(Date date) {
        return date == null ? null : 
            date.toInstant().atZone(ZoneOffset.UTC).toLocalDate();
    }
}

@Mapper(config = CentralConfig.class)
public interface MyMapper {
    // 自动使用中央配置的转换方法
}

验证建议

  1. 打印原始 Date 对象的 toString()getTime()
  2. 检查系统默认时区 ZoneId.systemDefault()
  3. 确保数据库连接和应用程序使用相同的时区配置

通过明确控制时区转换,可以避免 Date 到 LocalDate 转换时的日期偏差问题。

你可能感兴趣的:(java,MapStruct)