我正在尝试使用mongodb来获取一些带有日期字段的记录,示例记录如下所示,并且想要将已使用jayway jsonpath解析的日期字段转换为java.util.Date长整数。转换后的长整数与原始整数不匹配。请帮忙。
测试器集合中的样本记录:
{
"_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
}
预期:
t.getDateField()。getTime()==== d.getTime()
请帮忙
问候
克里斯
最佳答案
tl; dr
您的格式化模式省略了小数秒,因此输出中不会出现毫秒。
您正在使用过时的日期时间类。使用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()
也是如此。以
continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用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.util.Date
接口(您的问题尚不清楚)。您会发现方便的转换方法,将新方法添加到旧类中。
从
java.util.Date
到java.time.Instant
。Instant myInstant = myJavaUtilDate.toInstant() ;
如上所示继续。调整到所需的时区,并生成一个
String
。从现代
Instant
类到传统类Date
,朝着另一个方向发展。java.util.Date myDate = java.util.Date.from( myInstant ) ;
不变的对象
java.time类设计为thread-safe,并使用immutable objects模式。请注意,上面的代码是如何根据原始值而不是更改(“变异”)原始值来产生新鲜对象的。
关于java.time
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如
java.util.Date
,Calendar
和SimpleDateFormat
。现在位于Joda-Time中的maintenance mode项目建议迁移到java.time类。
要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换java.time对象。使用与JDBC driver或更高版本兼容的JDBC 4.2。不需要字符串,不需要
java.sql.*
类。在哪里获取java.time类?
Java SE 8,Java SE 9,Java SE 10和更高版本
内置的
标准Java API的一部分,具有捆绑的实现。
Java 9添加了一些次要功能和修复。
Java SE 6和Java SE 7
ThreeTen-Backport中的大部分java.time功能都已反向移植到Java 6和7。
Android
更高版本的Android捆绑了java.time类的实现。
对于早期的Android(<26),ThreeTenABP项目改编为ThreeTen-Backport(如上所述)。请参见How to use ThreeTenABP…。
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如
Interval
,YearWeek
,YearQuarter
和more。
关于java - Java保留时间的差异(以毫秒为单位),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51218990/