毫秒到天

时间:2011-10-19 23:45:59

标签: java math time milliseconds

我做了一些研究,但仍然找不到如何得到这些日子......这就是我得到的:

int seconds = (int) (milliseconds / 1000) % 60 ;
int minutes = (int) ((milliseconds / (1000*60)) % 60);
int hours   = (int) ((milliseconds / (1000*60*60)) % 24);
int days = ????? ;

请帮助,我吮吸数学,谢谢。

8 个答案:

答案 0 :(得分:117)

对于像这样的简单情况,应该使用TimeUnit。与明确地进行所有算术计算相比,TimeUnit的使用对于所表示的内容更加明确,并且更易于读取和写入。例如,要计算从毫秒开始的天数,以下语句将起作用:

    long days = TimeUnit.MILLISECONDS.toDays(milliseconds);

对于更高级的情况,需要在使用时间的上下文中表示更精细的持续时间,应使用全包和现代日期/时间API。对于JDK8 +,现在包含了java.time(这里是tutorialsjavadocs)。对于早期版本的Java joda-time是一个可靠的替代方案。

答案 1 :(得分:86)

如果您没有比天数更大的时间间隔:

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小时。

答案 2 :(得分:3)

java.time

您可以使用 java.time.Duration,它以 ISO-8601 standards 为模型,并作为 JSR-310 implementation 的一部分与 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 的更多信息。

答案 3 :(得分:2)

int days = (int) (milliseconds / 86 400 000 )

答案 4 :(得分:2)

在 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);

答案 5 :(得分:2)

你不能。对不起。或者更准确地说:如果您知道时区和开始时间(或结束时间),则可以。一天的长度可能是 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

那么两天有多少毫秒取决于您指的是哪两天。以及在哪个时区。

那该怎么办?

  1. 如果出于您的目的,您可以始终安全地将一天定义为 24 小时,例如,因为您的天数以 UTC 计算,或者您的用户对不准确感到满意,请使用 Duration 或 {{1 }}。从 Java 9 开始,TimeUnit 类还会告诉您除了整天之外还有多少小时、分钟和秒。请参阅 Arvind Kumar Avinash 的回答。对于 Duration 枚举,请参阅 whaley 和 Dev Parzival 的答案。无论如何,好消息是你数学很烂并不重要,因为数学已经为你准备好了。

  2. 如果您知道时区和起点,请使用 TimeUnitZonedDateTime。在这种情况下,数学也会为您处理。

    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 方法)从端点中减去您的毫秒数以获取起点。

在任何情况下都不要像问题和当前接受的答案那样自己进行数学计算。它容易出错并导致代码难以阅读。如果您的读者数学很烂,他或她可能会花费大量宝贵的开发人员时间来验证您是否正确完成了计算。将数学留给经过验证的库方法,您的读者会更容易相信您的代码是正确的。

答案 6 :(得分:1)

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

答案 7 :(得分:0)

如果您要解决更复杂的在代码中记录执行统计信息的任务:

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).");
}

P.S。如果需要,可以将Logger替换为简单的System.out.println()。