Calendar对象计算时间差误区
前几天一个朋友遇到一个问题,大概描述如下:
使用Calendar类来计算两个日期的差值(计算天数),但是计算结果总是比实际要多一个月。代码如下:
public static void main(String[] args) { Calendar now = new GregorianCalendar(); //当前时间20151011 Calendar year = new GregorianCalendar(2015,10,12); //设置一个时间 //获取毫秒数差值 long times = year.getTimeInMillis() - now.getTimeInMillis(); //打印天数,打印结果为31天,实际相差天数为1天 System.out.println(times/(1000 * 60 * 60 * 24)); } |
为了解决找出现这种情况的原因,首先查看API中关于GregorianCalendar类的构造函数的详细描述。上面实验使用public GregorianCalendar(int year, int month, int dayOfMonth) 构造函数,其具体描述如下:
year - 用来在日历中设置 YEAR 日历字段的值。
month - 用来在日历中设置 MONTH 日历字段的值。Month 值是基于 0 的,例如,0 表示 1 月。
dayOfMonth - 用来在日历中设置 DAY_OF_MONTH 日历字段的值。
从对month参数的描述找到了原因,month参数的值为10时,设置的月份为11月,所以打印结构为31天,而不是1天。为了解决这个问题,测试时在获取毫秒数前一行添加一个行代码(year.set(Calendar.MONTH, 10);),测试结果和之前一样,问题没有解决。
我们知道DateFormat可以把字符串格式化成日期。在java API中对DateFormat的子类SimpleDateFormat的描述有这样一段:
在分析缩写年份模式("y" 或 "yy")时,SimpleDateFormat 必须相对于某个世纪来解释缩写的年份。这通过将日期调整为 SimpleDateFormat 实例创建之前的 80 年和之后 20 年范围内来完成。例如,在 "MM/dd/yy" 模式下,如果 SimpleDateFormat 实例是在 1997 年 1 月 1 日创建的,则字符串 "01/11/12" 将被解释为 2012 年 1 月 11 日,而字符串 "05/04/64" 将被解释为 1964 年 5 月 4 日。(引用API描述结束)
我们可以发现,使用SimpleDateFormat格式化字符串生成日期的方式,可以把"2015-10-12"转换成2015年10月12日,这个结果恰好是我们想要的。现在我们再次修改代码,把Calendar year = new GregorianCalendar(2015,9,12); 用下面这段代码代替。
Calendar year = Calendar.getInstance(); String str = "2015-10-12"; //时间字符串 //使用DateFormat来实现字符串转成日期 DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); Date date = null; try { date = df.parse(str); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } year.setTime(date); |
运行代码,打印结果变成了0,这个结果和预期的还是不一致。我们使用debug模式运行程序,查看date对象时发现它的值是Mon Oct 12 00:00:00 CST 2015,小时、分钟和秒数都是0。我们在想想现在的系统时间,的小时、分钟和秒,他们不为零,所以两个时间毫秒数的差值小于一天的毫秒数,所以结果为0。这里需要做一个简单的处理,最终代码如下:
public static void main(String[] args) { Calendar now = new GregorianCalendar(); //当前时间 Calendar year = Calendar.getInstance(); String str = "2015-10-12"; //时间字符串 //使用DateFormat来实现字符串转成日期 DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); Date date = null; try { date = df.parse(str); } catch (ParseException e) { e.printStackTrace(); } year.setTime(date); //获取毫秒数差值 long times = year.getTimeInMillis() - now.getTimeInMillis(); //long times = date.getTime() - now.getTimeInMillis();//可以直接使用date对象获取毫秒数 //打印天数 long days = times % (1000 * 60 * 60 * 24) == 0 ? times / (1000 * 60 * 60 * 24) : times / (1000 * 60 * 60 * 24) + 1; System.out.println(days); } |
蜗牛学院,只为成就更好的你!
你!敢不敢!用你三个月的时间,换你不一样的未来!
赶快关注蜗牛学院官方微信,了解更多信息吧!