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

Spring Data Mongo如何仅保存日期(不含时间)?

解决MongoDB仅保存日期部分的问题

嘿,我完全懂你遇到的困扰——想用Spring把日期存成纯YYYY-MM-DD格式到MongoDB,试了@DateTimeFormat的两种ISO配置,结果数据库里还是带着时间戳。这其实是因为Java的Date类型和MongoDB的存储特性在捣鬼,咱们来一步步解决:

方法一:用Java 8+的LocalDate替代Date(推荐)

LocalDate是Java 8引入的日期类,本身就只包含年、月、日,没有时间部分,完美匹配你的需求。配合Spring的注解就能直接用:

import java.time.LocalDate;
import org.springframework.format.annotation.DateTimeFormat;

public class JourneyEntity {
    // 用ISO.DATE格式处理前端的日期字符串,同时存储到MongoDB时只保留日期
    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
    private LocalDate journeyDate;

    // 别忘了添加getter和setter
    public LocalDate getJourneyDate() {
        return journeyDate;
    }

    public void setJourneyDate(LocalDate journeyDate) {
        this.journeyDate = journeyDate;
    }
}

Spring Data MongoDB对LocalDate有原生支持,存到数据库后会自动转成MongoDB的Date类型,但时间部分会默认设为00:00:00。后续查询时,你可以直接用日期范围来匹配:

// 查询2018-01-26的所有文档
db.journeys.find({
  journeyDate: {
    $gte: ISODate("2018-01-26T00:00:00Z"),
    $lt: ISODate("2018-01-27T00:00:00Z")
  }
})

方法二:手动清零Date的时间部分

如果坚持要用Java的Date类型,那在保存前需要把时间部分手动设为当天的起始时间(00:00:00):

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;

// 设置当前日期并清零时间
LocalDate today = LocalDate.now();
Date journeyDate = Date.from(today.atStartOfDay(ZoneId.systemDefault()).toInstant());

// 把这个journeyDate赋值给实体类再保存
JourneyEntity entity = new JourneyEntity();
entity.setJourneyDate(journeyDate);
journeyRepository.save(entity);

这样存到MongoDB的journeyDate就是当天零点的时间戳,查询时同样可以用上面的范围条件来精准匹配日期。

方法三:自定义MongoDB转换器,存为字符串格式

如果你希望数据库里直接存储"2018-01-26"这样的字符串,可以自定义类型转换器,让Spring Data把Date和字符串互相转换:

1. 写转换器类

import org.springframework.core.convert.converter.Converter;
import java.text.SimpleDateFormat;
import java.util.Date;

// Date转字符串
public class DateToStringConverter implements Converter<Date, String> {
    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public String convert(Date source) {
        return dateFormat.format(source);
    }
}

// 字符串转Date
public class StringToDateConverter implements Converter<String, Date> {
    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public Date convert(String source) {
        try {
            return dateFormat.parse(source);
        } catch (Exception e) {
            throw new IllegalArgumentException("日期格式错误,请使用yyyy-MM-dd", e);
        }
    }
}

2. 注册转换器到MongoDB配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import java.util.Arrays;

@Configuration
public class MongoConfig {
    @Bean
    public MongoCustomConversions mongoCustomConversions() {
        return new MongoCustomConversions(Arrays.asList(
                new DateToStringConverter(),
                new StringToDateConverter()
        ));
    }
}

之后存到MongoDB的journeyDate就是纯字符串格式,查询时直接匹配字符串即可:

db.journeys.find({journeyDate: "2018-01-26"})

为什么之前的@DateTimeFormat没用?

这里要注意:@DateTimeFormat主要是用来处理前端请求参数和后端响应的格式化,比如把前端传来的"2018-01-26"字符串转成Java的Date对象,或者把Date转成字符串返回给前端。但它不会改变MongoDB存储Date类型的本质——MongoDB的Date类型本身就包含时间戳,所以光靠这个注解没法去掉时间部分。

内容的提问来源于stack exchange,提问作者Srini Kandula

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:30:07