gpt4 book ai didi

scala - 多语言环境日期解析

转载 作者:行者123 更新时间:2023-12-04 01:32:45 25 4
gpt4 key购买 nike

我正在尝试编写一个类,它能够将多格式和多语言环境字符串解析为 DateTime

多格式 表示日期可能是:dd/MM/yyyy, MMM dd yyyy, ...(最多 10格式)

多语言环境 意味着日期可能是:29 Dec 201529 Dez 2015dice 29 2015 ...(最多 10 个语言环境,例如 engritjp)

使用答案 Using Joda Date & Time API to parse multiple formats我写道:

val locales = List(
Locale.ENGLISH,
Locale.GERMAN,
...
)

val patterns = List(
"yyyy/MM/dd",
"yyyy-MM-dd",
"MMMM dd, yyyy",
"dd MMMM yyyy",
"dd MMM yyyy"
)

val parsers = patterns.flatMap(patt => locales.map(locale => DateTimeFormat.forPattern(patt).withLocale(locale).getParser)).toArray
val birthDateFormatter = new DateTimeFormatterBuilder().append(null, parsers).toFormatter

但它不起作用:

birthDateFormatter.parseDateTime("29 Dec 2015") // ok
birthDateFormatter.parseDateTime("29 Dez 2015") // exception below

Invalid format: "29 Dez 2015" is malformed at "Dez 2015"
java.lang.IllegalArgumentException: Invalid format: "29 Dez 2015" is
malformed at "Dez 2015"

我发现所有 parsers: List[DateTimeParser] 在附加到 birthDateFormatter: DateTimeFormatter 后都“丢失”了它们的语言环境。 birthDateFormatter 只有一种语言环境 - en

我会写:

val birthDateFormatter = locales.map(new DateTimeFormatterBuilder().append(null, parsers).toFormatter.withLocale(_))

并像这样使用它:

birthDateFormatter.map(_.parseDateTime(stringDate))

但是它会抛出很多异常。太可怕了。

如何使用 joda-time 解析多格式和多语言环境字符串?我怎样才能用其他方式做到这一点?

最佳答案

调查很有趣。这是一个帮助我的测试套件(在 Java 中,但我希望你能理解):

import java.util.*;
import java.util.stream.Collectors;

import org.joda.time.DateTime;
import org.joda.time.format.*;
import org.junit.Test;

import static org.assertj.core.api.Assertions.*;

public class JodaTimeLocaleTest {

@Test // fails on both assertions
public void testTwoLocales() {
List<Locale> locales = Arrays.asList(Locale.FRENCH, Locale.GERMAN);
DateTimeParser[] parsers = locales.stream()
.map(locale -> DateTimeFormat.forPattern("dd MMM yyyy").withLocale(locale).getParser())
.collect(Collectors.toList())
.toArray(new DateTimeParser[0]);
DateTimeFormatter formatter = new DateTimeFormatterBuilder().append(null, parsers).toFormatter();

DateTime dateTime1 = formatter.parseDateTime("29 déc. 2015");
DateTime dateTime2 = formatter.parseDateTime("29 Dez 2015");

assertThat(dateTime1).isEqualTo(new DateTime("2015-12-29T00:00:00"));
assertThat(dateTime2).isEqualTo(new DateTime("2015-12-29T00:00:00"));
}

@Test // passes
public void testFrench() {
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd MMM yyyy").withLocale(Locale.FRENCH);

DateTime dateTime = formatter.parseDateTime("29 déc. 2015");

assertThat(dateTime).isEqualTo(new DateTime("2015-12-29T00:00:00"));
}

@Test // passes
public void testGerman() {
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd MMM yyyy").withLocale(Locale.GERMAN);

DateTime dateTime = formatter.parseDateTime("29 Dez 2015");

assertThat(dateTime).isEqualTo(new DateTime("2015-12-29T00:00:00"));
}
}

首先,你的第一个例子

birthDateFormatter.parseDateTime("29 Dec 2015")

仅因为您机器的默认区域设置为英语而通过。如果不同,这个案子也会失败。这就是为什么我在使用英语语言环境的机器上运行时使用法语和德语。就我而言,这两个断言都失败了。

事实证明,语言环境并未存储在解析器中,而仅存储在格式化程序中。所以当你这样做的时候

DateTimeFormat.forPattern("dd MMM yyyy").withLocale(locale).getParser()

语言环境是在格式化程序上设置的,但在创建解析器时会丢失:

// DateTimeFormatter#withLocale:
public DateTimeFormatter withLocale(Locale locale) {
if (locale == getLocale() || (locale != null && locale.equals(getLocale()))) {
return this;
}
// Notice how locale does not affect the parser
return new DateTimeFormatter(iPrinter, iParser, locale,
iOffsetParsed, iChrono, iZone, iPivotYear, iDefaultYear);
}

接下来,当您创建一个新的格式化程序时

new DateTimeFormatterBuilder().append(null, parsers).toFormatter()

它是使用系统的默认区域设置创建的(除非您使用 withLocale() 覆盖它)。并且在解析期间使用该语言环境:

// DateTimeFormatter#parseDateTime
public DateTime parseDateTime(String text) {
InternalParser parser = requireParser();

Chronology chrono = selectChronology(null);
// Notice how the formatter's locale is used
DateTimeParserBucket bucket = new DateTimeParserBucket(0, chrono, iLocale, iPivotYear, iDefaultYear);
int newPos = parser.parseInto(bucket, text, 0);
// ... snipped
}

所以事实证明,虽然您可以有多个解析器来支持多种格式,但每个格式化程序实例仍然只能使用一个语言环境。

关于scala - 多语言环境日期解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34513886/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com