问题描述
我想获取一个日期作为字符串和一个语言标签,并根据该日期以语言环境格式解析该字符串.
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
的输出与使用格式样式LONG
.因此,我们无法准确回答.但是,这可以为您指明正确的方向.
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:
- 在您的应用程序中,传递java.time对象,而不只是字符串.
- 在应用程序/系统之间,传递字符串是标准的 ISO 8601 格式.一般来说,在UTC中针对日期时间值进行操作.
- 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
和法国都使用 IsoChronology
.
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 );
请注意,由于缺少关键信息,如何不能将此输出 解析回日期时间值.
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 );
顺便说一句,我建议您的方法采用 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时间从语言标签获取的任何语言环境格式化日期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!