为什么SimpleDateFormat忽略了语言环境?

时间:2017-04-11 07:13:56

标签: java android datetime locale simpledateformat

根据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  
-----------  

但是,这是如何工作的(I)预期的?为什么 yyyy-MM-dd HH:mm:ssdd-MMM-yyyy表现得如此不同?

4 个答案:

答案 0 :(得分:1)

它不会被忽略,但是您正在从String中解析日期,并将其转换为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.

答案 1 :(得分:1)

作为this answer discussesLocale没有合适的时区。因此,当您解析日期字符串时,将使用默认时区,该时区似乎为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没有时区,它只是一个任意时间点。

答案 2 :(得分:0)

由于您似乎想要获得区域设置的标准格式,因此您应该这样做:

DateFormat.getDateTimeInstance(DateFormat.LONG, Locale.FRANCE);

现在您不必指定模式,而是模式将是给定区域设置常见的模式。

答案 3 :(得分:0)

如果您按上述方式使用它(通过指定模式),Locale不会更改顺序。它不会将MM / dd / yy更改为dd / MM / yy。

区域设置仅将4月更改为apr或更改为avr或....

如果您希望根据区域设置进行更改,则必须使用DateFormat.LONG或FormatStyle.LONG指定模式。