情境再现:需要获取并显示一个用户的年龄,eg:26岁。后台返回的数据含有User实体类,该类中含有long型字段的birthday(毫秒数)。
我的思路:获取系统的当前时间(毫秒数),减去用户的生日(毫秒数),得到的是用户已经活了多长时间(毫秒数),然后除以每一年的毫秒数,即可得到用户的年龄,代码如下:
long haveLiveMs = System.currentTimeMillis() - data.getBirthday(); long haveLiveYear = haveLiveMs/(365*24*60*60*1000);
但是得到的结果却是不正确的,为587,明显错误。看了又看,想了又想:没错啊,这逻辑没有错误啊,但为什么就是结果不正确呢?
它山之石:同事让通过后台给的long型数据生成Date变量,然后通过SimpleDateFormat类转换出出生年份,当前年份减去转换出的年份即为用户年龄,代码如下:
Date date = new Date(data.getBirthday()); SimpleDateFormat sdf = new SimpleDateFormat("yyyy"); String s = sdf.format(date);
得到的结果是正确的。这就说明后台返回的数据是正确的,但是“我的思路”到底错在哪里了呢?
柳暗花明:当初,我误认为(365*24*60*60*1000)
的结果会是long型,但是Java对于整形数据而言,都默认为int类型的,(365*24*60*60*1000)
得到的值明显会大于Integer.Max_Value,存储的时候必然产生截断,导致参与除法的除数的数值发生变化,进而产生错误的结果。
因此,正确的做法是显示声明(365*24*60*60*1000)
的类型为long型,eg:
long haveLiveYear = haveLiveMs/(365*24*60*60*1000L);
这样就得到了正确的结果。
正确的正确:就同事的方法而言,我的思路明显没有考虑到闰年天数变化所带来的误差,因此应采取同事的方法,及时自己的思路是正确的。