[英]SimpleDateFormat.parse and SimpleDateFormat.format not producing identical values
[英]Why SimpleDateFormat.format() and SimpleDateFormat.parse() are giving different time though setting only one TimeZone?
我正在嘗試通過SimpleDateFormat將時區設置為其他國家的時區。 SimpleDateFormat.format()返回給定時區的正確當前時間,但是SimpleDateFormat.parse()返回本地當前時間,我不知道為什么會這樣。 這是我的代碼-
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:MM:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
System.out.println("Time1 : " + dateFormat.format(new Date()));
System.out.println("Time2 : " + dateFormat.parse(dateFormat.format(new Date())));
輸出是-
Time1 : 2013-01-17 21:01:55
Time2 : Fri Jan 18 10:30:55 IST 2013
Time1是“ America / Los_Angeles”的輸出,而Time2是local(即“ Asia / Calcutta”)的輸出 。
我只想要UTC秒格式的給定時區的當前時間(即,自1970年1月1日以來的秒)。
為什么雖然只設置一個時區,但SimpleDateFormat.format()和SimpleDateFormat.parse()卻給出了不同的時間?
請幫我。
使用Parse ,您可以命令編譯器理解特定格式的給定日期。 它了解並保持其自己的格式,並准備提供您想要的任何格式!
您將得到一個輸出,這表示您輸入日期已成功解析。 您無法控制變量存儲的date的格式。
使用格式,您可以將日期轉換為任何所需的格式。
只需解析->閱讀(我可以以任何方式閱讀並以我想要的任何方式存儲)格式->寫(我會以您想要的格式給您)
dateFormat.format()將為您提供給定格式的輸出,並將時區更改為格式化程序中設置的時區。 (例如dateFormat.setTimeZone(TimeZone.getTimeZone(“ America / Los_Angeles”)));)
而dateFormat.parse()假定日期已在提到的時區中,它將日期轉換為您的本地時區。
第二個println中的dateFormat.parse()
System.out.println("Time2 : " + dateFormat.parse(dateFormat.format(new Date())));
返回Date和Date.toString()以EEE MMM dd HH:mm:ss zzz yyyy
格式返回日期的字符串表示形式。 參見Date.toString()API
在第一行中,您正在將本地日期格式化為特定時區,它將返回一個字符串,該字符串表示在特定時區中傳遞的參數日期,但是解析函數有所不同。它將返回一個日期對象,該對象表示自一月份以來的毫秒數1970年1月1日,UTC。 它不包含任何時區信息。
糟糕的舊日期時間類非常令人困惑,尤其是在處理隱式默認時區時。 但是,您的謎尚無足輕重 ,因為這些可怕的舊類早在幾年前就被現代的java.time類所取代。
Instant.now() // Capture current moment in UTC. This class replaces `java.util.Date`.
.atZone( // Adjust from UTC to the wall-clock time used by the people of a particular region, a time zone.
ZoneId.of( "America/Montreal" )
) // Returns a `ZonedDateTime`
.format(
DateTimeFormatter.ISO_LOCAL_DATE_TIME
) // Returns a String like: `2013-01-17T21:01:55`.
.replace( "T" , " " ) // Replace the `T` in the middle (from the standard ISO 8601 format) with a SPACE.
2013-01-17 21:01:55
由於可怕的舊日期時間類(例如SimpleDateFormat
已被java.time取代,因此該問題不存在 。
java.util.Date
類由java.time.Instant
替換。 兩者都代表UTC時刻,始終代表UTC。 (盡管在應用JVM的當前默認時區時對您說謊,盡管Date::toString
。)
Instant instant = Instant.now() ; // Capture current moment in UTC.
調整到一個時區。
ZoneId z = ZoneId.of( "America/Los_Angeles" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
調整到另一個時區。
ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" ) ; // Contemporary time in India.
ZonedDateTime zdtKolkata = instant.atZone( zKolkata ) ;
這三個對象( instant
, zdt
和zdtKolkata
)都表示同一時刻 ,時間軸上的同一點。 只有掛鍾時間不同。
當生成表示日期時間值的字符串時,除非上下文絕對清晰,否則我建議始終包括偏移量/區域信息。 在時間范圍不明確的報告中,我在商業世界中看到了很多困惑。
但是,如果您堅持要用DateTimeFormatter
類定義自己的格式化模式,或者使用給定的格式化程序ISO_LOCAL_DATE_TIME
並將中間的T
替換為SPACE。
DateTimeFormatter f = DateTimeFormatter.ISO_LOCAL_DATE_TIME ;
String output = zdt.format( f ) ;
2013-01-17 21:01:55
問題的一部分是您的字符串的歧義2013-01-17 21:01:55
。 該字符串缺少任何時區或UTC偏移量的指示。 這樣的值不是時刻, 也不是時間軸上的一點。 例如,印度的晚上9點比魁北克的晚上9點早幾個小時。 沒有區域或偏移量,該字符串僅代表沿全球時區范圍約26-27小時的潛在時刻。
傳統類沒有此類代表這種價值的類。 在現代類中,我們為此設置了LocalDateTime
,這是一個無時區,日期和時間的無區域/偏移量。
解析/生成字符串時, java.time類默認使用ISO 8601標准格式。 您的輸入幾乎符合要求。 我們只需要在中間用T
替換SPACE即可。
LocalDateTime ldt = LocalDateTime.parse( "2013-01-17 21:01:55".replace( "" , "T" ) ) ;
如果您知道該字符串后面的意圖是表示特定時區中的某個時刻,請應用ZoneId
來獲取ZonedDateTime
。 例如,如果您確定它代表了北美大部分西海岸的一刻,請使用America/Los_Angeles
。
ZoneId z = ZoneId.of( "America/Los_Angeles" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
要從該區域調整為UTC,請提取一個Instant
對象。 Instant
類以UTC表示時間軸上的時刻,分辨率為納秒 (最多十進制的九(9)位數字)。
Instant instant = zdt.toInstant() ; // Adjust from some zone to UTC. Same moment, same point on the timeline, different wall-clock 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
,和更多 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.