milliseconds to days

JavaMathTimeMilliseconds

Java Problem Overview


i did some research, but still can't find how to get the days... Here is what I got:

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

Please help, I suck at math, thank's.

Java Solutions


Solution 1 - Java

For simple cases like this, TimeUnit should be used. TimeUnit usage is a bit more explicit about what is being represented and is also much easier to read and write when compared to doing all of the arithmetic calculations explicitly. For example, to calculate the number days from milliseconds, the following statement would work:

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

For cases more advanced, where more finely grained durations need to be represented in the context of working with time, an all encompassing and modern date/time API should be used. For JDK8+, java.time is now included (here are the tutorials and javadocs). For earlier versions of Java joda-time is a solid alternative.

Solution 2 - Java

If you don't have another time interval bigger than days:

int days = (int) (milliseconds / (1000*60*60*24));

If you have weeks too:

int days = (int) ((milliseconds / (1000*60*60*24)) % 7);
int weeks = (int) (milliseconds / (1000*60*60*24*7));

It's probably best to avoid using months and years if possible, as they don't have a well-defined fixed length. Strictly speaking neither do days: daylight saving means that days can have a length that is not 24 hours.

Solution 3 - Java

Go for TImeUnit in java

In order to import use, 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);

Solution 4 - Java

java.time

You can use java.time.Duration which is modelled on ISO-8601 standards and was introduced with Java-8 as part of JSR-310 implementation. With Java-9 some more convenient methods were introduced.

Demo:

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);
		// ##############################################################################
	}
}

A sample run:

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)

Learn more about the modern date-time API from Trail: Date Time.

Solution 5 - Java

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

Solution 6 - Java

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;

You could cast int but I would recommend using long.

Solution 7 - Java

You can’t. Sorry. Or more precisely: you can if you know a time zone and a start time (or end time). A day may have a length of 23, 24 or 25 hours or some other length. So there isn’t any sure-fire formula for converting from milliseconds to days. So while you can safely rely on 1000 milliseconds in a second, 60 seconds in a minute (reservation below) and 60 minutes in an hour, the conversion to days needs more context in order to be sure and accurate.

Reservation: In real life a minute is occasionally 61 seconds because of a leap second. Not in Java. Java always counts a minute as 60 seconds because common computer clocks don’t know leap seconds. Common operating systems and Java itself do know not only summer time (DST) but also many other timeline anomalies that cause a day to be shorter or longer than 24 hours.

To demonstrate. I am writing this on March 29, 2021, the day after my time zone, Europe/Copenhagen, and the rest of the EU switched to summer time.

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

Output:

> 169200000 > 172800000

So how many milliseconds are in two days depends on which two days you mean. And in which time zone.

So what to do?

  1. If for your purpose you can safely define a day as 24 hours always, for example because your days are counted in UTC or your users are fine with the inaccuracy, use either Duration or TimeUnit. Since Java 9 the Duration class will additionally tell you how many hours, minutes and seconds there are in addition to the whole days. See the answer by Arvind Kumar Avinash. For the TimeUnit enum see the answers by whaley and Dev Parzival. In any case the good news is that it doesn’t matter if you suck at math because the math is taken care of for you.

  2. If you know a time zone and a starting point, use ZonedDateTime and ChronoUnit.DAYS. In this case too the math is taken care of for you.

    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

If you additionally want the hours, minutes and seconds:

	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

If instead you had got an endpoint, subtract your milliseconds from the endpoint using the minus method (instead of the plus method used in the above code) to get the start point.

Under no circumstances do the math yourself as in the question and in the currently accepted answer. It’s error-prone and results in code that is hard to read. And if your reader sucks at math, he or she can spend much precious developer time trying to verify that you have done it correctly. Leave the math to proven library methods, and it will be much easier for your reader to trust that your code is correct.

Solution 8 - Java

In case you solve a more complex task of logging execution statistics in your code:

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 can be replaced with simple System.out.println() if you like.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionReacenView Question on Stackoverflow
Solution 1 - JavawhaleyView Answer on Stackoverflow
Solution 2 - JavaMark ByersView Answer on Stackoverflow
Solution 3 - JavaUdesh RanjanView Answer on Stackoverflow
Solution 4 - JavaArvind Kumar AvinashView Answer on Stackoverflow
Solution 5 - JavaKurtis NusbaumView Answer on Stackoverflow
Solution 6 - JavaCodeversedView Answer on Stackoverflow
Solution 7 - JavaOle V.V.View Answer on Stackoverflow
Solution 8 - JavaZonView Answer on Stackoverflow