You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Calendar.getTime()返回值意外变更问题排查

问题原因

Calendar实例的值变动和读取日期字段的操作没有任何关系,问题出在day_list.setSelectedIndex(d-1)这行代码触发了意料之外的监听器逻辑。

  • 你已经给day_list下拉框绑定了change_date动作监听器,Swing的JComboBox只要执行setSelectedIndex修改选中项,无论触发源是用户手动点击还是代码主动调用,都会立刻触发绑定的所有ActionListener执行。
  • 你写的change_date监听器本身存在逻辑错误:
private class change_date implements ActionListener {
    public void actionPerformed(ActionEvent ae) {
        JComboBox b = (JComboBox) ae.getSource();
        calendar.set(Calendar.DAY_OF_MONTH, b.getSelectedIndex());
    }
}

下拉框索引从0开始计数,你填充的选项是1到当月最大天数的整数,索引0对应1号、索引1对应2号,这里直接把索引值作为日期传给Calendar.DAY_OF_MONTH,本身就比正确日期小1;如果索引值为0(对应1号),Calendar会自动把日期计算为上个月的最后一天,直接出现跨月的异常跳变。

执行链路还原

点击"Get Current Date"按钮时的执行顺序完全可以解释两次打印结果不一致的现象:

  1. 执行calendar.setTime(new Date())将日历对象重置为当前时间,第一次打印出正确的当前日期
  2. 读取当前日期的“日”字段值d,调用day_list.setSelectedIndex(d-1)同步下拉框选中状态
  3. 该调用立刻触发change_date监听器,执行错误的calendar.set逻辑修改了日历对象存储的时间
  4. 执行第二次打印,此时拿到的已经是被监听器改坏的日期值
修复方法
  1. 修正监听器的取值逻辑,不要用索引计算日期,直接取下拉框中存储的实际日期值:
private class change_date implements ActionListener {
    public void actionPerformed(ActionEvent ae) {
        JComboBox<Integer> b = (JComboBox<Integer>) ae.getSource();
        calendar.set(Calendar.DAY_OF_MONTH, b.getSelectedItem());
    }
}
  1. 代码主动修改下拉框选中状态时,如果不需要触发联动逻辑,可以临时移除监听器,修改完成后再重新绑定,避免非用户操作产生的额外修改。更规范的实现是把监听器实例存为类的成员变量,不需要每次动态获取或新建:
// 把监听器定义为成员变量
private final ActionListener dateChangeListener = new change_date();

// 绑定监听器时直接用成员变量
day_list.addActionListener(dateChangeListener);

private void set_calendar() {
    System.out.println(calendar.getTime());
    int d = calendar.get(Calendar.DAY_OF_MONTH);
    // 临时移除监听器,避免触发修改
    day_list.removeActionListener(dateChangeListener);
    day_list.setSelectedIndex(d-1);
    // 重新绑定监听器
    day_list.addActionListener(dateChangeListener);
    System.out.println(calendar.getTime());
}

内容的提问来源于stack exchange,提问作者user19356087

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 07:09:16