如何使用Java时间从语言标签获取的任何语言环境格式化日期? [英] How to format a date by any locale obtained from language tag with java time?

查看:107
本文介绍了如何使用Java时间从语言标签获取的任何语言环境格式化日期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想获取一个日期作为字符串和一个语言标签,并根据该日期以语言环境格式解析该字符串.

I want to get a date as string and a language tag and based on that to parse the string by the locale format.

这是我到目前为止所做的:

This is what I've done so far:

public static String formatDateByLocale(String date, String languageTag) {
    Locale locale = Locale.forLanguageTag(languageTag);
    String datePattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(FormatStyle.LONG, FormatStyle.LONG, Chronology.ofLocale(locale), locale);

    DateTimeFormatter targetFormat = DateTimeFormatter.ofPattern(datePattern).withLocale(locale);
    DateTimeFormatter currentFormat = DateTimeFormatter.ofPattern("dd/MM/yyyy hh:mm a");

    LocalDateTime localDateTime = LocalDateTime.parse(date, currentFormat);

    String result = targetFormat.format(localDateTime);


    return result;
}

这会抛出Unable to extract value: class java.time.LocalDateTime

我应该如何确定这个日期:2017年4月17日上午10:50(带有FR标签)转换为2017/04/17 10:50上午?

How should I approach this to have this date: 17/04/2017 10:50AM with FR tag transform into 2017/04/17 10:50AM?

推荐答案

您的示例不完整且不正确.您应该提供 MCVE .您的示例17/04/2017 10:50AM的输出与使用

Your example is incomplete and incorrect. You should provide a MCVE. Your example output of 17/04/2017 10:50AM is not at all close to the actual output of French with format style LONG. So we cannot answer precisely. But here is something to point you in the right direction.

您不能指望能够解析任何日期时间输入字符串.有些歧义是无法解决的.并且一些关键信息,例如从UTC偏移或时区可能会被省略.相反:

You cannot count on being able to parse any date-time input string. Some ambiguities are impossible to resolve. And some crucial information such as offset-from-UTC or time zone may be omitted. Instead:

  • Within your app, pass around java.time objects, rather than mere strings.
  • Between apps/systems, pass strings is standard ISO 8601 format. Do so in UTC for date-time values, generally speaking.

下面是一些示例代码,显示了所需的法语输出.

Here is some example code showing your desired French output.

使用Instant捕获UTC中的当前时刻.

Capture the current moment in UTC as an Instant.

Instant instant = Instant.now( );

调整到特定的时区.请记住,时区与本地化问题无关.

Adjust into a particular time zone. Remember that time zone has nothing to do with localization issues.

ZoneId z = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = instant.atZone( z );

确定一个Locale.在这里,我们将法语与法国的文化规范结合起来使用.

Determine a Locale. Here we use French language with cultural norms of France.

Locale locale = Locale.forLanguageTag( "fr-FR" );

您的问题显示交换 (适用于语言环境).在这里无效,因为Instant和法国都使用

Your Question shows swapping of Chronology where appropriate for a locale. Has no effect here as both Instant and France use IsoChronology.

Chronology c = Chronology.ofLocale( locale );

定义格式化程序.不需要在问题中看到的构建器模式.

Define a formatter. No need for the builder pattern seen in the Question.

DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.SHORT ).withLocale( locale ).withChronology( c ) ;

生成输出.

String s = zdt.format( f );

转储到控制台.

System.out.println( "instant.toString(): " + instant + " at zone: " + z + " in chrono: " + c + " = " + s );

instant.toString():2017-11-23T04:30:45.091424Z在区域:亚洲/加尔各答(以时间顺序):ISO = 2017/11/23 10:00

instant.toString(): 2017-11-23T04:30:45.091424Z at zone: Asia/Kolkata in chrono: ISO = 23/11/2017 10:00

请注意,由于缺少关键信息,如何不能将此输出 解析回日期时间值.

Note how this output cannot be parsed back into a date-time value as it lacks crucial information.

在这种情况下,您可以将字符串解析为LocalDateTime,如您的问题所示.但是,这里有数据丢失. LocalDateTime故意没有偏移或区域的概念,因此 not 并不代表时间轴上的一个点. LocalDateTime不是 实际时刻,只是在大约26-27小时内可能发生的一系列可能时刻的模糊暗示.您甚至还没有接近起点.

You could, in this case, parse the string to a LocalDateTime as shown in your Question. But you have data loss here. A LocalDateTime purposely has no concept of offset or zone, and so it does not represent a point on the timeline. A LocalDateTime is not an actual moment, only a vague hint of a range of possible moments that may be occurring over a period of about 26-27 hours. You are not even close to ending up where you started.

LocalDateTime ldt = LocalDateTime.parse( s , f );
System.out.println( "ldt: " + ldt );

ldt.toString():2017-11-23T10:00

ldt.toString(): 2017-11-23T10:00

顺便说一句,我建议您的方法采用 Locale ,而不仅仅是语言标签的字符串.调用程序员应负责确定有效语言标签的完整Locale.语言标签及其变体是复杂的业务.调用程序的程序员应该通过成功实例化Locale(最好是对其进行测试)来验证自己是否已正确定义了有效的语言构造.此处的方法应着重于日期时间问题,而不必同时处理语言标签的复杂性.

By the way, I suggest your method take a Locale rather than a mere string of the language tag. The calling programmer should be responsible for determining the full Locale for a valid language tag. Language tags and their variants are complicated business. The calling programmer should verify they have properly defined a valid language construct by successfully instantiating a Locale (and, ideally, testing it). The method at hand here should focus on date-time issues and not have to also deal with language tag complications.

这篇关于如何使用Java时间从语言标签获取的任何语言环境格式化日期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆