В настоящее время я пытаюсь написать набор программ проверки часовых поясов, чтобы узнать, интерпретируют ли различные платформы Данные часового пояса ИАНЫ.
Формат вывода, на который я нацелен, включает сокращение, действующее для определенного времени, например "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 для Америки / Нью-Йорка, но ничего для Европы / Лондона; с локалью Великобритании я вижу GMT / BST для Европы / Лондона, но ничего для Америки / Нью-Йорка :(
Есть ли способ убедить 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 именно то, что я хочу - я подозреваю, что информация просто недоступна :(
format.setTimeZoneFormat(format.getTimeZoneFormat().setTimeZoneNames(TimeZoneNames.getTZDBInstance(ULocale.US)))
? - person RealSkeptic   schedule 25.07.2015TimeZoneNames
, который делает код чище. До 1970 года мне это не помогает, но все же лучше ... - person Jon Skeet   schedule 25.07.2015getMetaZoneID(String,long)
. Это, в свою очередь, вызываетcom.ibm.icu.impl.TimeZoneNamesImpl._getMetaZoneID(String,long)
, который, в свою очередь, вызывает this thing, где 1 января 1970 года жестко запрограммировано какfrom
точка. - person RealSkeptic   schedule 25.07.2015