java - 如何将没有时区计算的原始日期/时间存储到 MongoDb

标签 java mongodb spring-boot date timezone

我从具有事件日期/时间的提供者那里得到了一些在不同位置的事件的列表(事件在不同的时区,所以日期/时间总是本地的)。我需要在得到它们时将其保存到 mongodb,但看起来 Mongo 正在使用我的本地时区对其进行转换,因此我将 18:00 保存在数据库中,而不是从 20:00 开始的事件。

我正在使用 java spring boot 应用程序,当我尝试过滤结果时,如果我选择 19:00 之后的事件,我的事件不在列表中,但它应该在那里。我想在不计算时区的情况下存储这些日期。有没有办法配置mongo不做计算?我使用的是 mongodb 驱动程序版本 3.9.0。

更新(时间字段定义):

@Temporal(TemporalType.TIMESTAMP)
@Field("time")
private LocalDateTime time;

更新 2: 我玩过 shell,当我插入类似的东西时:

var mydate2 = ISODate();
db.test.insertOne( { iso: mydate2 } );

结果是:

{ "_id" : ObjectId("5d5173dc6240209d9377677a"), "iso" : ISODate("2019-08-12T14:12:42.762Z") }

但是当我插入日期时:

var mydate2 = Date();
db.test.insertOne( { iso: mydate2 } );

结果是:

{ "_id" : ObjectId("5d51741b6240209d9377677b"), "iso" : "Mon Aug 12 2019 16:13:42 GMT+0200 (Central Europe Standard Time)" }

,所以是正确的。 我可以从 Spring 文档定义中以某种方式说我想使用 Date 吗?我应该使用 ZonedDateTime 而不是 LocalDateTime 吗?

最佳答案

我设法使用 ZonedDateTime 而不是 LocalDateTime 解决了这个问题: 在spring data mongo文件中定义

@Field("eventTime")
private ZonedDateTime eventTime;

Mongo 没有自己的 ZonedDateTime 转换器,所以我创建了自己的转换器:

public class ZonedDateTimeReadConverter implements Converter<Date, ZonedDateTime> {

    @Override
    public ZonedDateTime convert(Date date) {
        return date.toInstant().atZone(ZoneOffset.UTC);
    }
}

public class ZonedDateTimeWriteConverter implements Converter<ZonedDateTime, Date> {

    @Override
    public Date convert(ZonedDateTime zonedDateTime) {
        return Date.from(zonedDateTime.toInstant());
    }
}

我们还需要在 MongoDbConfig 类中注册它,例如:

@Configuration
public class MongoDbCommonConfiguration {

    @Bean
    public ValidatingMongoEventListener validatingMongoEventListener() {
        return new ValidatingMongoEventListener(validator());
    }

    @Bean
    public LocalValidatorFactoryBean validator() {
        return new LocalValidatorFactoryBean();
    }

    @Bean
    @Primary
    public CustomConversions customConversions() {
        ZonedDateTimeReadConverter zonedDateTimeReadConverter = new ZonedDateTimeReadConverter();
        ZonedDateTimeWriteConverter zonedDateTimeWriteConverter = new ZonedDateTimeWriteConverter();

        return new CustomConversions(Arrays.asList(zonedDateTimeReadConverter, zonedDateTimeWriteConverter));
    }
}

当我得到我的事件提供者时,我将它的 LocalDateTime 更改为 UTC 时区的 ZonedDateTime,例如:

return new Event(providerEvent.getTime().atZone(ZoneId.of("UTC")), providerEvent.getName(),...);

现在当我从 Activity 提供者那里得到 18:00 时,18:00 将被保存到 mongodb 中。

关于java - 如何将没有时区计算的原始日期/时间存储到 MongoDb,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57461759/

相关文章:

java - 使用 Java 将 PDF 转换为 XML

Java ArrayList 不允许我从外部构造函数添加

node.js - 错误消息 : MongoError: bad auth Authentication failed through URI string

java - 在 Spring Boot 测试之前初始化数据库

java - Spring Boot集成测试: Mock Environment Interface

java - 使用 Wss4jSecurityInterceptor 抛出 WRONG_DOCUMENT_ERR : A node is used in a different document than the one that created it

java - 如何在 IntelliJ IDE 中将 Spark 与 Scala 项目集成?

MongoDB 游标不返回所有文档

node.js - 不需要的多个 MongoDB 连接

java - 如何在 jsf 中使用 FacesContext?