Java: контролл корректировки времени

В середине 2011 года вышел закон, в котором отменяется певод времени на летнее. #СПАСИБОСАМИЗНАЕТЕЗАЭТО.

Вот только кто софту скажет что всё поменялось? В частности в джаве есть косяки Оракл не торопится выпускать апдейт под венду, который исправляет время.
Напомню, что даже если в венде поставленны патчи и оно показывается правильное время, джава будет по-прежнему показывать GMT+3 (вместо GMT+4), т.е. на час раньше.

Да, оракл выпустил патч (глазам не поверил – консольная тузла) под винду, которая помогает системным администатором всё вернуть в рабочий режим. Я так и не смог накатить его на рабочую машинку, видимо фиговый из меня админ, ога :-/ . Да и желания фиксить таким образом нет – ну ок, я сделаю это на своей машине, а пользователи? Надо им разбираться там куда что как писать и запускать? Важно понимать, что если моя программа показывает не правильно, то виноват именно я, а не оракл или самизанаетекто.

Я запарился с этим возится (не предстваляю как пришлось бы мучатся конечным юзерам) и сделал мега костыль в программке на swing (десктопный клиент-нотификатор к SugarCRM) – при старте даю возможность “подогнать” смещение времени так, чтоб стало “как нужно”.

Суть задачи

Получилось большое введение :). Задача в создании “красивого” контролла для ввода коррекции времени.

Решается достаточно просто, но пришлось скомпоновать много похожих решений в сети


fldTimeFix = new JSpinner(new SpinnerNumberModel(0, -12, +12, 1));
JSpinner.NumberEditor numberEditor = new JSpinner.NumberEditor(fldTimeFix);
JFormattedTextField formattedTextField = numberEditor.getTextField();
NumberFormatter fmt = new NumberFormatter(new DecimalFormat("'+'00':00';'-'00':00'"));
fmt.setValueClass(fldTimeFix.getValue().getClass());
DefaultFormatterFactory fmtFactory = new DefaultFormatterFactory(fmt, fmt, fmt);
formattedTextField.setFormatterFactory(fmtFactory);
formattedTextField.setEditable(false);
fldTimeFix.setEditor(numberEditor);

UPD: скорректированное время

Вариант привести к нормальному виду (ибо непонятно по отношению к чему человек выставляет смещение). Справа от Spinner’a поставить время, которе получилось после внесения коррекции.

Так явно посимпотичнее. Зато количество кода на такую “мелочь” увеличилось значительно. Важно не забывать останавливать таймер когда фрейм не активен (в моём случае он не создаётся заново при открытии), и запускать когда появляется.


private void fillContent() {
. . . . .
fldTimeFix = new JSpinner(new SpinnerNumberModel(0, -12, +12, 1));
JSpinner.NumberEditor numberEditor = new JSpinner.NumberEditor(fldTimeFix);
JFormattedTextField formattedTextField = numberEditor.getTextField();
NumberFormatter fmt = new NumberFormatter(new DecimalFormat("'+'00':00 ';'-'00':00 '"));
fmt.setValueClass(fldTimeFix.getValue().getClass());
DefaultFormatterFactory fmtFactory = new DefaultFormatterFactory(fmt, fmt, fmt);
formattedTextField.setFormatterFactory(fmtFactory);
formattedTextField.setEditable(false);
fldTimeFix.setEditor(numberEditor);

final Panel timeFixPanel = new Panel(new GridLayout(1, 2, 4, 1));

timeFixPanel.add(fldTimeFix, BorderLayout.PAGE_START);

lblTimeFixResult = new JLabel("--:--");
timeFixPanel.add(lblTimeFixResult, BorderLayout.PAGE_END);
. . . . .
timerFixTime = new Timer(990, updateFixTimeResult);

fldTimeFix.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent ce) {
updateFixTimeResult.actionPerformed(null);
}
});
}

private Action updateFixTimeResult = new AbstractAction() {
private final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
@Override
public void actionPerformed(ActionEvent e) {
Calendar nc = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
nc.add(Calendar.HOUR, getTimeFixHours());
lblTimeFixResult.setText(" " + sdf.format(nc.getTime()));
}
};

@Override
public void setVisible(boolean isVis) {
super.setVisible(isVis);
if (isVis) timerFixTime.start();
else timerFixTime.stop();
}


Все эти манипуляции с календарём – вынужденная мера. Да, прям вот так руками пришлось пересчитывать время GMT. :(

Справа – как выглядит под вендой