尽管值正确,但显示时间的 JSpinner 具有恒定的小时偏移量



我有以下一段代码,应该在JSpinner对象中显示时间

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.AM_PM, 0);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
spStartTime = new JSpinner(new CustomSpinnerModel(cal.getTime(), null, null, cal.get(Calendar.HOUR_OF_DAY), 100, "start"));
((JSpinner.DefaultEditor) spStartTime.getEditor()).getTextField().setFormatterFactory(new DefaultFormatterFactory(new DateFormatter(new SimpleDateFormat("hh:mm:ss,SSS"))));

CustomSpinnerModel 扩展了 SpinnerDateModel,我正在覆盖 getNextValue(( 和 getPreviousValue((。

public Object getNextValue()
{
    Object next = super.getValue();
    Calendar calendar = new GregorianCalendar();
    calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
    calendar.setTime((Date) next);
    Date helper = new Date(calendar.getTimeInMillis() + defaultStep);
    calendar.setTime(helper);
    System.out.println(calendar.getTimeInMillis());
    return calendar.getTime();
}

现在,当我第一次点击向上箭头时,它会打印 100 毫秒,这意味着该值是正确的,因为我从 0 毫秒开始。问题是我在JSpinner中看到的是

02:00:00,100

可视化中有一个恒定的 2 小时偏移量。

我认为DateFormat#setTimeZone(TimeZone(就是你要找的:

//((JSpinner.DefaultEditor) spStartTime.getEditor()).getTextField()
//  .setFormatterFactory(new DefaultFormatterFactory(
//    new DateFormatter(new SimpleDateFormat("hh:mm:ss,SSS"))));
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss,SSS");
format.setTimeZone(TimeZone.getTimeZone("GMT"));
((JSpinner.DefaultEditor) spStartTime.getEditor()).getTextField()
    .setFormatterFactory(new DefaultFormatterFactory(
      new DateFormatter(format)));
import java.awt.*;
import java.text.*;
import java.util.*;
import javax.swing.*;
import javax.swing.text.*;
public class DateEditorTimeZoneTest {
  public JComponent makeUI() {
    SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss,SSS");
    format.setTimeZone(TimeZone.getTimeZone("GMT"));
    Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
    cal.clear(Calendar.HOUR_OF_DAY);
    cal.clear(Calendar.AM_PM);
    cal.clear(Calendar.HOUR);
    cal.clear(Calendar.MINUTE);
    cal.clear(Calendar.SECOND);
    cal.clear(Calendar.MILLISECOND);
    Date start = cal.getTime();
    System.out.println(start);
    System.out.println(format.format(start));
    int defaultStep = 100;
    JSpinner spinner = new JSpinner(new SpinnerDateModel(
            start, null, null, Calendar.MILLISECOND) {
      @Override public void setCalendarField(int calendarField) {
        // If you only want one field to spin you can subclass
        // and ignore the setCalendarField calls. 
      }
      @Override public Object getNextValue() {
        Object next = super.getValue();
        Calendar calendar = new GregorianCalendar();
        calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
        calendar.setTime((Date) next);
        Date helper = new Date(calendar.getTimeInMillis() + defaultStep);
        calendar.setTime(helper);
        System.out.println(calendar.getTimeInMillis());
        return calendar.getTime();
      }
      //@Override public Object getPreviousValue() {
      //  //...
      //}
    });
    JSpinner.DateEditor editor = new JSpinner.DateEditor(spinner, "HH:mm:ss,SSS");
    spinner.setEditor(editor);
    editor.getTextField().setFormatterFactory(
        new DefaultFormatterFactory(new DateFormatter(format)));
    JPanel p = new JPanel();
    p.add(spinner);
    return p;
  }
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new DateEditorTimeZoneTest().makeUI());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

最新更新