簡體   English   中英

將字符串轉換為人類可讀日期(java / android)

[英]Convert string to human readable date (java/android)

基於具有以下格式的輸入字符串: "yyyyMMdd" ,例如"20170412" ,如何顯示日期和日期?

例如:

input -> "20170412"

output -> "Wednesday, April 12th 2017""Wed Apr 12 2017" output -> "Wednesday, April 12th 2017" "Wed Apr 12 2017"或類似的東西

無論我嘗試使用SimpleDateFormathttps://stackoverflow.com/a/4216767/658323 ),我總是得到我不需要的時間和時區。

那可能嗎?

編輯:我的問題重復。 我在帖子中明確提到,可能重復的問題中列出的所有SimpleDateFormat模式都顯示用戶的時間和時區。 我需要一個用戶區域設置日期的模式,沒有時間或時區。

如果我正確理解你的問題:似乎你需要不同的格式來從字符串到日期閱讀和不同的顯示。 嘗試這個

    String string = "20170412";
    DateFormat readFormat = new SimpleDateFormat("yyyyMMdd");
    Date date = readFormat.parse(string);

    DateFormat displayFormat = new SimpleDateFormat("E MMMM d, yyyy", Locale.ENGLISH);
    System.out.println(displayFormat.format(date));

但通常你應該尊重用戶為系統選擇的日期格式。 所以每個應用程序都會有相同的顯示日期格式:在這篇文章中如何在Android中獲取用戶選擇的日期格式?

TL;博士

LocalDate.parse(
    "20170412" ,
    DateTimeFormatter.BASIC_ISO_DATE
).format(
    DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL )
                     .withLocale( Locale.US )
)

2017年4月12日星期三

使用java.time

現代的方法是使用java.time類,特別是LocalDate LocalDate類表示沒有時間且沒有時區的僅日期值。

定義格式模式以匹配您的輸入。 您的輸入符合ISO 8601的“基本”版本,其中分隔符的使用被最小化。 為此,java.time已經預先定義了格式化模式。

DateTimeFormatter f = DateTimeFormatter.BASIC_ISO_DATE ;
LocalDate ld = LocalDate.parse( "20170412" , f );

要生成標准ISO 8601格式的字符串,請調用toString 解析/生成字符串時,java.time類使用標准格式。

String output = ld.toString() ;

2017年4月12日

一般來說,我建議您堅持使用ISO 8601格式的擴展版本,如上面的示例所示,其中包括日期中的連字符,而不是基本版本。 擴展版本更容易被人閱讀,並且更容易被識別為日期時間值。

本土化

您可以生成其他格式的字符串。 如果需要,您可以指定確切的格式。 但通常最好讓java.time本地化為您服務。

要進行本地化,請指定:

  • FormatStyle用於確定字符串的長度或縮寫。
  • 用於確定(a)翻譯日期名稱,月份名稱等的人類語言的Locale ,以及(b)決定縮寫,大小寫,標點符號,分隔符等問題的文化規范。

示例代碼。

Locale l = Locale.CANADA_FRENCH ;  // Or Locale.US, Locale.ITALY, etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL )
                                       .withLocale( l ) ;
String output = ld.format( f ) ;

對於Locale.US ,輸出將是:

2017年4月12日星期三


關於java.time

java.time框架內置於Java 8及更高版本中。 這些類取代了麻煩的舊遺留日期時間類,如java.util.DateCalendarSimpleDateFormat

現在處於維護模式Joda-Time項目建議遷移到java.time類。

要了解更多信息,請參閱Oracle教程 並搜索Stack Overflow以獲取許多示例和解釋。 規范是JSR 310

從哪里獲取java.time類?

ThreeTen-Extra項目使用其他類擴展了java.time。 該項目是未來可能添加到java.time的試驗場。 您可以在這里找到一些有用的類,比如IntervalYearWeekYearQuarter ,和更多

所以,實際上答案很簡單。 Android getBestDateTimePattern有一個內置方法(自API 18起可用),它將根據用戶的語言自動設置日期格式:

String pattern = android.text.format.DateFormat.getBestDateTimePattern(Locale.getDefault(), "EEEEMMMMdyyyy"); //order on the String doesn't matter
SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.getDefault());
String dateToDisplay = format.format(date);

這是getBestDateTimePattern的官方文檔:

返回給定語言環境的給定骨架的最佳可能本地化形式。 骨架類似於Unicode UTS#35模式,並使用相同的格式字符。

一個區別是訂單無關緊要。 例如,“MMMMd”將在en_US語言環境中返回“MMMM d”,但在de_CH語言環境中返回“d.MMMM”。 另請注意,在第二個示例中添加了德語的必要標點符號。 對於es_ES中的相同輸入,我們還有更多的額外文本:“d'de'MMMM”。

此方法將自動糾正語法上的必要性。 給定相同的“MMMMd”輸入,此方法將在fa_IR語言環境中返回“d LLLL”,其中需要單獨的月份。 長度保留在有意義的地方,因此“Md”會給“MMMd”提供不同的結果,例如,除了ja_JP這樣只有一個月長度的區域設置。

此方法僅返回CLDR中的模式,並且只要您知道格式字符串中需要哪些元素但又不想使您的代碼特定於任何一個語言環境,這種方法就很有用。

對於API低於18,您可以使用Emiter描述的解決方法對他的評論:

final String format = Settings.System.getString(getContentResolver(), Settings.System.DATE_FORMAT);
if (TextUtils.isEmpty(format)) dateFormat = android.text.format.DateFormat.getMediumDateFormat(getApplic‌​ationContext());
else dateFormat = new SimpleDateFormat(format);

暫無
暫無

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

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