В настоящее время я пытаюсь написать набор программ проверки часовых поясов, чтобы узнать, интерпретируют ли различные платформы время IANA данные зоны.
Формат вывода, на который я нацелен, включает аббревиатуру, действующую в течение определенного времени - например, "BST" для "Британского летнего времени" или "PST" для "Тихоокеанского стандартного времени".
На большинстве платформ это легко - но ICU4J, похоже, не работает, как ни странно. Согласно документации SimpleDateFormat
, я должен использовать шаблон "zzz", чтобы получить то, что я ищу, но это, похоже, возвращается к "O" в GMT + X в течение долгого времени. Для некоторых часовых поясов аббревиатуры вообще отсутствуют.
Короткий пример с использованием Нью-Йорка:
import java.util.Date;
import java.util.Locale;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.text.SimpleDateFormat;
public class Test {
public static void main(String[] args) {
TimeZone zone = TimeZone.getTimeZone("America/New_York");
SimpleDateFormat format = new SimpleDateFormat("zzz", Locale.US);
format.setTimeZone(zone);
// One month before the unix epoch
System.out.println(format.format(new Date(-2678400000L))); // GMT-5
// At the unix epoch
System.out.println(format.format(new Date(0L))); // EST
}
}
(Я запускаю с помощью ICU4J 55.1, как загрузку запаса, так и после обновления с выпуском данных 2015e.)
Мне не ясно, получает ли ICU4J свои сокращения из данных tz или из CLDR - я подозреваю, что это последнее, учитывая, что в данных tz нет ничего, чтобы предложить здесь разницу.
На него, похоже, также влияет языковой стандарт, который, я полагаю, является разумным - с использованием американского языка я могу видеть EST/EDT для America/New_York, но ничего для Европы/Лондона; с британским языком я вижу GMT/BST для Европы/Лондона, но ничего для Америки /New _York: (
Есть ли способ убедить ICU4J вернуться к сокращениям tz? В моем конкретном случае, все, что я ищу.
Обновление
Благодаря комментариям RealSkeptic, похоже, что TimeZoneNames
- более чистый способ получения этих данных без форматирования. Все это звучит так многообещающе - там даже TimeZoneNames.getTZDBInstance
:
Возвращает экземпляр TimeZoneNames, содержащий только короткие имена определенных зон (
TimeZoneNames.NameType.SHORT_STANDARD
иTimeZoneNames.NameType.SHORT_DAYLIGHT
), совместимые с аббревиатурами зоны базы данных IANA tz (не локализованные).
Это в значительной степени то, что я хочу - но это не происходит в 1970 году в большинстве случаев и не включает в себя все соответствующие данные:
import static com.ibm.icu.text.TimeZoneNames.NameType.SHORT_STANDARD;
import com.ibm.icu.text.TimeZoneNames;
import com.ibm.icu.text.TimeZoneNames.NameType;
import com.ibm.icu.util.ULocale;
public class Test {
public static void main(String[] args) {
TimeZoneNames names = TimeZoneNames.getTZDBInstance(ULocale.ROOT);
long december1969 = -2678400000L;
// 24 hours into the Unix epoch...
long january1970 = 86400000L;
// null
System.out.println(
names.getDisplayName("America/New_York", SHORT_STANDARD, december1969));
// EST
System.out.println(
names.getDisplayName("America/New_York", SHORT_STANDARD, january1970));
// null
System.out.println(
names.getDisplayName("Europe/London", SHORT_STANDARD, december1969));
// null
System.out.println(
names.getDisplayName("Europe/London", NameType.SHORT_STANDARD, january1970));
}
}
Учитывая, что на данный момент на самом деле очень мало косвенности - я говорю ICU4J точно, что хочу, - мое подозрение в том, что информация просто недоступна: (