根据javadocs,我可以创建一个可以识别语言环境的SimpleDateFormat
。
但是尝试以下代码:
Locale [] locales = {
Locale.GERMANY,
Locale.CANADA_FRENCH,
Locale.CHINA,
Locale.ITALIAN,
Locale.JAPANESE,
Locale.ENGLISH
};
try {
for(Locale locale : locales) {
final SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", locale);
System.out.println(myFormat.parse("2017-04-01 12:00:01"));
}
} catch (ParseException e) {
e.printStackTrace();
}
我在输出中看到:
Sat Apr 01 12:00:01 CEST 2017
Sat Apr 01 12:00:01 CEST 2017
Sat Apr 01 12:00:01 CEST 2017
Sat Apr 01 12:00:01 CEST 2017
Sat Apr 01 12:00:01 CEST 2017
Sat Apr 01 12:00:01 CEST 2017
那么,为什么无论区域设置如何,日期格式都相同呢?
评论后更新:
for(Locale locale : locales) {
System.out.println("Locale " + locale);
final SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", locale);
System.out.println(myFormat.parse("2017-04-01 12:00:01"));
System.out.println(myFormat.format(myFormat.parse("2017-04-01 12:00:01")));
System.out.println("-----------");
}
上面的代码片段打印:
-----------
Locale zh_CN
Sat Apr 01 12:00:01 CEST 2017
2017-04-01 12:00:01
-----------
Locale it
Sat Apr 01 12:00:01 CEST 2017
2017-04-01 12:00:01
-----------
Locale ja
Sat Apr 01 12:00:01 CEST 2017
2017-04-01 12:00:01
-----------
Locale en
Sat Apr 01 12:00:01 CEST 2017
2017-04-01 12:00:01
-----------
更新 2:
以下代码考虑了区域设置:
final SimpleDateFormat myFormat1 = new SimpleDateFormat("dd-MMM-yyyy");
final SimpleDateFormat myFormat = new SimpleDateFormat("dd-MMM-yyyy", locale);
Date date = myFormat1.parse("05-Apr-2017");
String out = myFormat.format(date);
System.out.println(out);
System.out.println("-----------");
输出为:
Locale de_DE
05-Apr-2017
-----------
Locale fr_CA
05-avr.-2017
-----------
Locale zh_CN
05-四月-2017
-----------
Locale it
05-apr-2017
-----------
Locale ja
05-4-2017
-----------
Locale en
05-Apr-2017
-----------
但是,为什么这像(我(预期的那样工作?为什么 yyyy-MM-dd HH:mm:ss
和dd-MMM-yyyy
的行为如此不同?
正如这个答案所讨论的,Locale
没有合适的时区。 因此,当您解析日期字符串时,将使用默认时区,该时区似乎是 CEST
,即在中西部的某个地方。 如果您改为为SimpleDateFormat
分配时区,您将获得所需的行为:
String[] tzs = new String[]{
"Europe/Berlin",
"Canada/Eastern",
"Asia/Shanghai",
"Europe/Rome",
"Asia/Tokyo",
"America/New_York"
};
for (String tz : tzs) {
SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz");
TimeZone timeZone = TimeZone.getTimeZone(tz);
myFormat.setTimeZone(timeZone);
System.out.println(myFormat.format(new Date()));
}
输出:
2017-04-11 09:52:42 CEST
2017-04-11 03:52:42 EDT
2017-04-11 15:52:46 CST
2017-04-11 09:52:47 CEST
2017-04-11 16:52:49 JST
2017-04-11 03:52:50 EDT
如果要将日期字符串转换为时间戳,则可以浏览Java Date
对象。 请注意,Java Date
没有时区,它只是一个任意时间点。
不会被忽略,但您正在解析字符串中的日期,该日期将转换为java.util.Date
。 这些始终以相同的方式打印。
相反,如果您使用的是format
方法,您将获得预期的结果:
Date date = myFormat.parse("2017-04-01 12:00:01"); // Creates a Date object
String locallyFormattedDate = myFormat.format(date); // formats that Date object according to locale.
由于您似乎想要获取区域设置的标准格式,因此您应该这样做:
DateFormat.getDateTimeInstance(DateFormat.LONG, Locale.FRANCE);
现在,您不必指定模式,而是给定区域设置通用的模式。
如果您如上所述使用它(通过指定模式(,则 Locale 不会更改顺序。它不会将 MM/dd/yy 更改为 dd/MM/yy。
区域设置仅将 Apr 更改为 apr 或 avr 或 ....
如果您希望根据区域设置更改它,则必须使用 DateFormat.LONG 或 FormatStyle.LONG 指定模式。