You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MapStruct属性映射时转换日期属性的格式?

MapStruct实现不同格式日期属性映射的解决方案

嘿,这个场景我之前做项目的时候刚好碰到过,用MapStruct处理不同格式的日期转换其实有几种实用的方案,我给你一步步拆解清楚:

方法一:自定义日期转换器(最灵活)

如果你的日期格式比较特殊,或者需要复用转换逻辑,自定义转换器是最优选择。

  1. 先写一个转换器类,封装日期转换逻辑:
import org.mapstruct.Named;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateConverter {
    // 匹配源日期格式:2018-05-18T18:43:33.623+0200
    private static final SimpleDateFormat SOURCE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    // 目标日期格式:2018-05-18
    private static final SimpleDateFormat TARGET_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

    // 把Date类型转成目标格式的字符串
    @Named("dateToYmdString")
    public String convertDateToYmd(Date sourceDate) {
        if (sourceDate == null) {
            return null;
        }
        return TARGET_DATE_FORMAT.format(sourceDate);
    }

    // 如果源类的日期是字符串类型,加这个方法解析成Date
    @Named("stringToDate")
    public Date convertStringToDate(String sourceDateStr) throws ParseException {
        if (sourceDateStr == null || sourceDateStr.isBlank()) {
            return null;
        }
        return SOURCE_DATE_FORMAT.parse(sourceDateStr);
    }
}
  1. 在你的MapStruct Mapper接口里引入这个转换器,指定转换方法:
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

@Mapper(uses = DateConverter.class)
public interface MyObjectMapper {
    MyObjectMapper INSTANCE = Mappers.getMapper(MyObjectMapper.class);

    @Mapping(source = "sourceDate", target = "targetDate", qualifiedByName = "dateToYmdString")
    TargetClass convertSourceToTarget(SourceClass source);
}

注意:如果源类的日期是字符串类型,把qualifiedByName改成stringToDate即可,根据实际字段类型调整。

方法二:直接使用表达式(快速实现)

如果转换逻辑很简单,不想单独写转换器,可以直接在@Mapping里用Java表达式:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.text.SimpleDateFormat;

@Mapper
public interface MyObjectMapper {
    MyObjectMapper INSTANCE = Mappers.getMapper(MyObjectMapper.class);

    @Mapping(target = "targetDate", expression = "java(new SimpleDateFormat(\"yyyy-MM-dd\").format(source.getSourceDate()))")
    TargetClass convertSourceToTarget(SourceClass source);
}

不过这种方式要注意异常处理,最好封装成工具类避免表达式太臃肿:

// 先写个工具类
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateUtils {
    private static final SimpleDateFormat TARGET_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

    public static String formatToYmd(Date date) {
        if (date == null) {
            return null;
        }
        try {
            return TARGET_FORMAT.format(date);
        } catch (Exception e) {
            // 这里可以加日志或者自定义异常处理
            return null;
        }
    }
}

然后表达式改成:

@Mapping(target = "targetDate", expression = "java(DateUtils.formatToYmd(source.getSourceDate()))")

方法三:结合Java 8+时间API(推荐)

如果你的项目用Java 8及以上,强烈推荐用LocalDateTime、LocalDate这些新时间类,MapStruct对它们的支持非常友好,而且线程安全:

假设源类的日期是字符串类型(格式2018-05-18T18:43:33.623+0200),目标类是LocalDate或者yyyy-MM-dd格式的字符串:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;

@Mapper
public interface MyObjectMapper {
    MyObjectMapper INSTANCE = Mappers.getMapper(MyObjectMapper.class);
    // 匹配源日期格式的格式化器
    DateTimeFormatter SOURCE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

    // 自定义转换方法,把源字符串转成LocalDate
    default LocalDate convertToLocalDate(String sourceDateStr) {
        if (sourceDateStr == null) {
            return null;
        }
        OffsetDateTime offsetDateTime = OffsetDateTime.parse(sourceDateStr, SOURCE_FORMATTER);
        return offsetDateTime.toLocalDate();
    }

    // 如果目标是字符串格式,用这个方法
    default String convertToYmdString(String sourceDateStr) {
        if (sourceDateStr == null) {
            return null;
        }
        OffsetDateTime offsetDateTime = OffsetDateTime.parse(sourceDateStr, SOURCE_FORMATTER);
        return offsetDateTime.toLocalDate().format(DateTimeFormatter.ISO_LOCAL_DATE);
    }

    // 根据目标字段类型选择对应的转换方法
    @Mapping(source = "sourceDate", target = "targetDate")
    TargetClass convertSourceToTarget(SourceClass source);
}

额外注意事项

  • 所有转换逻辑都要处理null值,避免空指针异常
  • 如果用Java 8之前的Date类,SimpleDateFormat不是线程安全的,建议在方法内部创建实例,或者用ThreadLocal封装
  • 确保你的项目已经配置了MapStruct的注解处理器(比如Maven/Gradle里的依赖配置),否则不会自动生成实现类

内容的提问来源于stack exchange,提问作者du-it

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:37:06