2016-06-20 21 views
6

Tôi đang cố gắng hiểu một số mã SimpleDateFormat. Đặc biệt tôi đang cố gắng sử dụng các chuỗi mẫu được bản địa hóa trong SimpleDateFormat. Từ số javadoc:SimpleDateFormat Lỗi ký tự mẫu không hợp lệ với mẫu được bản địa hóa

SimpleDateFormat cũng hỗ trợ chuỗi mẫu ngày và giờ được bản địa hóa. Trong các chuỗi này, các mẫu chữ được mô tả ở trên có thể được thay thế bằng các chữ cái mẫu, phụ thuộc, ngôn ngữ khác.

Nó cũng xác định một constructor SimpleDateFormat(String pattern, DateFormatSymbols formatSymbols):

Constructs một cá thể SimpleDateFormat sử dụng mô hình nhất định và những biểu tượng định dạng ngày tháng.

Tuy nhiên, mặc dù getLocalPatternChars() dụ được trình bày các nhân vật mô hình dự kiến, nhà thầu SimpleDateFormat của đang từ chối mẫu có chứa những ký tự:

public void run() { 
    Locale loc = new Locale("de", "de"); 
    DateFormatSymbols dfs = new DateFormatSymbols(loc); 
    String sym = dfs.getLocalPatternChars(); 
    System.out.println(sym); 
    SimpleDateFormat datefmt = new SimpleDateFormat("tt.MM.uuuu", dfs); 
} 

sản xuất đầu ra:

GuMtkHmsSEDFwWahKzZ 
Exception in thread "main" java.lang.IllegalArgumentException: Illegal pattern character 't' 
    at java.text.SimpleDateFormat.compile(SimpleDateFormat.java:845) 
    ... 

Tôi nhận được cùng một đầu ra nếu Tôi thay thế dòng cuối cùng bằng "... new SimpleDateFormat("tt.MM.uuuu", loc);".

Mặt khác, nếu tôi tạo một cá thể SimpleDateFormat bằng bất kỳ chuỗi mẫu Anglicized nào, sau đó gọi "applyLocalizedPattern("tt.MM.uuuu")", mẫu được bản địa hóa được chấp nhận.

Vì vậy, có vẻ như người ta không thể sử dụng chuỗi mẫu được bản địa hóa trong các hàm tạo của SimpleDateFormat và cần khởi tạo hai bước này. Hành vi có chủ ý này?

+2

Hàm tạo không gọi 'translatePattern' (' applyLocalizedPattern' làm điều đó), vì vậy đây là lỗi hoặc một JavaDoc không rõ ràng giải thích cách sử dụng hàm tạo. – Tom

+0

@Tom đúng. Tham số mẫu của hàm tạo chỉ đề cập đến các ký tự mẫu-ngày-thời gian không được tập trung. –

+0

Xem thêm http://stackoverflow.com/a/24128930/2491410 –

Trả lời

3

Thật không may tài liệu về cách xử lý các mẫu được bản địa hóa là khủng khiếp. Vì vậy, tôi đã nghiên cứu mã nguồn và thực hiện các cuộc điều tra của riêng tôi. Kết quả:

Phương thức khởi tạo của SimpleDateFormat chấp nhận chuỗi mẫu chỉ đề cập đến các ký tự mẫu không được định vị có định nghĩa được ghi trong tiêu đề javadoc của lớp SimpleDateFormat. Những nhân vật mẫu unlocalized cũng được định nghĩa là liên tục trong DateTimeFormatSymbols:

/** 
* Unlocalized date-time pattern characters. For example: 'y', 'd', etc. 
* All locales use the same these unlocalized pattern characters. 
*/ 
static final String patternChars = "GyMdkHmsSEDFwWahKzZYuXL"; 

Ba bước cần thiết để sử dụng mô hình cục bộ (như "tt.MM.uuuu" những gì mà bạn tin là Đức - nhưng là KHÔNG Tiếng Đức, thay vì phải là "TT.MM.JJJJ" - ví dụ cho các tài nguyên JDK sai):

  1. Xác định các ký tự mẫu được bản địa hóa qua DateFormatSymbols.setLocalPatternChars(...).
  2. Sử dụng biểu tượng định dạng ngày tùy chỉnh trên SimpleDateFormat -object của bạn.
  3. Áp dụng từ ngày thời gian mô hình cục bộ qua SimpleDateFormat.applyLocalizedPattern(...)

Sau đó, mô hình cục bộ sẽ được dịch sang các định nghĩa mô hình nhân vật nội bộ và chính thức.

Ví dụ về cách sử dụng (sử dụng đúng kiểu Đức TT.MM.JJJJ):

SimpleDateFormat sdf = new SimpleDateFormat(); // uses default locale (here for Germany) 
System.out.println(sdf.toPattern()); // dd.MM.yy HH:mm 
System.out.println(sdf.toLocalizedPattern()); // tt.MM.uu HH:mm 

DateFormatSymbols dfs = DateFormatSymbols.getInstance(Locale.GERMANY); 
dfs.setLocalPatternChars("GJMTkHmsSEDFwWahKzZYuXL"); 
sdf.setDateFormatSymbols(dfs); 
sdf.applyLocalizedPattern("TT.MM.JJJJ"); 

System.out.println(sdf.toPattern()); // dd.MM.yyyy 
System.out.println(sdf.toLocalizedPattern()); // TT.MM.JJJJ 
System.out.println(sdf.format(new Date())); // 20.06.2016 

Side lưu ý: Tôi đã thay đổi mô hình thích hợp chars y và d để J và T trong chuỗi "GyMdkHmsSEDFwWahKzZYuXL" để tạo ra một định nghĩa cục bộ.

Thật không may là tài nguyên JDK rõ ràng là không đáng tin cậy vì vậy quan điểm cá nhân của tôi là toàn bộ tính năng chỉ có thể được sử dụng một cách khó xử và không thực sự hữu ích trong thực tế.

+0

Tôi cũng đã tìm kiếm trong dữ liệu CLDR cho các ký tự mẫu theo thời gian được bản địa hóa như "GyMdkHmsSEDFwWahKzZYuXL" nhưng chưa được tìm thấy. Vì vậy, nó không phải là rõ ràng đối với tôi như thế nào Sun/Oracle được những dữ liệu này. Đó có phải là dự đoán của riêng họ không? Có lẽ ai đó biết nhiều hơn về nguồn dữ liệu được bản địa hoá? –

+0

Không sao, các phiên bản cũ của dữ liệu CLDR biết phần tử . Nó đã không được chấp nhận và không còn được điền (trong CLDR v29). Vì vậy, JDK dường như sử dụng dữ liệu cũ. Xem thêm [ICU-ticket] này (https://sourceforge.net/p/icu/mailman/message/10846249/) –

Các vấn đề liên quan