繁体   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