YoY*_*oYo 24 java date java-8 java-time
我注意到java.time.format.DateTimeFormatter
无法按预期解析.见下文:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Play {
public static void tryParse(String d,String f) {
try {
LocalDate.parse(d, DateTimeFormatter.ofPattern(f));
System.out.println("Pass");
} catch (Exception x) {System.out.println("Fail");}
}
public static void main(String[] args) {
tryParse("26-may-2015","dd-L-yyyy");
tryParse("26-May-2015","dd-L-yyyy");
tryParse("26-may-2015","dd-LLL-yyyy");
tryParse("26-May-2015","dd-LLL-yyyy");
tryParse("26-may-2015","dd-M-yyyy");
tryParse("26-May-2015","dd-M-yyyy");
tryParse("26-may-2015","dd-MMM-yyyy");
tryParse("26-May-2015","dd-MMM-yyyy");
}
}
Run Code Online (Sandbox Code Playgroud)
只有最后一次尝试tryParse("26-May-2015","dd-MMM-yyyy");
将"通过".根据文档LLL
应该能够解析出文本格式.也不是大写'M'与小写'm'的细微差别.
这真的很烦人,因为我无法默认解析Oracle DB默认格式化的字符串
SELECT TO_DATE(SYSDATE,'DD-MON-YYYY') AS dt FROM DUAL;
Run Code Online (Sandbox Code Playgroud)
同样,对于以下程序:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Play {
public static void output(String f) {
LocalDate d = LocalDate.now();
Locale l = Locale.US;
// Locale l = Locale.forLanguageTag("ru");
System.out.println(d.format(DateTimeFormatter.ofPattern(f,l)));
}
public static void main(String[] args) {
output("dd-L-yyyy");
output("dd-LLL-yyyy");
output("dd-M-yyyy");
output("dd-MMM-yyyy");
}
}
Run Code Online (Sandbox Code Playgroud)
我得到以下输出:
28-5-2015
28-5-2015
28-5-2015
28-May-2015
Run Code Online (Sandbox Code Playgroud)
显然L
格式说明符不会对待任何文本,对我来说似乎是数字...
但是,如果我将Locale更改为,则会Locale.forLanguageTag("ru")
得到以下输出:
28-5-2015
28-???-2015
28-5-2015
28-???-2015
Run Code Online (Sandbox Code Playgroud)
一切都很有意思,你不同意吗?
我的问题是:
L
模式说明符的用法.引用我认为"重要"的文档中的一部分:
文本:文本样式基于使用的模式字母数确定.少于4个模式字母将使用简短形式.正好4个模式字母将使用完整形式.正好5个模式字母将使用窄格式.模式字母'L','c'和'q'指定文本样式的独立形式.
Number:如果字母数为1,则使用最小位数输出该值,不进行填充.否则,将使用数字位数作为输出字段的宽度,并根据需要将值填充为零.以下模式字母对字母数量有约束.只能指定一个字母'c'和'F'.最多可以指定两个字母'd','H','h','K','k','m'和's'.最多可以指定三个字母"D".
数字/文本: 如果模式字母的数量为3或更大,请使用上面的文本规则.否则使用上面的数字规则.
UPDATE
我向Oracle提交了两份提交内容:
Mis*_*sha 18
我认为'L'适用于本月使用不同单词的语言与日期中使用的语言.例如:
Locale russian = Locale.forLanguageTag("ru");
asList("MMMM", "LLLL").forEach(ptrn ->
System.out.println(ptrn + ": " + ofPattern(ptrn, russian).format(Month.MARCH))
);
Run Code Online (Sandbox Code Playgroud)
输出:
MMMM: ?????
LLLL: ????
Run Code Online (Sandbox Code Playgroud)
在解析日期时,不应该有任何理由使用'L'而不是'M'.
我尝试了以下内容来查看哪些语言环境支持独立月份名称格式:
Arrays.stream(Locale.getAvailableLocales())
.collect(partitioningBy(
loc -> "3".equals(Month.MARCH.getDisplayName(FULL_STANDALONE, loc)),
mapping(Locale::getDisplayLanguage, toCollection(TreeSet::new))
)).entrySet().forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
以下语言从"LLLL"获取特定于语言环境的独立月份名称:
加泰罗尼亚语,中文,克罗地亚语,捷克语,芬兰语,希腊语,匈牙利语,意大利语,立陶宛语,挪威语,波兰语,罗马尼亚语,俄语,斯洛伐克语,土耳其语,乌克兰语
所有其他语言都将"3"作为March的独立名称.
根据javadocs:
模式字母“ L”,“ c”和“ q”指定文本样式的独立形式。
但是,我对“独立”表单应该是什么一无所知。在查看代码时,我看到使用'L'选择TextStyle.SHORT_STANDALONE
并根据该javadoc:
供独立使用的短文本,通常是缩写。例如,星期几星期一可能会输出“星期一”。
但是,这似乎并不起作用。即使使用三个字母,我也会从此代码中获得数值输出:
DateTimeFormatter pattern = DateTimeFormatter.ofPattern ("dd-LLL-yyyy");
System.out.println (pattern.format (LocalDate.now ()));
Run Code Online (Sandbox Code Playgroud)
编辑
经过进一步研究,似乎(据我所知)这些代码的“独立”版本适用于您想加载自己的独立于语言环境的数据(大概使用)DateTimeFormatterBuilder
。因此,默认情况下DateTimeFormatter
,不会加载任何条目TextStyle.SHORT_STANDALONE
。