关于Java中Calendar类getTimeMillis方法每次返回结果不一样的问题

问题发生的原因

在测试样例中测试Calendar类时,发现每次使用Calendar类的getTimeMillis方法返回结果都不一样

public void testIntervals() {
		DutyIntervalSet intervalSet = emptyInstance();initLabels();

		Calendar day1 = Calendar.getInstance();
		day1.set(2021, 6, 25);

		Calendar day2 = Calendar.getInstance();
		day2.set(2021, 6, 26);
		
		assertEquals(null, intervalSet.intervals(label1));
		intervalSet.insert(day1.getTimeInMillis(), day2.getTimeInMillis(), label1);
		assertEquals("{ [1=[1627142400000, 1627228800000]] }", intervalSet.intervals(label1).toString());
	}

Calendar类是一个抽象类,在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说是透明的,我们需要使用getInstance方法创建对象。

我们知道Calendar.getTimeMillis返回的是返回从格林威治标准时间 1970 年 1 月 1 日的 00:00:00:000到Calendar对象表示的时间之间的long类型毫秒数。

当我们对Calendar对象进行时间设置时,需要调用set方法:

void set(int field, int value) 
用给定的值设置时间字段。

void set(int year, int month, int date) 
设置年、月、日的值。

void set(int year, int month, int date, int hour, int minute) 
设置年、月、日、小时、分钟的值。

void set(int year, int month, int date, int hour, int minute, int second) 
设置年、月、日、小时、分钟、秒的值。

而在我使用set使用“年-月-日”格式对Calendar对象进行初始化时,调用方法void set(int year, int month, int date) 对对象的年(Calendar.YEAR)、月(Calendar.MONTH)、日(Calendar.DATE)位进行赋值,但对于我们没有具体赋值的其他位(如小时(Calendar.HOUR/Calendar.HOUR_OF_DAY)、分钟(Calendar.MINUTE)、秒(Calendar.SECOND)等),set没有具体的数据,于是使用随机数进行赋值。

也就是说我们调用void set(int year, int month, int date) 并不是调用

void set(int year, int month, int date, 0, 0, 0) ,也就是说我们有时、分、秒、毫秒四位数值没有统一设置,这与我们通常的想法不同。

Date类也会出现同样的问题,这对一些需要精确数值的情况不友好。

解决办法

1.Calendard对象在调用set前使用clear方法

Calendar.clear方法将所有的日历字段值和Calendar的时间值为undefined,默认值即格林威治标准时间 1970 年 1 月 1 日的 00:00:00:000的相关数据。Calendar实现类可能会使用默认字段值的日期和时间计算。

void clear()

​​​​​​​将所有的日历字段值和Calendar的时间值为undefined

则我们情况可以改为

public void testIntervals() {
		DutyIntervalSet intervalSet = emptyInstance();initLabels();

		Calendar day1 = Calendar.getInstance();
        day1.clear();
		day1.set(2021, 6, 25);

		Calendar day2 = Calendar.getInstance();
        day2.clear();
		day2.set(2021, 6, 26);

		assertEquals(null, intervalSet.intervals(label1));
		intervalSet.insert(day1.getTimeInMillis(), day2.getTimeInMillis(), label1);
		assertEquals("{ [1=[1627142400000, 1627228800000]] }", intervalSet.intervals(label1).toString());
	}

2.使用Calendar.set方法强制将某个位改为0

这种情况更加灵活,我们可以根据不同情况将不同位置零。

void set(int field, int value) 
用给定的值设置时间字段

其中field为Calendar类中设置的各个常量

常量描述
Calendar.YEAR年份
Calendar.MONTH月份
Calendar.DATE日期
Calendar.DAY_OF_MONTH日期,和上面的字段意义完全相同
Calendar.HOUR12小时制的小时
Calendar.HOUR_OF_DAY24小时制的小时
Calendar.MINUTE分钟
Calendar.SECOND
Calendar.DAY_OF_WEEK星期几

则我的情况可以改为

public void testIntervals() {
		DutyIntervalSet intervalSet = emptyInstance();initLabels();

		Calendar day1 = Calendar.getInstance();
		day1.set(2021, 6, 25);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);

		Calendar day2 = Calendar.getInstance();
		day2.set(2021, 6, 26);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
		
		assertEquals(null, intervalSet.intervals(label1));
		intervalSet.insert(day1.getTimeInMillis(), day2.getTimeInMillis(), label1);
		assertEquals("{ [1=[1627142400000, 1627228800000]] }", intervalSet.intervals(label1).toString());
	}
        

Date情况与Calendar类似,而正可以通过getTime的long值随便转换。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值