【问题标题】:JSpinner showing time has constant hours offset despite correct value尽管值正确,但显示时间的 JSpinner 具有恒定的小时偏移量
【发布时间】:2017-07-04 00:29:53
【问题描述】:

我有以下应该在 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 小时偏移量。

【问题讨论】:

    标签: java swing time jspinner


    【解决方案1】:

    我认为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);
        });
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2023-01-22
      • 2019-03-08
      • 2019-09-27
      • 2023-03-16
      • 1970-01-01
      • 2015-06-14
      • 2014-09-26
      • 2020-10-01
      • 1970-01-01
      相关资源
      最近更新 更多