问题描述
我希望具有美国或德国系统区域设置的用户获得正确的"本地化时间.表示"1:00 PM"和"13:00"
I want the "correct" localized time for users with US or German system locale. Meaning "1:00 PM" and "13:00"
Java API说: https://docs.oracle.com /javase/tutorial/i18n/format/dateFormat.html
Java API says: https://docs.oracle.com/javase/tutorial/i18n/format/dateFormat.html
Formats U.S. Locale German Locale
DEFAULT 7:03:47 AM 7:03:47
SHORT 7:03 AM 07:03
到目前为止正确.
Android API: https://developer.android.com/reference/java/text/DateFormat.html
Android API: https://developer.android.com/reference/java/text/DateFormat.html
SHORT is completely numeric, such as 12.13.52 or 3:30pm
更正于美国,如果您设置了德语区域设置,则Android将翻译" AM/PM而不是将其删除,以及正确的方式以及Java的操作方式.
Correct for US, if you set a German Locale, Android will "translate" AM/PM and not remove it, how the correct way is and how Java did it.
我的问题是,为什么Google会这样做?我是不是愚蠢且缺乏睡眠,不了解"Google逻辑"?这是一个微不足道的要求,但我尝试了2个小时才能获得正确的德国短时演讲,这也适用于美国本地化. "13:57 nachm."不是德语时间表示.没有人使用它,这就是我们拥有24小时格式化系统的原因.太尴尬了,它打断了每次阅读的尝试.
My question, why does Google do that? Am I stupid and lacking sleep, not to understand "the Google logic"? This is a trivial request, yet I tried for 2 hours to get a correct German short time presentation, that would also work for US localization. "13:57 nachm." is NOT a German time representation. No one uses that, that's why we have a 24 hour formating system. It's so awkward that it breaks every reading attempt.
测试代码:
private void testGoogleLocaleLogic() {
TimeZone tz_de = TimeZone.getTimeZone("Europe/Berlin");
Calendar c_us = Calendar.getInstance(tz_de,Locale.US);
Calendar c_de = Calendar.getInstance(tz_de,Locale.GERMAN);
java.text.DateFormat df_date_us_short_ = java.text.DateFormat.getTimeInstance(java.text.DateFormat.SHORT,Locale.US);
java.text.DateFormat df_date_de_short = java.text.DateFormat.getTimeInstance(java.text.DateFormat.SHORT,Locale.GERMAN);
c_us.set(Calendar.YEAR,2018);
c_us.set(Calendar.MONTH,2);
c_us.set(Calendar.DAY_OF_YEAR,6);
c_us.set(Calendar.HOUR_OF_DAY,13);
c_de.set(Calendar.YEAR,2018);
c_de.set(Calendar.MONTH,2);
c_de.set(Calendar.DAY_OF_YEAR,6);
c_de.set(Calendar.HOUR_OF_DAY,13);
Log.d("localeTest","Android Dateformat getTimeInstance SHORT US: " + df_date_us_short_.format(c_us.getTime()));
Log.d("localeTest","Android Dateformat getTimeInstance SHORT DE: " + df_date_de_short.format(c_de.getTime()));
Log.d("localeTest","df_date_de_short is type of: " + df_date_de_short.getClass().getName());
}
结果
Android Dateformat SHORT US: 1:57 PM
Android Dateformat SHORT DE: 1:57 nachm.
为什么在德国语言环境中不是13:57,尽管我在Calendar中设置了两次,而DateFormat也不是我所知.
Why it's not 13:57 for German locale, although I set it two times in Calendar and DateFormat is also beyond my knowledge.
一种手动打印分钟和小时,然后在系统语言环境之间切换大小写以添加或隐藏"PM/AM"的解决方案,正是人们首先发明语言环境的原因.为了避免这种情况.请告诉我事实并非如此.
A solution to print out minutes and hours manually and then switch case between system locales to add or hide "PM/AM" is exactly why people invented Locales in the first place. To avoid that. Please tell me this is not the case.
更新/更多测试/更多研究(强制使用java.text ...):
UPDATES/MORE TESTING/MORE RESEARCH (forced use of java.text....):
My Moto X Style,Android 7,德语语言环境打印:
My Moto X Style, Android 7, German locale prints:
Android Dateformat getTimeInstance SHORT US: 1:29 PM
Android Dateformat getTimeInstance SHORT DE: 1:29 nachm.
df_date_de_short is type of: java.text.SimpleDateFormat
Android模拟器NEXUS_5_API_26(美国语言环境)
Android Emulator NEXUS_5_API_26, US locale
Android Dateformat getTimeInstance SHORT US: 1:18 PM
Android Dateformat getTimeInstance SHORT DE: 13:18
df_date_de_short is type of: java.text.SimpleDateFormat
那么强制使用"java.text.SimpleDateFormat"可以,但是只能在模拟器上使用,而不能在现实世界中使用吗?我接近了,也许有人能拿到最后的5美分!
So the forced use of "java.text.SimpleDateFormat" works, but only on an emulator, not in real world? I'm close, maybe someone has the last 5 cents!
推荐答案
可悲的是,我先前的猜测是正确的.如果您不使用此猜测"来搜索它,那么您将永远找不到它,因为日期格式是如此常见.长话短说,这是 Android错误:
My guess earlier was right, sadly. If you don't search for it with this "guess", you'll never find it as date formatting is such a common topic. Long story short, it's an Android bug:
https://issuetracker.google.com/issues/37054851
一年前已修复.这就是为什么仿真器可以工作的原因,但是API27之前的设备将无法修复,因为OEM不在乎.
It was fixed over a year ago. That's why the emulator works, but devices before API27 won't have the fixes as OEM don't care.
Google员工在上述错误报告中添加了此替代方法:
Google employee added this workaround in above bug report:
boolean use24Hour = android.text.format.DateFormat.is24HourFormat(context);
final String skeleton = use24Hour ? "Hm" : "hm";
final String pattern = android.text.format.DateFormat.getBestDateTimePattern(locale, skeleton);
DateFormat formatter = new SimpleDateFormat(pattern, locale);
...表示简短日期. MEDIUM会使用"Hms"/"hms"的框架.上面的代码绕过了内部代码,该内部代码保持(不正确的)内存状态,该状态跟踪用户是喜欢12还是24小时格式. AFAIK,android.text.format.DateFormat.is24HourFormat始终使用基础用户设置.在API 3中添加了is24HourFormat().在API 18中仅添加了getBestDateTimePattern().
... for SHORT date. MEDIUM would use skeletons of "Hms" / "hms" instead.The code above bypasses the internal code that keep the (incorrect) in-memory state that tracks whether the user prefers 12 or 24 hour time formatting. AFAIK, android.text.format.DateFormat.is24HourFormat has always used the underlying user setting.is24HourFormat() was added in API 3. getBestDateTimePattern() was only added in API 18.
这正是我担心人类必须在2018年使用的开关盒垃圾.我们想生活在火星上,但我们不知道如何在地球上打印时间!
That's exactly the switch case crap I feared humanity has to use in the year of 2018. We want to live on Mars, yet we can't figure out how to print time on planet Earth!
这篇关于Android中的Java DateFormat.SHORT无法按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!