我做了一些研究,但仍然找不到如何度过这些日子......这是我得到的:
int seconds = (int) (milliseconds / 1000) % 60 ;
int minutes = (int) ((milliseconds / (1000*60)) % 60);
int hours = (int) ((milliseconds / (1000*60*60)) % 24);
int days = ????? ;
请帮忙,我数学很烂,谢谢。
我做了一些研究,但仍然找不到如何度过这些日子......这是我得到的:
int seconds = (int) (milliseconds / 1000) % 60 ;
int minutes = (int) ((milliseconds / (1000*60)) % 60);
int hours = (int) ((milliseconds / (1000*60*60)) % 24);
int days = ????? ;
请帮忙,我数学很烂,谢谢。
对于像这样的简单情况,应该使用TimeUnit 。与显式执行所有算术计算相比,TimeUnit 的使用对所表示的内容更加明确,并且也更容易读写。例如,要从毫秒计算天数,可以使用以下语句:
long days = TimeUnit.MILLISECONDS.toDays(milliseconds);
对于更高级的情况,需要在处理时间的上下文中表示更细粒度的持续时间,应使用包罗万象的现代日期/时间 API。对于 JDK8+,现在包含 java.time(这里是教程和javadocs)。对于 Java 的早期版本,joda-time是一个可靠的选择。
如果您没有另一个大于天的时间间隔:
int days = (int) (milliseconds / (1000*60*60*24));
如果你也有几周:
int days = (int) ((milliseconds / (1000*60*60*24)) % 7);
int weeks = (int) (milliseconds / (1000*60*60*24*7));
如果可能,最好避免使用月份和年份,因为它们没有明确定义的固定长度。严格来说,天也没有:夏令时意味着天的长度可以不是 24 小时。
在 java中使用TIMEUnit
为了导入使用,java.util.concurrent.TimeUnit
long millisec=System.currentTimeMillis();
long seconds=TimeUnit.MILLISECONDS.toSeconds(millisec);
long minutes=TimeUnit.MILLISECONDS.toMinutes(millisec);
long hours=TimeUnit.MILLISECONDS.toMinutes(millisec);
long days=TimeUnit.MILLISECONDS.toDays(millisec);
您可以使用java.time.Duration
它以ISO-8601 标准为模型,并作为JSR-310 实现的一部分与Java-8一起引入。Java-9引入了一些更方便的方法。
演示:
import java.time.Duration;
public class Main {
public static void main(String[] args) {
// Duration between the two instants
Duration duration = Duration.ofMillis(1234567890L);
// Print Duration#toString
System.out.println(duration);
// Custom format
// ####################################Java-8####################################
String formattedElapsedTime = String.format(
"%d Day %02d Hour %02d Minute %02d Second %d Millisecond (%d Nanosecond)", duration.toDays(),
duration.toHours() % 24, duration.toMinutes() % 60, duration.toSeconds() % 60,
duration.toMillis() % 1000, duration.toNanos() % 1000000000L);
System.out.println(formattedElapsedTime);
// ##############################################################################
// ####################################Java-9####################################
formattedElapsedTime = String.format("%d Day %02d Hour %02d Minute %02d Second %d Millisecond (%d Nanosecond)",
duration.toDaysPart(), duration.toHoursPart(), duration.toMinutesPart(), duration.toSecondsPart(),
duration.toMillisPart(), duration.toNanosPart());
System.out.println(formattedElapsedTime);
// ##############################################################################
}
}
示例运行:
PT342H56M7.89S
14 Day 06 Hour 56 Minute 07 Second 890 Millisecond (890000000 Nanosecond)
14 Day 06 Hour 56 Minute 07 Second 890 Millisecond (890000000 Nanosecond)
从Trail: Date Time了解有关现代日期时间 API 的更多信息。
int days = (int) (milliseconds / 86 400 000 )
public static final long SECOND_IN_MILLIS = 1000;
public static final long MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60;
public static final long HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60;
public static final long DAY_IN_MILLIS = HOUR_IN_MILLIS * 24;
public static final long WEEK_IN_MILLIS = DAY_IN_MILLIS * 7;
你可以投int但我建议使用long。
你不能。对不起。或者更准确地说:如果您知道时区和开始时间(或结束时间),则可以。一天可能有 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
and 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
上面代码中使用的方法)从端点中减去您的毫秒数以获得起点。
在任何情况下,都不要像在问题和当前接受的答案中那样自己做数学。它容易出错,并导致代码难以阅读。如果你的读者数学很烂,他或她可以花费大量宝贵的开发人员时间来验证你是否正确地完成了它。将数学留给经过验证的库方法,您的读者会更容易相信您的代码是正确的。
如果您解决了在代码中记录执行统计信息的更复杂任务:
public void logExecutionMillis(LocalDateTime start, String callerMethodName) {
LocalDateTime end = getNow();
long difference = Duration.between(start, end).toMillis();
Logger logger = LoggerFactory.getLogger(ProfilerInterceptor.class);
long millisInDay = 1000 * 60 * 60 * 24;
long millisInHour = 1000 * 60 * 60;
long millisInMinute = 1000 * 60;
long millisInSecond = 1000;
long days = difference / millisInDay;
long daysDivisionResidueMillis = difference - days * millisInDay;
long hours = daysDivisionResidueMillis / millisInHour;
long hoursDivisionResidueMillis = daysDivisionResidueMillis - hours * millisInHour;
long minutes = hoursDivisionResidueMillis / millisInMinute;
long minutesDivisionResidueMillis = hoursDivisionResidueMillis - minutes * millisInMinute;
long seconds = minutesDivisionResidueMillis / millisInSecond;
long secondsDivisionResidueMillis = minutesDivisionResidueMillis - seconds * millisInSecond;
logger.info(
"\n************************************************************************\n"
+ callerMethodName
+ "() - "
+ difference
+ " millis ("
+ days
+ " d. "
+ hours
+ " h. "
+ minutes
+ " min. "
+ seconds
+ " sec."
+ secondsDivisionResidueMillis
+ " millis).");
}
如果您愿意,可以用简单的 System.out.println() 替换 PS Logger。