我正在开发一个阿拉伯语的网络监控项目,我想像这样转换字符串日期:
الاثنين 24 أبريل 2017 - 15:00
到 Java 8 日期对象。我怎样才能做到这一点?
我正在开发一个阿拉伯语的网络监控项目,我想像这样转换字符串日期:
الاثنين 24 أبريل 2017 - 15:00
到 Java 8 日期对象。我怎样才能做到这一点?
编辑:感谢 slim 和 Meno Hochschild 的灵感:
String dateTimeString = "الاثنين 24 أبريل 2017 - 15:00";
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("EEEE d MMMM uuuu - HH:mm", new Locale("ar"));
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter);
System.out.println(dateTime);
这打印:
2017-04-24T15:00
@Ole 和 @slim 的答案是有效的,但不是因为他们认为的原因。
第一次观察 - 对于给定的例子,nu-extension 是不必要的:
Oles 建议也适用于 localenew Locale("ar", "SA")
而不是Locale.forLanguageTag("ar-SA-u-nu-arab")
. 那么这里的 unicode-nu-extension 是什么?没有什么。下一个问题:
nu-extension 应该在这里做什么?
nu-code-word "arab"由 unicode consortium 指定以产生阿拉伯-印度数字。但是要解析的输入只有西方数字 0-9(在历史上被阿拉伯人取代并指定为代码字“latn”——顺便说一句用词不当)。因此,如果 nu-extension 真的在这里完成了它的工作,那么解析应该会失败,因为阿拉伯印度数字不是 0-9,而是:
٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩
显然,Java-8 中的新时间 API 通常不支持 nu 扩展。
是否SimpleDateFormat
支持 nu 扩展?
使用以下代码的调试,我发现仅泰语数字支持 nu 扩展名(另请参阅 class 的官方 javadoc,java.util.Locale
但不支持阿拉伯印度数字:
SimpleDateFormat sdf =
new SimpleDateFormat("EEEE d MMMM yyyy - HH:mm", Locale.forLanguageTag("ar-SA-nu-arab"));
Date d = sdf.parse(dateTimeString);
System.out.println(d);
String formatted = sdf.format(d);
System.out.println(formatted);
System.out.println(sdf.format(d).equals(dateTimeString));
sdf = new SimpleDateFormat("EEEE d MMMM uuuu - HH:mm", Locale.forLanguageTag("ar-SA-u-nu-thai"));
String thai = sdf.format(d);
System.out.println("u-nu-thai: " + thai);
我假设DateTimeFormatter
Java-8 类也支持泰语数字。
结论:
忘记 nu 扩展名。只需通过不带 unicode 扩展的老式方式构建语言环境,并以这种方式调整 Oles 回答。它之所以有效,是因为您的输入只有西方数字 0-9。
对于广泛的 i18n 支持,包括各种编号系统的 nu 扩展(如果您有这样的输入),您可以考虑使用外部库(例如 ICU4J 或我的 lib Time4J)。
我对阿拉伯语的了解不足,无法理解阿拉伯语格式的日期。但是这段代码:
Locale arabicLocale = new Locale.Builder().setLanguageTag("ar-SA-u-nu-arab").build();
LocalDate date = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(arabicLocale);
String formatted = date.format(formatter);
System.out.println(formatted);
System.out.println(formatter.parse(formatted));
产生这个输出:
26 أبريل, 2017
{},ISO resolved to 2017-04-26
创建的代码来自对设置阿拉伯编号系统区域设置Locale
的答案不显示阿拉伯数字
您可以通过定义自己的FormatStyle
.
您必须在解析字符串时指定字符集,假设您要解析的日期将始终采用您提供的格式,这将起作用:
public static Date getDate(String strDate) throws Exception{
strDate=new String(strDate.getBytes(),"UTF-8");
Map<String, Integer> months = new HashMap<>();
String JAN = new String("يناير".getBytes(), "UTF-8");
String FEB = new String("فبراير".getBytes(), "UTF-8");
String MAR = new String("مارس".getBytes(), "UTF-8");
String APR = new String("أبريل".getBytes(), "UTF-8");
String APR_bis = new String("ابريل".getBytes(), "UTF-8");
String MAY = new String("ماي".getBytes(), "UTF-8");
String JUN = new String("بونيو".getBytes(), "UTF-8");
String JUN_bis = new String("يونيه".getBytes(), "UTF-8");
String JUL = new String("يوليوز".getBytes(), "UTF-8");
String AUG = new String("غشت".getBytes(), "UTF-8");
String SEP = new String("شتنبر".getBytes(), "UTF-8");
String SEP_bis = new String("سبتمبر".getBytes(), "UTF-8");
String OCT = new String("أكتوبر".getBytes(), "UTF-8");
String OCT_bis = new String("اكتوبر".getBytes(), "UTF-8");
String NOV = new String("نونبر".getBytes(), "UTF-8");
String NOV_bis = new String("نوفمبر".getBytes(), "UTF-8");
String DEC = new String("دجنبر".getBytes(), "UTF-8");
String DEC_bis = new String("ديسمبر".getBytes(), "UTF-8");
months.put(JAN, 0);
months.put(FEB, 1);
months.put(MAR, 2);
months.put(APR, 3);
months.put(APR_bis, 3);
months.put(MAY, 4);
months.put(JUN, 5);
months.put(JUN_bis, 5);
months.put(JUL, 6);
months.put(AUG, 7);
months.put(SEP, 8);
months.put(SEP_bis, 8);
months.put(OCT, 9);
months.put(OCT_bis, 9);
months.put(NOV, 10);
months.put(NOV_bis, 10);
months.put(DEC, 11);
months.put(DEC_bis, 11);
StringTokenizer stringTokenizer = new StringTokenizer(strDate);
Calendar calendar = Calendar.getInstance();
while(stringTokenizer.hasMoreElements()) {
stringTokenizer.nextElement();// to skip the first string which is the name of the day
int day = Integer.parseInt(stringTokenizer.nextElement().toString().trim());
String strMonth = stringTokenizer.nextElement().toString().trim();
int month = months.get(strMonth);
int year = Integer.parseInt(stringTokenizer.nextElement().toString().trim());
calendar.set(year, month, day);
}
return calendar.getTime();
}
它给出了这个输出:
Fri Oct 20 15:26:47 WEST 2017
一种解决方案可能是将日期翻译成英文然后解析它:
private final static Map<String, Integer> monthMapping = new HashMap<>();
static {
// list of all month.
monthMapping.put("أبريل", "4");
}
public Date fromArabicToDate(String arabicInput) throws ParseException {
String[] parts = arabicInput.split(" ");
if (parts.length != 4)
throw new IllegalArgumentException();
String dateInput = parts[0] + "-" + monthMapping.get(parts[1]) + "-" + parts[2];
SimpleDateFormat parser = new SimpleDateFormat("YYYY-MM-DD");
return parser.parse(dateInput);
}
我试图复制月份,但我不相信我做得正确。put
解析时切换的参数。