[英]Discrepancy in java retaining time in milliseconds
我正在嘗試使用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()
請幫忙
問候
短劍的一種
例:
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`.
)
您正在使用非常麻煩的舊日期時間類: 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.systemDefault()
,也要使用ZoneId
顯式。
以continent/region
的格式指定適當的時區名稱 ,例如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.util.Date
接口(您的問題不明確),因為舊的代碼尚未更新以支持java.time 。
您將找到方便的轉換方法,舊方法中添加了新方法。
從java.util.Date
到java.time.Instant
。
Instant myInstant = myJavaUtilDate.toInstant() ;
繼續如上所示。 調整到您想要的時區,並生成一個String
。
走向另一個方向,從現代的Instant
類到傳統的類Date
。
java.util.Date myDate = java.util.Date.from( myInstant ) ;
java.time類設計為線程安全的 ,並使用不可變對象模式。 注意上面的代碼如何根據原始值生成新對象,而不是改變(“改變”)原始對象。
java.time框架內置於Java 8及更高版本中。 這些類取代了麻煩的舊遺留日期時間類,如java.util.Date
, Calendar
和SimpleDateFormat
。
現在處於維護模式的Joda-Time項目建議遷移到java.time類。
要了解更多信息,請參閱Oracle教程 。 並搜索Stack Overflow以獲取許多示例和解釋。 規范是JSR 310 。
您可以直接與數據庫交換java.time對象。 使用符合JDBC 4.2或更高版本的JDBC驅動程序 。 不需要字符串,不需要java.sql.*
類。
從哪里獲取java.time類?
ThreeTen-Extra項目使用其他類擴展了java.time。 該項目是未來可能添加到java.time的試驗場。 您可以在這里找到一些有用的類,比如Interval
, YearWeek
, YearQuarter
,和更多 。
new SimpleDateFormat("MMM dd, yyyy hh:mm:ss aaa");
您正在丟棄輸入的毫秒部分,這會導致您看到的差異。 請改用:
new SimpleDateFormat("MMM dd, yyyy hh:mm:ss.SSS aaa");
^^^^
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.