我正在开发支持Google两步验证的应用程序。此应用程序还支持一项功能,可以信任此设备30天。
我使用数据库来保存所有这些信息,例如IP地址和过期时间。现在,当我填写时间戳System.currentTimeMillis() + 30 * 24 * 60 * 60 * 1000
以将30天添加到当前时间时,它会将比当前时间早的时间戳插入到数据库中。
例如:当前时间= 1483223733000 (2016-31-12 11:36 PM UTC+1)
。
现在,当我添加30天(即2592000000
毫秒时,它会出现类似于1481520984841 (2016-12-12 6:36 AM UTC+1)
的日期,而不是提前30天,而是大约19天后。
答案 0 :(得分:3)
这个问题与32位整数溢出有关。由于整数的最大值为2147483647
,因此对于整数而言,30天(以毫秒为单位)对于整数而言会过大,并且会产生类似-1702967296
的整数(大约是-19天,以毫秒为单位)。
要解决此问题,我使用的是long
而不是int
。所以现在我做:
System.currentTimeMillis() + 30L * 24 * 60 * 60 * 1000;
答案 1 :(得分:1)
您已经回答了为什么计算错误的问题,但如果您使用Java 8,我想建议您使用日期的更惯用的方式。
如果您只需要添加30个24小时长的日子(即24 * 30小时),请使用:
Instant.now().plus(Duration.ofDays(30)).toEpochMilli();
或
Instant.now().plus(30, ChronoUnit.DAYS).toEpochMilli();
如果您需要根据当前的JVM时区准确添加30天(某些天可能需要23或25小时,因为夏令时等),请使用:
ZonedDateTime.now(ZoneId.systemDefault()).plusDays(30).toInstant().toEpochMilli();
或(隐式使用JVM时区)
ZonedDateTime.now().plusDays(30).toInstant().toEpochMilli();
答案 2 :(得分:0)
您可以使用 Calendar cal = Calendar.getInstance();
System.out.println(cal.getTime());
System.out.println(cal.getTimeInMillis());
//cal.add(Calendar.DATE, 30);
cal.setTimeInMillis(System.currentTimeMillis() + 30L * 24 * 60 * 60 * 1000);
System.out.println(cal.getTime());
System.out.println(cal.getTimeInMillis());
执行此操作:
{{1}}