簡體   English   中英

從尊重時區的日歷對象中獲取格式化字符串的最簡單方法是什么?

[英]What is the easiest way to get a formatted string from a calendar object which respects timezone?

當我在線搜索“如何將Calendar轉換為String ”時,發現的所有結果建議先轉換為Date ,然后再將Date轉換為String

問題在於, Date僅表示自該紀元以來的毫秒數-它不遵守時區。 Calendar以這種方式更高級。

當然,我可以調用單個Calendar.get方法來創建自己的格式化字符串,但是肯定有一種更簡單的方法嗎?

為了說明,我編寫了以下代碼:

long currentTime = Calendar.getInstance().getTimeInMillis();
Calendar calendar = new GregorianCalendar();
calendar.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
calendar.setTimeInMillis(currentTime);
System.out.println(calendar.getTime().toString());
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime()));
System.out.println(calendar.get(Calendar.HOUR_OF_DAY));

在晚上8:02從位於倫敦(UTC + 0)的計算機上運行此代碼時,我得到以下結果:

Wed Nov 18 20:02:26 UTC 2015
2015-11-18 20:02:26
21

最后一行根據日歷的時區(馬德里為UTC + 1)顯示實際時間。 在馬德里,這是晚上9:02,但是顯然,本機的Date.toStringDateFormat.format方法都忽略了時區,因為在調用Calendar.getTime (類似Calendar.getTimeInMillis )時,時區信息已被刪除。

鑒於此,從尊重時區的Calendar獲取格式化字符串的最佳方法是什么?

在SimpleDateFormat對象上設置時區,然后使用z ..

sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
System.out.println(sdf.format(calendar.getTime());

有關如何在Java中處理時區的詳細信息,請參見此處

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));

Calendar cal = Calendar.getInstance();
System.out.println(simpleDateFormat.format(cal.getTime()));

java.time

盡管其他答案似乎是正確的,但是更好的方法是避免完全使用java.util.Date/.Calendar。

這些舊的日期時間類已被內置在Java 8及更高版本中的java.time框架取代。 新課程的靈感取自於成功的Joda-Time框架,該框架旨在作為其繼任者,其概念相似但經過重新架構。 JSR 310定義。 ThreeTen-Extra項目擴展。 請參閱教程

Instant

Instant表示UTC時間軸上的時刻。

Instant instant = Instant.now ( ); // Current moment in UTC.

對於給定的Calendar對象,使用Java 8中添加的toInstant方法轉換為Instant

Instant instant = myCalendar.toInstant();

ZonedDateTime

您可以將時區( ZoneId )分配給Instant以獲得ZonedDateTime

ZoneId zoneId = ZoneId.of ( "Europe/Madrid" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant, zoneId );

日期時間值的字符串表示形式

轉儲到控制台。

System.out.println ( "instant: " + instant + " adjusted into zone: " + zoneId + " is zdt: " + zdt );

解析/生成日期時間值的字符串表示形式時,java.time類默認使用ISO 8601標准格式。 默認情況下,除了通常的offset-from-UTC之外,還通過附加時區名稱來擴展ISO 8601樣式。

即刻:2015-11-18T22:23:46.764Z調整為區域:歐洲/馬德里為zdt:2015-11-18T23:23:46.764 + 01:00 [歐洲/馬德里]

如果要使用ISO 8601樣式但不使用T ,請在生成的String對象上調用.replace( "T" , "" )定義自己的formatter

java.time.format包可以完成確定適合於特定Locale的本地化格式的工作。

Locale locale = Locale.forLanguageTag ( "es-ES" );
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.FULL );
String output = zdt.format ( formatter.withLocale ( locale ) );

miércoles18 de noviembre de 2015 23H38'CET

您可以使用String.format()避免時區問題

http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html

本示例以以下格式給出結果:“ yyyy-MM-dd HH:mm:ss”

Calendar c = Calendar.getInstance();
String s = String.format("%1$tY-%1$tm-%1$td:%1$tM:%1$tS", c);
System.out.println(s);

輸出:

2015-11-20:44:55

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM