java保留时间存在差异(以毫秒为单位)
我试图使用mongodb获取一些带有日期字段的记录,下面显示了示例记录,并希望将使用jayway jsonpath解析的日期字段转换为java.util.date长整数。转换的长整数与原始整数不匹配。请帮忙 测试仪集合中的样本记录:java保留时间存在差异(以毫秒为单位),java,mongodb,datetime,milliseconds,Java,Mongodb,Datetime,Milliseconds,我试图使用mongodb获取一些带有日期字段的记录,下面显示了示例记录,并希望将使用jayway jsonpath解析的日期字段转换为java.util.date长整数。转换的长整数与原始整数不匹配。请帮忙 测试仪集合中的样本记录: { "_id" : ObjectId("5b3fe6f91e618afb473dc644"), "dateField" : ISODate("2018-07-06T15:46:55.819Z") } 使用jongo获取记录的Java代码如下: Li
{
"_id" : ObjectId("5b3fe6f91e618afb473dc644"),
"dateField" : ISODate("2018-07-06T15:46:55.819Z")
}
使用jongo获取记录的Java代码如下:
List<Tester> list= jongo.runCommand("{aggregate : 'tester',pipeline:[],cursor : {batchSize :10}}")
.field("cursor")
.as(Tester.class);
for(Tester t : list)
{
System.out.println("dateField test: : : : "+t.getDateField()+" : : : : "+t.getDateField().getTime());
// Output is perfectly fine : dateField test: : : : Fri Jul 06 21:16:55 IST 2018 : : : : 1530892015819
Gson gson = new Gson();
String str = gson.toJson(t);
DocumentContext docCtx = JsonPath.parse(str);
JsonPath jsonPath = JsonPath.compile("$.dateField");
Object obj = docCtx.read(jsonPath);
System.out.println(obj);
//After parsing with jsonPath the date is retained - Jul 6, 2018 9:16:55 PM
SimpleDateFormat format = new SimpleDateFormat("MMM dd, yyyy hh:mm:ss aaa");
Date d = format.parse(obj.toString());
System.out.println(d + " : : : " + d.getTime());
//Fri Jul 06 21:16:55 IST 2018 : : : 1530892015000 - Time is not retained
}
List List=jongo.runCommand(“{aggregate:'tester',管道:[],光标:{batchSize:10}”)
.字段(“光标”)
.as(测试仪等级);
用于(测试仪t:列表)
{
System.out.println(“日期字段测试::”+t.getDateField()+”::“+t.getDateField().getTime());
//输出非常好:dateField测试:::Fri Jul 06 21:16:55 IST 2018::::1530892015819
Gson Gson=新的Gson();
字符串str=gson.toJson(t);
DocumentContext docCtx=JsonPath.parse(str);
JsonPath JsonPath=JsonPath.compile(“$.dateField”);
objectobj=docCtx.read(jsonPath);
系统输出打印项次(obj);
//使用jsonPath解析后,保留日期-2018年7月6日晚上9:16:55
SimpleDateFormat=新的SimpleDateFormat(“mm dd,yyyy hh:mm:ss aaa”);
dated=format.parse(obj.toString());
System.out.println(d+“:”+d.getTime());
//2018年7月6日星期五21:16:55:1530892015000-时间不保留
}
预期:
t、 getDateField().getTime()==d.getTime()
请帮忙
问候
克里斯
您正在丢弃输入的毫秒部分,这将导致您所看到的差异。改用这个:
new SimpleDateFormat("MMM dd, yyyy hh:mm:ss.SSS aaa");
^^^^
tl;博士
- 您的格式化模式忽略了小数秒,因此输出中不会出现毫秒
- 您正在使用过时的日期时间类。改用java.time
Instant // Represent a moment in UTC, with a resolution as fine as nanoseconds.
.parse( "2018-07-06T15:46:55.819Z" ) // Parse a string in standard ISO 8601 format. The `Z` on the end means UTC, pronounced “Zulu”.
.atZone( ZoneId.of( "Asia/Kolkata" ) ) // Adjust from UTC to a desired time zone. Same moment, same point on the timeline, different wall-clock time. Returns a `ZonedDateTime` object.
.toString() // Generate a String in standard ISO 8601 format. Represents the moment in our `ZonedDateTime` object.
从遗留的java.util.Date
类转换为现代的java.time.Instant
,然后再转换回来。示例代码:
java.util.Date.from( // Convert from modern `Instant` to legacy `Date`.
myJavaUtilDate.toInstant() // Convert from legacy `Date` to modern `Instant`.
)
java.time
您正在使用非常麻烦的旧日期时间类:date
&SimpleDateFormat
。多年前,这些类被现代java.time类所取代
您的输入2018-07-06T15:46:55.819Z
采用标准ISO 8601格式。在解析或生成字符串时,java.time类默认使用ISO 8601格式。因此,无需指定格式化模式
末尾的Z
发音为Zulu
,表示UTC。Instant
类表示UTC中的一个时刻
Instant instant = Instant.parse( "2018-07-06T15:46:55.819Z" ) ;
生成ISO 8601格式的输出字符串
String output = instant.toString() ;
2018-07-06T15:46:55.819Z
您的代码忽略了时区这一关键问题。不要隐式地依赖JVM的当前默认时区,而是显式地使用ZoneId
,即使这是ZoneId.systemDefault()
以大陆/地区
的格式指定,例如,或太平洋/奥克兰
。切勿使用3-4个字母的缩写,如EST
或IST
,因为它们不是真正的时区,也不是标准化的,甚至不是唯一的(!)。例如,您的IST
可能表示爱尔兰标准时间、印度标准时间、伊朗标准时间或其他
从UTC调整到特定时区后,我们仍然有相同的时刻,时间线上的相同点。只有挂钟的时间不同
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ; // Or `ZoneId.systemDefault()`.
ZonedDateTime zdt = instant.atZone( z ) ; // Adjust from UTC to a specific time zone.
生成ISO 8601格式的输出字符串,扩展为将时区名称附加在方括号中
String output = zdt.toString() ;
2018-07-06T21:16:55.819+05:30[亚洲/加尔各答]
请注意,分数秒(毫秒)仍然完好无损
转换
也许您必须与一个接口(您的问题不清楚),因为旧代码尚未更新以支持java.time
您将发现方便的转换方法,即添加到旧类中的新方法
从到java.time.Instant
Instant myInstant = myJavaUtilDate.toInstant() ;
如上所示进行操作。调整到您想要的时区,并生成一个字符串
另一个方向,从现代的Instant
类到传统的Date
类
java.util.Date myDate = java.util.Date.from( myInstant ) ;
不变对象
time类被设计为,并使用该模式。注意上面的代码是如何基于原始值生成新对象的,而不是修改(“变异”)原始值
关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,& 该项目现已启动,建议迁移到类 要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是 您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*
类
从哪里获得java.time类
- 然后
- 内置的李>
- 标准JavaAPI的一部分,带有捆绑实现
- Java9添加了一些次要功能和修复
- 及
- 大部分java.time功能都在中向后移植到Java6和Java7
-
- 更高版本的Android捆绑包实现了java.time类
- 对于早期的Android(您在
中的输入不包括第二个组件的分数-SimpleDataFormat
与'2018-07-06T15:46:55.819ZFri Jul 06 21:16:55 IST 2018
.819'。您需要返回并查看一下不完全相同,它缺少一秒钟的时间。
正在转换jongo
日期字段,b因为它似乎是错误的(或者缺少一些数据)。如果
已经是obj
对象,那么不要使用Date
,因为它使用了错误的格式。jongo部分完全可以使用System.out.println(t.getDateField()+”::“+tobj.toString()
java.util.Date myDate = java.util.Date.from( myInstant ) ;