为什么Calendar.after总是重新调整为真?

时间:2019-09-30 07:40:27

标签: java date calendar java.util.calendar

您好,有人可以从Calendar .after方法中解释这种异常行为的原因

Calendar cal = Calendar.getInstance();
Calendar cal1 = Calendar.getInstance();

cal.set(Calendar.HOUR, 14);
cal1.set(Calendar.HOUR, 13);

System.out.println(cal.after(cal1)+" Cal "+cal.getTime()+" cal1 "+cal1.getTime());      

cal.set(Calendar.DATE, Calendar.getInstance().get(Calendar.DATE));
System.out.println(cal.after(cal1)+" Cal "+cal.getTime()+" cal1 "+cal1.getTime());

输出:

true Cal Tue Oct 01 02:55:16 IST 2019 cal1 Tue Oct 01 01:55:16 IST 2019
true Cal Wed Oct 30 02:55:16 IST 2019 cal1 Tue Oct 01 01:55:16 IST 2019

但是即使我将cal1的日期设置为当前日期,我也无法理解为什么cal在cal1之后。

因此,如果cal是今天,我将时间指定为下一个日期的14小时,那么我将日期设置为cal中的当前日期,而对于cal1,我没有设置该日期。

那么为什么我的cal1明显比cal大1天,cal.after(cal1)仍然在第二个syso中显示为真?

4 个答案:

答案 0 :(得分:1)

是否有解决此类问题的建议?使用java.time

我同意您的观点,您的代码中有些意外。您可能打算这样做:

    ZoneId zone = ZoneId.of("Asia/Kolkata");
    ZonedDateTime zdt = ZonedDateTime.now(zone);
    ZonedDateTime zdt1 = ZonedDateTime.now(zone);

    zdt = zdt.withHour(14);
    zdt1 = zdt1.withHour(13);

    System.out.println(zdt.isAfter(zdt1) + " zdt " + zdt + " zdt1 " + zdt1);

    zdt = zdt.withDayOfMonth(ZonedDateTime.now(zone).getDayOfMonth());
    System.out.println(zdt.isAfter(zdt1) + " zdt " + zdt + " zdt1 " + zdt1);

我刚才运行代码时的输出:

true zdt 2019-09-30T14:44:13.630029+05:30[Asia/Kolkata] zdt1 2019-09-30T13:44:13.630362+05:30[Asia/Kolkata]
true zdt 2019-09-30T14:44:13.630029+05:30[Asia/Kolkata] zdt1 2019-09-30T13:44:13.630362+05:30[Asia/Kolkata]

我两次都得到true,就像您从代码中得到的一样,这并不奇怪。就像其他人所说的,02:55h在01:55h之后,Oct 30在Oct 01之后。另外,根据我的结果,14:44在13:44之后。在这两行中,将这两次比较。

我正在使用现代Java日期和时间API java.time。

您的代码出了什么问题?

Calendar类的设计欠佳,并且通常表现出与我们立即期望的不同。

  1. 为什么将小时设置为14,为什么会收到IST 2019年10月1日星期二02:55:16?日期已更改为下个月,并且一天中的小时是2,而不是14。
  2. 为什么将日期设置为今天的9月30日,却又是10月30日?

对于1。,Calendar.HOUR表示AM或PM中从0到11的小时。因此将其设置为14,我们应该预期会有异常。具有标准设置的Calendar无关紧要。由于时间已经在PM中,因此可以推断出来,因此14 PM在第二天变成凌晨2点。由于今天是九月的最后一天,所以您将在10月1日。

对于2,Calendar.DATE不是完整日期,而是月份中的某天。由于本月的当前日是30,而我们已经有了October1,所以我们将10月30日定为。

长话短说:避免使用Calendar类。使用ZonedDateTime和/或其他类(来自现代Java日期和时间API)java.time。它们可以更好地工作,并且给您的惊喜比您经历的要少得多。

链接

Oracle tutorial: Date Time解释了如何使用java.time。

答案 1 :(得分:0)

  
    

Java文档-Calendar.after()

  
override func viewDidLoad() {
   super.viewDidLoad()

   let button = UIButton()
   button.setTitle("btn 1", for: .normal)
   button.backgroundColor = UIColor.red
   button.translatesAutoresizingMaskIntoConstraints = false

   let button2 = UIButton()
   button2.setTitle("btn 2", for: .normal)
   button2.backgroundColor = UIColor.gray
   button2.translatesAutoresizingMaskIntoConstraints = false

   let button3 = UIButton()
   button3.setTitle("btn 3", for: .normal)
   button3.backgroundColor = UIColor.brown
   button3.translatesAutoresizingMaskIntoConstraints = false

   buttonStackView.alignment = .fill
   buttonStackView.distribution = .fillEqually
   buttonStackView.spacing = 8.0

   buttonStackView.addArrangedSubview(button)
   buttonStackView.addArrangedSubview(button2)
   buttonStackView.addArrangedSubview(button3)  

}
public boolean after(Object when) {
    return when instanceof Calendar && compareTo((Calendar)when) > 0;
}

答案 2 :(得分:0)

         System.out.println(cal.after(cal1)+" Cal "+cal.getTime()+" cal1 "+cal1.getTime()); 
        //true Cal Tue Oct 01 02:25:19 MMT 2019 cal1 Tue Oct 01 01:25:19 MMT 2019  
    cal.set(Calendar.DATE, Calendar.getInstance().get(Calendar.DATE));
    System.out.println(cal1.after(cal)+" Cal "+cal.getTime()+" cal1 "+cal1.getTime());
   //false Cal Wed Oct 30 02:25:19 MMT 2019 cal1 Tue Oct 01 01:25:19 MMT 2019

答案 3 :(得分:0)

使用

cal.setTime((Calendar.getInstance()).getTime());

代替

cal.set(Calendar.DATE, Calendar.getInstance().get(Calendar.DATE));

获得理想的结果。