将字符串转换为人类可读日期(java / android)

时间:2017-04-12 18:25:54

标签: java android date

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

例如:

input -> "20170412"

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

无论我尝试使用SimpleDateFormathttps://stackoverflow.com/a/4216767/658323)的模式,我总能得到我不需要的时间和时区。

这可能吗?

编辑:我的问题是重复。我在帖子中明确提到,可能重复的问题中列出的所有SimpleDateFormat模式都会显示用户的时间和时区。我需要在用户的语言环境中使用日期模式,没有时间或时区。

3 个答案:

答案 0 :(得分:5)

如果我正确理解你的问题:似乎你需要不同的格式来从字符串到日期阅读和不同的显示。试试这个

    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));

但是通常你应该尊重用户为系统选择的日期格式。所以每个应用程序都有相同的显示日期格式: 就像在这篇文章How to get user-selected date format in Android?

中一样

答案 1 :(得分:5)

TL;博士

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

2017年4月12日星期三

使用java.time

现代的方法是使用java.time类,LocalDateLocalDate类表示没有时间且没有时区的仅限日期的值。

定义格式模式以匹配您的输入。您的输入符合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格式的扩展版本,如上面的示例所示,其中包含日期中的连字符,而不是 basic 版本。扩展版本更容易被人阅读,并且更容易被识别为日期时间值。

本地化

您可以生成其他格式的字符串。如果需要,您可以指定确切的格式。但通常最好让java.time为你本地化。

要进行本地化,请指定:

  • FormatStyle确定字符串的长度或缩写。
  • Locale确定(a)翻译日期名称,月份名称等的人类语言,以及(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及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 2 :(得分:1)

所以,实际上答案很简单。 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"将   返回" MMMM d"在en_US语言环境中,但是" d。 MMMM"在de_CH   语言环境。还要注意那个必要的第二个例子   添加了德语标点符号。对于es_ES中的相同输入,我们是&#d; d   还有更多的文字:" d' de' MMMM"

     

此方法将自动纠正语法上的必要性。   给出相同的" MMMMd"输入,此方法将返回" d LLLL"在里面   fa_IR语言环境,需要独立的月份。长度是   保存在有意义的地方,所以" Md"会给出不同的结果   " MMMd&#34 ;,比如说,除了ja_JP等只有一个的区域设置   月长。

     

此方法仅返回CLDR中的模式,并且非常有用   每当你知道格式字符串中你想要什么元素时   不想让您的代码特定于任何一个区域设置。

对于低于18的API,您可以使用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);