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

Java 如何将没有时区计算的原始日期/时间存储到MongoDb,java,mongodb,spring-boot,date,timezone,Java,Mongodb,Spring Boot,Date,Timezone,我从提供者那里得到了一个不同位置的事件列表,其中包含事件日期/时间事件在不同的时区,因此日期/时间始终是本地的。我需要在得到它们时将其保存到mongodb,但看起来Mongo正在使用我的本地时区进行转换,所以我在数据库中保存了18:00而不是20:00开始的事件 我正在使用JavaSpringBoot应用程序,当我尝试筛选结果时,如果我选择19:00之后的事件,我的事件不在列表中,但应该在列表中。我想在不计算时区的情况下存储这些日期。有没有办法配置mongo不进行计算?我使用的是mongodb驱

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

我正在使用JavaSpringBoot应用程序,当我尝试筛选结果时,如果我选择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") }
{ "_id" : ObjectId("5d51741b6240209d9377677b"), "iso" : "Mon Aug 12 2019 16:13:42 GMT+0200 (Central Europe Standard Time)" }
但当我插入日期时:

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

{ "_id" : ObjectId("5d5173dc6240209d9377677a"), "iso" : ISODate("2019-08-12T14:12:42.762Z") }
{ "_id" : ObjectId("5d51741b6240209d9377677b"), "iso" : "Mon Aug 12 2019 16:13:42 GMT+0200 (Central Europe Standard Time)" }
,所以是正确的。 我能从Spring文档定义中说我想使用Date吗?我应该使用ZonedDateTime而不是LocalDateTime吗?

尝试使用Instant

Instant i = Instant.now();
ZoneId losAngelesTimeZone = ZoneId.of("America/Los_Angeles");
System.out.println(i.atZone(chicagoTimeZone));
我看不到没有时区或偏移的日期和时间

ISO 8601 因此,我建议您以标准ISO 8601格式YYYY-MM-DDTHH:MM:SS将值另存为文本。T将日期部分与时间部分分开

请注意,按字母顺序排序时,这些文本是按时间顺序排列的

LocalDate ld = LocalDate.of( 2020 , 1 , 23 ) ;
LocalTime lt = LocalTime.of( 15 , 30 ) ;
LocalDateTime ldt = LocalDateTime.of( ld , lt ) ;
String output = ldt.toString() ; 
2020-01-23T15:30

解析

LocalDateTime ldt = LocalDateTime.parse( "2020-01-23T15:30:00" ) ;

我使用ZonedDateTime而不是LocalDateTime解决了这个问题: 在spring数据mongo文档定义中

@Field("eventTime")
private ZonedDateTime eventTime;
Mongo没有自己的ZoneDateTime转换器,因此我创建了自己的:

public class ZonedDateTimeReadConverter implements Converter<Date, ZonedDateTime> {

    @Override
    public ZonedDateTime convert(Date date) {
        return date.toInstant().atZone(ZoneOffset.UTC);
    }
}
当我获得我的事件提供程序时,我会在UTC区域将其LocalDateTime更改为ZoneDateTime,如:

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

现在,当我从活动提供商那里得到18:00时,18:00将保存到mongodb

到目前为止你试过什么?你在用ISODate吗?是的,ISODate。也使用mongobee。看起来mongo在保存之前将LocalDateTime转换为日期时就是这样做的。也许我不应该在mongo文档定义中使用LocalDateTime?您应该使用UTC/GMT/Zulu,而不是local.where,how?文档定义中的字段?我将在文档中用我当前的时间域定义更新这个问题…但我想避免使用时区。我只希望我的日期/时间保存为原样。。。不会这么难吧?我遗漏了什么?通常,我收到的日期时间是ISO 1861 UTC。将其保存在UTC的DB中,并在显示时将其转换为客户端时区或应用程序用户配置时区。我想你需要保存'LocalDateTime',你需要保存时区。当我加载回它时,它是converterd-back,但当我直接使用repo进行过滤时,这不是计算偏移量。。。所以我的过滤不起作用。我设法解决了它,明天将提供答案…无法使用文本选项,因为我使用聚合,并且使用字符串而不是Iso时存在限制。我会在字符串末尾添加“Z”,以强调它是UTC:yyyy mm ddTHH:mm:SS.sssZ。它是ISO8601@Shloim你错过了问题的要点:没有考虑区域/偏移的日期和时间。因此,添加UTC的Z正是这里不应该做的事情。你是对的。我确实错过了。我习惯于这样一种约定:要么从epoch开始存储毫秒/秒,然后实际上没有时区信息,要么以UTC存储时间,然后它也是时区中立的。以yyyymmddHHMMSS格式存储时间而不包含任何时区信息的想法让我感到困惑,因为它只会带来诸如时区转换和夏令时不兼容等复杂问题。这里的ZonedDateTime违背了目的-最初它有TZ,但您将其存储在Z中。当您恢复它时,原始TZ将丢失。如果您总是希望使用Z格式的日期-使用即时-这远没有误导性,并且默认情况下支持它。