你不能。对不起。或者更准确地说:如果您知道时区和开始时间(或结束时间),则可以。一天可能有 23、24 或 25 小时或其他一些长度。因此,没有任何可靠的公式可以将毫秒转换为天。因此,虽然您可以安全地依赖一秒 1000 毫秒、一分钟 60 秒(以下预留)和一小时 60 分钟,但转换为天需要更多上下文才能确定和准确。
保留:在现实生活中,由于闰秒,一分钟有时是 61 秒。不是在 Java 中。 Java 总是将一分钟计为 60 秒,因为普通的计算机时钟不知道闰秒。常见的操作系统和 Java 本身不仅知道夏令时 (DST),而且还知道许多其他导致一天短于或长于 24 小时的时间线异常。
演示。我写这篇文章的时间是 2021 年 3 月 29 日,也就是我的时区欧洲/哥本哈根和欧盟其他地区切换到夏令时的第二天。
ZoneId myTimeZone = ZoneId.of("Europe/Copenhagen");
ZonedDateTime now = ZonedDateTime.now(myTimeZone);
ZonedDateTime twoDaysAgo = now.minusDays(2);
ZonedDateTime inTwoDays = now.plusDays(2);
System.out.println(ChronoUnit.MILLIS.between(twoDaysAgo, now));
System.out.println(ChronoUnit.MILLIS.between(now, inTwoDays));
输出:
169200000
172800000
所以两天是多少毫秒取决于你指的是哪两天。以及在哪个时区。
那该怎么办?
-
如果出于您的目的,您可以始终安全地将一天定义为 24 小时,例如因为您的天数以 UTC 计算,或者您的用户可以接受这种不准确,请使用 Duration 或 TimeUnit。从 Java 9 开始,Duration 类还会告诉您除了一整天之外还有多少小时、分钟和秒。请参阅 Arvind Kumar Avinash 的答案。对于TimeUnit 枚举,请参阅whaley 和Dev Parzival 的答案。不管怎样,好消息是你数学很烂也没关系,因为数学会帮你搞定。
-
如果您知道时区和起点,请使用ZonedDateTime 和ChronoUnit.DAYS。在这种情况下,数学也会为您处理。
ZonedDateTime start = LocalDate.of(2021, Month.MARCH, 28).atStartOfDay(myTimeZone);
long millisToConvert = 170_000_000;
ZonedDateTime end = start.plus(millisToConvert, ChronoUnit.MILLIS);
long days = ChronoUnit.DAYS.between(start, end);
System.out.format("%d days%n", days);
2 days
如果您还需要小时、分钟和秒:
Duration remainingTime = Duration.between(start.plusDays(days), end);
System.out.format(" - and an additional %s hours %d minutes %d seconds%n",
remainingTime.toHours(),
remainingTime.toMinutesPart(),
remainingTime.toSecondsPart());
- and an additional 0 hours 13 minutes 20 seconds
如果您有一个端点,请使用minus 方法(而不是上面代码中使用的plus 方法)从端点减去毫秒以获得起点。
在任何情况下都不要像在问题和当前接受的答案中那样自己进行数学运算。它容易出错,并导致代码难以阅读。如果您的读者数学很烂,他或她可能会花费大量宝贵的开发人员时间来尝试验证您是否正确完成了它。将数学留给经过验证的库方法,您的读者会更容易相信您的代码是正确的。