题
我有一串,表示日期在 法语 区域设置:09-oct-08:
我需要 分析 那串所以我来到了这SimpleDateFormat:
String format2 = "dd-MMM-yy";
但我有一个问题每月一部分,这似乎是预期与结束点:
df2.format(new Date());
给我说:
28-oct.-09
什么是现在最好的方式为我做SimpleDateFormat了解("09-oct-08")?
完整的代号:
String format2 = "dd-MMM-yy";
DateFormat df2 = new SimpleDateFormat(format2,Locale.FRENCH);
date = df2.parse("09-oct-08");
这给了我java。的文本。如果:Unparseable日期:"09-oct-08"
如果我再尝试记录:
df2.format(new Date());
我得到:28-oct.机构-09
解决方案
这似乎有效:
DateFormatSymbols dfsFr = new DateFormatSymbols(Locale.FRENCH);
String[] oldMonths = dfsFr.getShortMonths();
String[] newMonths = new String[oldMonths.length];
for (int i = 0, len = oldMonths.length; i < len; ++ i) {
String oldMonth = oldMonths[i];
if (oldMonth.endsWith(".")) {
newMonths[i] = oldMonth.substring(0, oldMonths[i].length() - 1);
} else {
newMonths[i] = oldMonth;
}
}
dfsFr.setShortMonths(newMonths);
DateFormat dfFr = new SimpleDateFormat(
"dd-MMM-yy", dfsFr);
// English date parser for creating some test data.
DateFormat dfEn = new SimpleDateFormat(
"dd-MMM-yy", Locale.ENGLISH);
System.out.println(dfFr.format(dfEn.parse("10-Oct-09")));
System.out.println(dfFr.format(dfEn.parse("10-May-09")));
System.out.println(dfFr.format(dfEn.parse("10-Feb-09")));
编辑:看起来像圣影打败了我。
其他提示
您只需删除“。”:
即可df2.format(new Date()).replaceAll("\\.", ""));
编辑,关于 lemon 答案:
使用Locale French时,格式似乎有问题。因此,我建议您只使用。
删除,如我所解释的那样。
确实,以下代码:
String format2 = "dd-MMM-yy";
Date date = Calendar.getInstance().getTime();
SimpleDateFormat sdf = new SimpleDateFormat(format2, Locale.FRENCH);
System.out.println(sdf.format(date));
sdf = new SimpleDateFormat(format2, Locale.ENGLISH);
System.out.println(sdf.format(date));
显示以下输出:
28-oct.-09
28-Oct-09
再次修改
好的,我现在遇到了你的问题。
我不知道如何在不先处理String的情况下解决这个问题。我们的想法是将原始字符串中的月份替换为综合月份:
String[] givenMonths = { "jan", "fév", "mars", "avr.", "mai", "juin", "juil", "août", "sept", "oct", "nov", "déc" };
String[] realMonths = { "janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc." };
String original = "09-oct-08";
for (int i = 0; i < givenMonths.length; i++) {
original = original.replaceAll(givenMonths[i], realMonths[i]);
}
String format2 = "dd-MMM-yy";
DateFormat df2 = new SimpleDateFormat(format2, Locale.FRENCH);
Date date = df2.parse(original);
System.out.println("--> " + date);
我同意,这很糟糕,但如果您使用 SimpleDateFormat
和 Date
类,我看不到任何其他解决方案。
另一种解决方案是使用真实日期和时间库而不是原始JDK,例如 Joda Time 。
String format2 = "dd-MMM-yy";
Date date = Calendar.getInstance().getTime();
SimpleDateFormat sdf = new SimpleDateFormat(format2);
System.out.println(sdf.format(date));
输出 28-Oct-09
我没有看到任何一点,先生。你有没有尝试过重新检查你的指纹?也许你不小心放了 .
你旁边 MMM
?
你越来越 java.text.ParseException: Unparseable date: "09-oct-08"
由于 "09-oct-08"
不匹配的格式 Locale.FRENCH
无论是使用的默认区域(美国,我认为)或者添加一个 .
你旁边 oct
好的,然后尝试«蛮力»:)
DateFormatSymbols dfs = new DateFormatSymbols(Locale.FRENCH);
String[] months = new String[13]
<fill with correct month names or just replace these month, that are not fully correct>
dfs.setMonths(months);
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yy", dfs);
Date nweDate = sdf.parse("09-fév-08");
java.time
让我们看看 java.time 框架是否可以提供帮助。
关于java.time
java.time Java 8及更高版本中内置的框架取代了麻烦的旧java.util.Date/.Calendar类。新课程的灵感来自非常成功的 Joda-Time 框架,旨在作为其继任者,类似在概念,但重新设计。由 JSR 310 定义。通过 ThreeTen-Extra 项目进行扩展。请参阅教程。
<代码> LOCALDATE 代码>
与旧类不同,java.time提供 LocalDate
类表示仅限日期的值,没有时间或时区。
法文缩写
在enFrançais中查看java.time中格式化程序对缩写月份名称的期望。
我们可以循环 Month 代码>
枚举以获取月份列表。此枚举提供 getDisplayName
用于生成月份的本地化名称的方法。此代码演示该方法生成与java.time格式化程序相同的输出。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "dd-MMM-yyyy" ).withLocale ( Locale.FRENCH );
for ( Month month : Month.values () ) {
LocalDate localDate = LocalDate.of ( 2015 , month.getValue () , 1 );
String output = formatter.format ( localDate );
String displayName = month.getDisplayName ( TextStyle.SHORT , Locale.FRENCH );
System.out.println ( "output: " + output + " | displayName: " + displayName );// System.out.println ( "input: " + input + " → " + localDate + " → " + output );
}
output: 01-janv.-2015 | displayName: janv.
output: 01-févr.-2015 | displayName: févr.
output: 01-mars-2015 | displayName: mars
output: 01-avr.-2015 | displayName: avr.
output: 01-mai-2015 | displayName: mai
output: 01-juin-2015 | displayName: juin
output: 01-juil.-2015 | displayName: juil.
output: 01-août-2015 | displayName: août
output: 01-sept.-2015 | displayName: sept.
output: 01-oct.-2015 | displayName: oct.
output: 01-nov.-2015 | displayName: nov.
output: 01-déc.-2015 | displayName: déc.
我们发现3到4个字母拼写的组合。较长的名称缩写为四个字符加一个句点(完全停止 )。四个月的名称足够短,无需使用缩写: mars
, mai
, juin
,août
。
因此,正如其他答案中所讨论的那样,没有简单的解决方案。
修复数据源
我的第一个建议是修复您的数据源。该来源显然没有遵循法国缩写的正确规则。 耶鲁大学同意Java 8对法语的理解。顺便说一句,如果修复你的数据源,我强烈建议使用四位数的年份,因为这两年导致混乱和模棱两可的结束。
修复输入
当然,消息来源可能不受你的控制/影响。在这种情况下,与其他Answers一样,您可能需要进行强力替换而不是尝试任何聪明。另一方面,如果您输入的唯一问题是缺少句点(FULL STOP),那么您可以使用 Month
枚举进行软编码,而不是硬编码不正确的值。
我会进行初步的解析尝试。用于 DateTimeParseException
的陷阱,在尝试修复之前。如果抛出异常,则修复输入。
要修复输入,请通过循环可能的枚举实例集来尝试一年中的每个月。每月,获取其缩写名称。从该缩写中删除句点(FULL STOP),以匹配我们怀疑的不正确的传入值。测试是否确实匹配输入。如果没有,请转到下个月。
当我们获得匹配时,修复输入以适当缩写Locale的规则(在我们的例子中为法语规则)。然后解析固定输入。这将是我们的第二次解析尝试,因为我们首先尝试了。如果第二次尝试失败,那就是
我遇到了同样的问题(法语和额外的点)我相信解决这个问题的正确方法是全局覆盖法语区域设置,如下所示:
import moment from 'moment';
moment.locale('fr', { monthsShort: 'janv_févr_mars_avr_mai_juin_juil_août_sept_oct_nov_déc'.split('_') });
原始的 monthsShort
法国对象有点像
janv._févr._mars_avr._...
,所以我们只是删除它们。
这是指向文档的链接,您可以在其中查看可覆盖的内容
请注意,如果我们只想覆盖ie: monthsShort
,我们不需要传递完整的语言环境对象。