[英]Java: SimpleDateFormat not formatting in desired TimeZone
我想為特定時區GMT設置日期格式,並且我希望該格式的結果始終相同,無論應用程序在哪個時區運行。
例如,在GMT時區中創建Calendar
實例並填充其字段:
TimeZone gmtTimeZone = TimeZone.getTimeZone( "GMT" );
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone( gmtTimeZone );
calendar.set( Calendar.YEAR, 1982 );
calendar.set( Calendar.MONTH, Calendar.JANUARY );
calendar.set( Calendar.DAY_OF_MONTH, 23 );
calendar.set( Calendar.HOUR, 1 );
calendar.set( Calendar.MINUTE, 2 );
calendar.set( Calendar.SECOND, 3 );
calendar.set( Calendar.MILLISECOND, 4 );
從日歷中檢索UTC時間戳:
Date utcDate = calendar.getTime();
據我了解, utcDate
現在是January 1, 1970, 00:00:00.000 GMT
January 23, 1982, 01:02:03.004 GMT
之間的毫秒數。 請參閱Date
Javadocs:
/**
* Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
* represented by this <tt>Date</tt> object.
*
* @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
* represented by this date.
*/
創建日期格式器並將其時區也設置為GMT:
SimpleDateFormat dateTimeFormat = new SimpleDateFormat( "yyyy-MM-dd' 'HH:mm:ss.SSSZ" );
dateTimeFormat.setTimeZone( gmtTimeZone );
將日期對象格式化為字符串:
String stringDate = dateTimeFormat.format( utcDate );
現在,當我這樣做時:
System.out.println( utcDate.getTime() );
System.out.println( stringDate );
我得到:
> 380638923004
> 1982-01-23 13:02:03.004+0000
但是,我的期望是(注意13
小時vs 01
小時):
> 1982-01-23 01:02:03.004+0000
即,因為我使用calendar.set( Calendar.HOUR, 1 );
將時間設置為1(凌晨calendar.set( Calendar.HOUR, 1 );
,我希望時間是1點(凌晨1點)而不是13點(下午1點)。
我要去哪里錯了?
SimpleDateFormat dateTimeFormat = new SimpleDateFormat( "yyyy-MM-dd' 'hh:mm:ss.SSSZ" );
dateTimeFormat.setTimeZone( gmtTimeZone );
這將為您提供預期的輸出。
根據JavaDoc for SimpleDateFormat,日期格式字符串中的“ h”將以am / pm(1-12)表示為小時。
編輯:Calendar.HOUR_OF_DAY應該用於設置24小時制的小時。
由於正確答案由斯賓塞布雷特說,你應該使用hh
如果你的意思是小寫的12小時制 ,而不是24小時。
使用Java 8及更高版本時,應避免使用這些眾所周知的麻煩的舊日期時間類(java.util.Date/.Calendar等)。 它們已被java.time框架取代。 請參閱教程 。
Instant
Instant
是UTC時間軸上的時刻。
Instant instant = Instant.now();
OffsetDateTime
但是, Instant
具有有限的格式和有限的實例化方式。 因此,讓我們看一下OffsetDateTime
,您可以將其視為與從UTC偏移 ( ZoneOffset
)結合的Instant
。 為了指定偏移量,我們可以使用常量java.time.ZoneOffset.UTC
。 要實例化OffsetDateTime
我們首先構建僅日期和僅 時間 ,然后結合偏移量。
java.time類具有納秒級的分辨率。 您在問題示例中的預期毫秒數。 因此,我們將使用TimeUnit
轉換。 您可以自己進行乘法運算,但是容易出錯。 而且TimeUnit
是自我記錄的。
LocalDate localDate = LocalDate.of( 1982 , 1 , 23 );
long nanoseconds = TimeUnit.NANOSECONDS.convert( 4 , TimeUnit.MILLISECONDS );
LocalTime localTime = LocalTime.of( 1 , 2 , 3 , nanoseconds );
OffsetDateTime odt = OffsetDateTime.of( localDate , localTime , ZoneOffset.UTC );
java.time類的toString
方法默認使用ISO 8601標准格式。 因此,您無需指定格式即可,因為它接近您想要的輸出。 與標准格式不太一樣,中間包含一個T
而不是一個SPACE。
String output = odt.toString();
1982-01-23T01:02:03.004Z
可以將T
替換為SPACE,也可以在Stack Overflow中搜索有關在java.time中使用DateTimeFormatter
類的許多示例。
String output = odt.toString().replace( "T" , " " );
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.