Convert long to remaining time - java

I'm currently trying to convert a long to a remaining time. I have got a
long remaining = XXXX
The long are the milliseconds to a certain date. For example: 3,600,000 should result in int weeks = 0, days = 0, hours = 1, minutes = 0, seconds = 0
how can I convert this long so that I end up with 5 ints:
int weeks;
int days;
int hours;
int minutes;
int seconds;
Thank you in advance!
DirtyDev

First, I suggest defining the number of ms in a second, minute, hour, etc as constants
static final int SECOND = 1000; // no. of ms in a second
static final int MINUTE = SECOND * 60; // no. of ms in a minute
static final int HOUR = MINUTE * 60; // no. of ms in an hour
static final int DAY = HOUR * 24; // no. of ms in a day
static final int WEEK = DAY * 7; // no. of ms in a week
Then, you can use basic division (/) and modulus (%) operations to find what you need.
long remaining = XXXX;
int weeks = (int)( remaining / WEEK);
int days = (int)((remaining % WEEK) / DAY);
int hours = (int)((remaining % DAY) / HOUR);
int minutes = (int)((remaining % HOUR) / MINUTE);
int seconds = (int)((remaining % MINUTE) / SECOND);

Excuse me, I don’t want to criticize too much, still I gather from the other answers that it’s easy to either write code that is hard to read or code with typos that gives an incorrect result. DirtyDev, I am aware that you may not be allowed to use Duration, but for anyone else:
long remaining = 3_600_000;
Duration remainingTime = Duration.ofMillis(remaining);
long days = remainingTime.toDays();
remainingTime = remainingTime.minusDays(days);
long weeks = days / 7;
days %= 7; // or if you prefer, days = days % 7;
long hours = remainingTime.toHours();
remainingTime = remainingTime.minusHours(hours);
long minutes = remainingTime.toMinutes();
remainingTime = remainingTime.minusMinutes(minutes);
long seconds = remainingTime.getSeconds();
System.out.println("" + weeks + " weeks " + days + " days "
+ hours + " hours " + minutes + " minutes " + seconds + " seconds");
This prints:
0 weeks 0 days 1 hours 0 minutes 0 seconds
It’s not perfect, but I believe it’s both readable, correct and robust. Duration was meant for times from hours down to nanoseconds, so we still have to do the weeks “by hand”.
Happy New Year.

This should do what you want.
long inputTimeInMilliseconds = 93800000;
long milliseconds = inputTimeInMilliseconds % 1000;
long seconds = (inputTimeInMilliseconds / 1000) % 60 ;
long minutes = ((inputTimeInMilliseconds / (1000*60)) % 60);
long hours = ((inputTimeInMilliseconds / (1000*60*60)) % 24);
long days = ((inputTimeInMilliseconds / (1000*60*60*24)) % 7);
long weeks = (inputTimeInMilliseconds / (1000*60*60*24*7));
String remainingTime = "time:"+weeks+":"+days+":"+ hours+":"+minutes+":"+seconds+":"+milliseconds;
System.out.println(remainingTime);

Related

Java - Weekly recurring calendar countdown

I'm trying to make a countdown timer that will reset weekly (Mondays at 10am eastern). I've found something similar to what I'm looking for, but it doesn't reset itself; it goes into the negative. Can someone please help me get this working?
public static int SECONDS_IN_A_DAY = 24 * 60 * 60;
public String main(String[] args) {
Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH);
Calendar reset = Calendar.getInstance();
reset.setTime(new Date(0));
reset.set(Calendar.DAY_OF_WEEK, 1); //2
reset.set(Calendar.MONTH, month);
reset.set(Calendar.YEAR, year);
reset.set(Calendar.HOUR_OF_DAY, 0); //10
reset.set(Calendar.MINUTE, 33);
Calendar today = Calendar.getInstance();
long diff = reset.getTimeInMillis() - today.getTimeInMillis();
long diffSec = diff / 1000;
long days = diffSec / SECONDS_IN_A_DAY;
long secondsDay = diffSec % SECONDS_IN_A_DAY;
long seconds = secondsDay % 60;
long minutes = (secondsDay / 60) % 60;
long hours = (secondsDay / 3600);
if (diff < 0) {
reset.setTime(new Date(0));
reset.set(Calendar.DAY_OF_WEEK, 1); //2
reset.set(Calendar.MONTH, month);
reset.set(Calendar.YEAR, year);
reset.set(Calendar.HOUR_OF_DAY, 0); //10
reset.set(Calendar.MINUTE, 33);
}
return "Reset in: " + days + " days, " + hours + " hours, " + minutes + " minutes, and " + seconds + " seconds.";
}
public void onMessageReceived(MessageReceivedEvent e) {
if(e.getMessage().getRawContent().equalsIgnoreCase(";reset")) {
e.getChannel().sendMessage(main(null)).queue();
}
}
I cant figure out how to make this reset once it reaches reset time. Any help very much appreciated. I haven't coded in 5+ years.
Below is screenshot of the output if the time has passed.
https://puu.sh/w3odJ/009663b380.png
Thanks!
UPDATE: I'm finding the best method for this is to use reset.add to add 7 days to the reset calendar. Can't get the proper conditions to be met to achieve this yet though. I've tried reset.compareTo(today) as well as some other combinations which aren't working, but it's progress.

Error in my calculations for a y2k38 count down

Hey I need to make a program that counts down the days/ hours/ min/ sec until y2k38 i got the code but I have a logic error and am getting the wrong number for hours mins and secs. Heres my code:
public class Assignment1 {
public static void main(String[] args) {
long now = System.currentTimeMillis();
// The problem will occur at 2^31 seconds
long y2k38 = (long) Math.pow(2, 31)*1000;
// Assigning the time intervals values based on eachother
long diffsec = (y2k38-now)/1000;
long diffmin = diffsec/60;
long diffhours = diffmin/60;
long diffdays = diffhours/24;
// issuing a print statement to output the days,hours..etc until y2k38
System.out.printf(
"%d days\n"+
"%d hours\n"+
"%d minutes\n"+
"%d seconds\n",
(diffdays),(diffmin%60), (diffsec%3600),(diffsec%60));
}
}
Your calculations are all very strange, you can modify and print them as follows:
long diffsecs = (y2k38 - now) / 1000;
long diffmins = (diffsecs / 60) % 60;
long diffhours = (diffsecs / 60 / 60) % 24;
long diffdays = diffsecs / 60 / 60 / 24;
diffsecs = diffsecs % 60;
System.out.printf("%d days, %d hours, %d minutes, d seconds\n",
diffdays, diffhours, diffmins, diffsecs);
This gives you something like:
8126 days, 22 hours, 42 minutes, 21 seconds
which roughly matches what you need.
You are converting the difference into total days/hours/mins/secs. Instead, you want to start with finding days, and use the reminder to find hours, and so on.
long diff = y2k38 - now;
long diffdays = diff/(24*60*60*1000);
diff = diff%(24*60*60*1000);
long diffhours = diff/(60*60*1000);
diff = diff%(60*60*1000);
long diffmin = diff/(60*1000);
diff = diff%(60*1000);
long diffsec = diff/1000;
Also it's faster to compute the y2k38 value by
long y2k38 = ((long)(Integer.MAX_VALUE) + 1)*1000;

JAVA convert minutes into default time [hh:mm:ss]

what is the easiest and fastest way to convert minutes (double) to default time hh:mm:ss
for example I used this code in python and it's working
time = timedelta(minutes=250.0)
print time
result:
4:10:00
is there a java library or a simple code can do it?
EDIT: To show the seconds as SS you can make an easy custom formatter variable to pass to the String.format() method
EDIT: Added logic to add one minute and recalculate seconds if the initial double value has the number value after the decimal separator greater than 59.
EDIT: Noticed loss of precision when doing math on the double (joy of working with doubles!) seconds, so every now and again it would not be the correct value. Changed code to properly calculate and round it. Also added logic to treat cases when minutes and hour overflow because of cascading from seconds.
Try this (no external libraries needed)
public static void main(String[] args) {
final double t = 1304.00d;
if (t > 1440.00d) //possible loss of precision again
return;
int hours = (int)t / 60;
int minutes = (int)t % 60;
BigDecimal secondsPrecision = new BigDecimal((t - Math.floor(t)) * 100).setScale(2, RoundingMode.HALF_UP);
int seconds = secondsPrecision.intValue();
boolean nextDay = false;
if (seconds > 59) {
minutes++; //increment minutes by one
seconds = seconds - 60; //recalculate seconds
}
if (minutes > 59) {
hours++;
minutes = minutes - 60;
}
//next day
if (hours > 23) {
hours = hours - 24;
nextDay = true;
}
//if seconds >=10 use the same format as before else pad one zero before the seconds
final String myFormat = seconds >= 10 ? "%d:%02d:%d" : "%d:%02d:0%d";
final String time = String.format(myFormat, hours, minutes, seconds);
System.out.print(time);
System.out.println(" " + (nextDay ? "The next day" : "Current day"));
}
Of course this can go on and on, expanding on this algorithm to generalize it. So far it will work until the next day but no further, so we could limit the initial double to that value.
if (t > 1440.00d)
return;
Using Joda you can do something like:
import org.joda.time.Period;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;
final Period a = Period.seconds(25635);
final PeriodFormatter hoursMinutes = new PeriodFormatterBuilder().appendHours().appendSuffix(" hour", " hours")
.appendSeparator(" and ").appendMinutes().appendSuffix(" minute", " minutes").appendSeparator(" and ")
.appendSeconds().appendSuffix(" second", " seconds").toFormatter();
System.out.println(hoursMinutes.print(a.normalizedStandard()));
//Accept minutes from user and return time in HH:MM:SS format
private String convertTime(long time)
{
String finalTime = "";
long hour = (time%(24*60)) / 60;
long minutes = (time%(24*60)) % 60;
long seconds = time / (24*3600);
finalTime = String.format("%02d:%02d:%02d",
TimeUnit.HOURS.toHours(hour) ,
TimeUnit.MINUTES.toMinutes(minutes),
TimeUnit.SECONDS.toSeconds(seconds));
return finalTime;
}

TimeUtil package in java [duplicate]

I want to record the time using System.currentTimeMillis() when a user begins something in my program. When he finishes, I will subtract the current System.currentTimeMillis() from the start variable, and I want to show them the time elapsed using a human readable format such as "XX hours, XX mins, XX seconds" or even "XX mins, XX seconds" because its not likely to take someone an hour.
What's the best way to do this?
Use the java.util.concurrent.TimeUnit class:
String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes(millis),
TimeUnit.MILLISECONDS.toSeconds(millis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
);
Note: TimeUnit is part of the Java 1.5 specification, but toMinutes was added as of Java 1.6.
To add a leading zero for values 0-9, just do:
String.format("%02d min, %02d sec",
TimeUnit.MILLISECONDS.toMinutes(millis),
TimeUnit.MILLISECONDS.toSeconds(millis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
);
If TimeUnit or toMinutes are unsupported (such as on Android before API version 9), use the following equations:
int seconds = (int) (milliseconds / 1000) % 60 ;
int minutes = (int) ((milliseconds / (1000*60)) % 60);
int hours = (int) ((milliseconds / (1000*60*60)) % 24);
//etc...
Based on #siddhadev's answer, I wrote a function which converts milliseconds to a formatted string:
/**
* Convert a millisecond duration to a string format
*
* #param millis A duration to convert to a string form
* #return A string of the form "X Days Y Hours Z Minutes A Seconds".
*/
public static String getDurationBreakdown(long millis) {
if(millis < 0) {
throw new IllegalArgumentException("Duration must be greater than zero!");
}
long days = TimeUnit.MILLISECONDS.toDays(millis);
millis -= TimeUnit.DAYS.toMillis(days);
long hours = TimeUnit.MILLISECONDS.toHours(millis);
millis -= TimeUnit.HOURS.toMillis(hours);
long minutes = TimeUnit.MILLISECONDS.toMinutes(millis);
millis -= TimeUnit.MINUTES.toMillis(minutes);
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);
StringBuilder sb = new StringBuilder(64);
sb.append(days);
sb.append(" Days ");
sb.append(hours);
sb.append(" Hours ");
sb.append(minutes);
sb.append(" Minutes ");
sb.append(seconds);
sb.append(" Seconds");
return(sb.toString());
}
long time = 1536259;
return (new SimpleDateFormat("mm:ss:SSS")).format(new Date(time));
Prints:
25:36:259
Using the java.time package in Java 8:
Instant start = Instant.now();
Thread.sleep(63553);
Instant end = Instant.now();
System.out.println(Duration.between(start, end));
Output is in ISO 8601 Duration format: PT1M3.553S (1 minute and 3.553 seconds).
Uhm... how many milliseconds are in a second? And in a minute? Division is not that hard.
int seconds = (int) ((milliseconds / 1000) % 60);
int minutes = (int) ((milliseconds / 1000) / 60);
Continue like that for hours, days, weeks, months, year, decades, whatever.
I would not pull in the extra dependency just for that (division is not that hard, after all), but if you are using Commons Lang anyway, there are the DurationFormatUtils.
Example Usage (adapted from here):
import org.apache.commons.lang3.time.DurationFormatUtils
public String getAge(long value) {
long currentTime = System.currentTimeMillis();
long age = currentTime - value;
String ageString = DurationFormatUtils.formatDuration(age, "d") + "d";
if ("0d".equals(ageString)) {
ageString = DurationFormatUtils.formatDuration(age, "H") + "h";
if ("0h".equals(ageString)) {
ageString = DurationFormatUtils.formatDuration(age, "m") + "m";
if ("0m".equals(ageString)) {
ageString = DurationFormatUtils.formatDuration(age, "s") + "s";
if ("0s".equals(ageString)) {
ageString = age + "ms";
}
}
}
}
return ageString;
}
Example:
long lastTime = System.currentTimeMillis() - 2000;
System.out.println("Elapsed time: " + getAge(lastTime));
//Output: 2s
Note: To get millis from two LocalDateTime objects you can use:
long age = ChronoUnit.MILLIS.between(initTime, LocalDateTime.now())
Either hand divisions, or use the SimpleDateFormat API.
long start = System.currentTimeMillis();
// do your work...
long elapsed = System.currentTimeMillis() - start;
DateFormat df = new SimpleDateFormat("HH 'hours', mm 'mins,' ss 'seconds'");
df.setTimeZone(TimeZone.getTimeZone("GMT+0"));
System.out.println(df.format(new Date(elapsed)));
Edit by Bombe: It has been shown in the comments that this approach only works for smaller durations (i.e. less than a day).
Just to add more info
if you want to format like: HH:mm:ss
0 <= HH <= infinite
0 <= mm < 60
0 <= ss < 60
use this:
int h = (int) ((startTimeInMillis / 1000) / 3600);
int m = (int) (((startTimeInMillis / 1000) / 60) % 60);
int s = (int) ((startTimeInMillis / 1000) % 60);
I just had this issue now and figured this out
Shortest solution:
Here's probably the shortest which also deals with time zones.
System.out.printf("%tT", millis-TimeZone.getDefault().getRawOffset());
Which outputs for example:
00:18:32
Explanation:
%tT is the time formatted for the 24-hour clock as %tH:%tM:%tS.
%tT also accepts longs as input, so no need to create a Date. printf() will simply print the time specified in milliseconds, but in the current time zone therefore we have to subtract the raw offset of the current time zone so that 0 milliseconds will be 0 hours and not the time offset value of the current time zone.
Note #1: If you need the result as a String, you can get it like this:
String t = String.format("%tT", millis-TimeZone.getDefault().getRawOffset());
Note #2: This only gives correct result if millis is less than a day because the day part is not included in the output.
I think the best way is:
String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toSeconds(length)/60,
TimeUnit.MILLISECONDS.toSeconds(length) % 60 );
Revisiting #brent-nash contribution, we could use modulus function instead of subtractions and use String.format method for the result string:
/**
* Convert a millisecond duration to a string format
*
* #param millis A duration to convert to a string form
* #return A string of the form "X Days Y Hours Z Minutes A Seconds B Milliseconds".
*/
public static String getDurationBreakdown(long millis) {
if (millis < 0) {
throw new IllegalArgumentException("Duration must be greater than zero!");
}
long days = TimeUnit.MILLISECONDS.toDays(millis);
long hours = TimeUnit.MILLISECONDS.toHours(millis) % 24;
long minutes = TimeUnit.MILLISECONDS.toMinutes(millis) % 60;
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis) % 60;
long milliseconds = millis % 1000;
return String.format("%d Days %d Hours %d Minutes %d Seconds %d Milliseconds",
days, hours, minutes, seconds, milliseconds);
}
Joda-Time
Using Joda-Time:
DateTime startTime = new DateTime();
// do something
DateTime endTime = new DateTime();
Duration duration = new Duration(startTime, endTime);
Period period = duration.toPeriod().normalizedStandard(PeriodType.time());
System.out.println(PeriodFormat.getDefault().print(period));
For those who looking for Kotlin code:
fun converter(millis: Long): String =
String.format(
"%02d : %02d : %02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(
TimeUnit.MILLISECONDS.toHours(millis)
),
TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(
TimeUnit.MILLISECONDS.toMinutes(millis)
)
)
Sample output: 09 : 10 : 26
My simple calculation:
String millisecToTime(int millisec) {
int sec = millisec/1000;
int second = sec % 60;
int minute = sec / 60;
if (minute >= 60) {
int hour = minute / 60;
minute %= 60;
return hour + ":" + (minute < 10 ? "0" + minute : minute) + ":" + (second < 10 ? "0" + second : second);
}
return minute + ":" + (second < 10 ? "0" + second : second);
}
Happy coding :)
Firstly, System.currentTimeMillis() and Instant.now() are not ideal for timing. They both report the wall-clock time, which the computer doesn't know precisely, and which can move erratically, including going backwards if for example the NTP daemon corrects the system time. If your timing happens on a single machine then you should instead use System.nanoTime().
Secondly, from Java 8 onwards java.time.Duration is the best way to represent a duration:
long start = System.nanoTime();
// do things...
long end = System.nanoTime();
Duration duration = Duration.ofNanos(end - start);
System.out.println(duration); // Prints "PT18M19.511627776S"
System.out.printf("%d Hours %d Minutes %d Seconds%n",
duration.toHours(), duration.toMinutes() % 60, duration.getSeconds() % 60);
// prints "0 Hours 18 Minutes 19 Seconds"
for Android below API 9
(String.format("%d hr %d min, %d sec", millis/(1000*60*60), (millis%(1000*60*60))/(1000*60), ((millis%(1000*60*60))%(1000*60))/1000))
For small times, less than an hour, I prefer:
long millis = ...
System.out.printf("%1$TM:%1$TS", millis);
// or
String str = String.format("%1$TM:%1$TS", millis);
for longer intervalls:
private static final long HOUR = TimeUnit.HOURS.toMillis(1);
...
if (millis < HOUR) {
System.out.printf("%1$TM:%1$TS%n", millis);
} else {
System.out.printf("%d:%2$TM:%2$TS%n", millis / HOUR, millis % HOUR);
}
Here is an answer based on Brent Nash answer, Hope that helps !
public static String getDurationBreakdown(long millis)
{
String[] units = {" Days ", " Hours ", " Minutes ", " Seconds "};
Long[] values = new Long[units.length];
if(millis < 0)
{
throw new IllegalArgumentException("Duration must be greater than zero!");
}
values[0] = TimeUnit.MILLISECONDS.toDays(millis);
millis -= TimeUnit.DAYS.toMillis(values[0]);
values[1] = TimeUnit.MILLISECONDS.toHours(millis);
millis -= TimeUnit.HOURS.toMillis(values[1]);
values[2] = TimeUnit.MILLISECONDS.toMinutes(millis);
millis -= TimeUnit.MINUTES.toMillis(values[2]);
values[3] = TimeUnit.MILLISECONDS.toSeconds(millis);
StringBuilder sb = new StringBuilder(64);
boolean startPrinting = false;
for(int i = 0; i < units.length; i++){
if( !startPrinting && values[i] != 0)
startPrinting = true;
if(startPrinting){
sb.append(values[i]);
sb.append(units[i]);
}
}
return(sb.toString());
}
long startTime = System.currentTimeMillis();
// do your work...
long endTime=System.currentTimeMillis();
long diff=endTime-startTime;
long hours=TimeUnit.MILLISECONDS.toHours(diff);
diff=diff-(hours*60*60*1000);
long min=TimeUnit.MILLISECONDS.toMinutes(diff);
diff=diff-(min*60*1000);
long seconds=TimeUnit.MILLISECONDS.toSeconds(diff);
//hour, min and seconds variables contains the time elapsed on your work
This is easier in Java 9:
Duration elapsedTime = Duration.ofMillis(millisDiff );
String humanReadableElapsedTime = String.format(
"%d hours, %d mins, %d seconds",
elapsedTime.toHours(),
elapsedTime.toMinutesPart(),
elapsedTime.toSecondsPart());
This produces a string like 0 hours, 39 mins, 9 seconds.
If you want to round to whole seconds before formatting:
elapsedTime = elapsedTime.plusMillis(500).truncatedTo(ChronoUnit.SECONDS);
To leave out the hours if they are 0:
long hours = elapsedTime.toHours();
String humanReadableElapsedTime;
if (hours == 0) {
humanReadableElapsedTime = String.format(
"%d mins, %d seconds",
elapsedTime.toMinutesPart(),
elapsedTime.toSecondsPart());
} else {
humanReadableElapsedTime = String.format(
"%d hours, %d mins, %d seconds",
hours,
elapsedTime.toMinutesPart(),
elapsedTime.toSecondsPart());
}
Now we can have for example 39 mins, 9 seconds.
To print minutes and seconds with leading zero to make them always two digits, just insert 02 into the relevant format specifiers, thus:
String humanReadableElapsedTime = String.format(
"%d hours, %02d mins, %02d seconds",
elapsedTime.toHours(),
elapsedTime.toMinutesPart(),
elapsedTime.toSecondsPart());
Now we can have for example 0 hours, 39 mins, 09 seconds.
for correct strings ("1hour, 3sec", "3 min" but not "0 hour, 0 min, 3 sec") i write this code:
int seconds = (int)(millis / 1000) % 60 ;
int minutes = (int)((millis / (1000*60)) % 60);
int hours = (int)((millis / (1000*60*60)) % 24);
int days = (int)((millis / (1000*60*60*24)) % 365);
int years = (int)(millis / 1000*60*60*24*365);
ArrayList<String> timeArray = new ArrayList<String>();
if(years > 0)
timeArray.add(String.valueOf(years) + "y");
if(days > 0)
timeArray.add(String.valueOf(days) + "d");
if(hours>0)
timeArray.add(String.valueOf(hours) + "h");
if(minutes>0)
timeArray.add(String.valueOf(minutes) + "min");
if(seconds>0)
timeArray.add(String.valueOf(seconds) + "sec");
String time = "";
for (int i = 0; i < timeArray.size(); i++)
{
time = time + timeArray.get(i);
if (i != timeArray.size() - 1)
time = time + ", ";
}
if (time == "")
time = "0 sec";
If you know the time difference would be less than an hour, then you can use following code:
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c2.add(Calendar.MINUTE, 51);
long diff = c2.getTimeInMillis() - c1.getTimeInMillis();
c2.set(Calendar.MINUTE, 0);
c2.set(Calendar.HOUR, 0);
c2.set(Calendar.SECOND, 0);
DateFormat df = new SimpleDateFormat("mm:ss");
long diff1 = c2.getTimeInMillis() + diff;
System.out.println(df.format(new Date(diff1)));
It will result to: 51:00
This answer is similar to some answers above. However, I feel that it would be beneficial because, unlike other answers, this will remove any extra commas or whitespace and handles abbreviation.
/**
* Converts milliseconds to "x days, x hours, x mins, x secs"
*
* #param millis
* The milliseconds
* #param longFormat
* {#code true} to use "seconds" and "minutes" instead of "secs" and "mins"
* #return A string representing how long in days/hours/minutes/seconds millis is.
*/
public static String millisToString(long millis, boolean longFormat) {
if (millis < 1000) {
return String.format("0 %s", longFormat ? "seconds" : "secs");
}
String[] units = {
"day", "hour", longFormat ? "minute" : "min", longFormat ? "second" : "sec"
};
long[] times = new long[4];
times[0] = TimeUnit.DAYS.convert(millis, TimeUnit.MILLISECONDS);
millis -= TimeUnit.MILLISECONDS.convert(times[0], TimeUnit.DAYS);
times[1] = TimeUnit.HOURS.convert(millis, TimeUnit.MILLISECONDS);
millis -= TimeUnit.MILLISECONDS.convert(times[1], TimeUnit.HOURS);
times[2] = TimeUnit.MINUTES.convert(millis, TimeUnit.MILLISECONDS);
millis -= TimeUnit.MILLISECONDS.convert(times[2], TimeUnit.MINUTES);
times[3] = TimeUnit.SECONDS.convert(millis, TimeUnit.MILLISECONDS);
StringBuilder s = new StringBuilder();
for (int i = 0; i < 4; i++) {
if (times[i] > 0) {
s.append(String.format("%d %s%s, ", times[i], units[i], times[i] == 1 ? "" : "s"));
}
}
return s.toString().substring(0, s.length() - 2);
}
/**
* Converts milliseconds to "x days, x hours, x mins, x secs"
*
* #param millis
* The milliseconds
* #return A string representing how long in days/hours/mins/secs millis is.
*/
public static String millisToString(long millis) {
return millisToString(millis, false);
}
There is a problem. When milliseconds is 59999, actually it is 1 minute but it will be computed as 59 seconds and 999 milliseconds is lost.
Here is a modified version based on previous answers, which can solve this loss:
public static String formatTime(long millis) {
long seconds = Math.round((double) millis / 1000);
long hours = TimeUnit.SECONDS.toHours(seconds);
if (hours > 0)
seconds -= TimeUnit.HOURS.toSeconds(hours);
long minutes = seconds > 0 ? TimeUnit.SECONDS.toMinutes(seconds) : 0;
if (minutes > 0)
seconds -= TimeUnit.MINUTES.toSeconds(minutes);
return hours > 0 ? String.format("%02d:%02d:%02d", hours, minutes, seconds) : String.format("%02d:%02d", minutes, seconds);
}
I have covered this in another answer but you can do:
public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) {
long diffInMillies = date2.getTime() - date1.getTime();
List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class));
Collections.reverse(units);
Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>();
long milliesRest = diffInMillies;
for ( TimeUnit unit : units ) {
long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS);
long diffInMilliesForUnit = unit.toMillis(diff);
milliesRest = milliesRest - diffInMilliesForUnit;
result.put(unit,diff);
}
return result;
}
The output is something like Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}, with the units ordered.
It's up to you to figure out how to internationalize this data according to the target locale.
DurationFormatUtils.formatDurationHMS(long)
I modified #MyKuLLSKI 's answer and added plurlization support. I took out seconds because I didn't need them, though feel free to re-add it if you need it.
public static String intervalToHumanReadableTime(int intervalMins) {
if(intervalMins <= 0) {
return "0";
} else {
long intervalMs = intervalMins * 60 * 1000;
long days = TimeUnit.MILLISECONDS.toDays(intervalMs);
intervalMs -= TimeUnit.DAYS.toMillis(days);
long hours = TimeUnit.MILLISECONDS.toHours(intervalMs);
intervalMs -= TimeUnit.HOURS.toMillis(hours);
long minutes = TimeUnit.MILLISECONDS.toMinutes(intervalMs);
StringBuilder sb = new StringBuilder(12);
if (days >= 1) {
sb.append(days).append(" day").append(pluralize(days)).append(", ");
}
if (hours >= 1) {
sb.append(hours).append(" hour").append(pluralize(hours)).append(", ");
}
if (minutes >= 1) {
sb.append(minutes).append(" minute").append(pluralize(minutes));
} else {
sb.delete(sb.length()-2, sb.length()-1);
}
return(sb.toString());
}
}
public static String pluralize(long val) {
return (Math.round(val) > 1 ? "s" : "");
}
Use java.util.concurrent.TimeUnit, and use this simple method:
private static long timeDiff(Date date, Date date2, TimeUnit unit) {
long milliDiff=date2.getTime()-date.getTime();
long unitDiff = unit.convert(milliDiff, TimeUnit.MILLISECONDS);
return unitDiff;
}
For example:
SimpleDateFormat sdf = new SimpleDateFormat("yy/MM/dd HH:mm:ss");
Date firstDate = sdf.parse("06/24/2017 04:30:00");
Date secondDate = sdf.parse("07/24/2017 05:00:15");
Date thirdDate = sdf.parse("06/24/2017 06:00:15");
System.out.println("days difference: "+timeDiff(firstDate,secondDate,TimeUnit.DAYS));
System.out.println("hours difference: "+timeDiff(firstDate,thirdDate,TimeUnit.HOURS));
System.out.println("minutes difference: "+timeDiff(firstDate,thirdDate,TimeUnit.MINUTES));
System.out.println("seconds difference: "+timeDiff(firstDate,thirdDate,TimeUnit.SECONDS));
This topic has been well covered, I just wanted to share my functions perhaps you can make use of these rather than importing an entire library.
public long getSeconds(ms) {
return (ms/1000%60);
}
public long getMinutes(ms) {
return (ms/(1000*60)%60);
}
public long getHours(ms) {
return ((ms/(1000*60*60))%24);
}

Add two String Times in java [duplicate]

This question already has answers here:
Sum two dates in Java
(9 answers)
Closed 8 years ago.
I have two String times
1:30:00
1:35:00
Is there a simple way to add these two times and get a new time which should be something
3:05:00?
I want to do this at client side , so if i can avoid any date liabraries
String time1="0:01:30";
String time2="0:01:35";
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
timeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date1 = timeFormat.parse(time1);
Date date2 = timeFormat.parse(time2);
long sum = date1.getTime() + date2.getTime();
String date3 = timeFormat.format(new Date(sum));
System.out.println("The sum is "+date3);
Ouput : The sum is 00:03:05
Keep in mind that you can convert int values for hours/minutes/seconds to a single int like this:
int totalSeconds = ((hours * 60) + minutes) * 60 + seconds;
And convert back:
int hours = totalSeconds / 3600; // Be sure to use integer arithmetic
int minutes = ((totalSeconds) / 60) % 60;
int seconds = totalSeconds % 60;
Or you can do arithmetic piecemeal as follows:
int totalHours = hours1 + hours2;
int totalMinutes = minutes1 + minutes2;
int totalSeconds = seconds1 + seconds2;
if (totalSeconds >= 60) {
totalMinutes ++;
totalSeconds = totalSeconds % 60;
}
if (totalMinutes >= 60) {
totalHours ++;
totalMinutes = totalMinutes % 60;
}
Use SimpleDateFormat to parse the Strings then you can add the hours minutes and seconds
something like
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
d1 = df.parse("1:30:00");
d2 = df.parse("1:35:00");
Long sumtime= d1.getTime()+d2.getTime();
you can see this here as well it looks like possible duplicate of #####
or if you want to use Calender API, then you can also do it using Calender API, then u can do something like
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
Calendar cTotal = Calendar.getInstance();
cTotal.add(c1.get(Calendar.YEAR), c2.get(Calendar.YEAR));
cTotal.add(c1.get(Calendar.MONTH) + 1)), c2.get(Calendar.MONTH) + 1)); // Months are zero-based!
cTotal.add(c1.get(Calendar.DATE), c2.get(Calendar.DATE));
Just sum them as you sum numbers in 1st-2nd grades, going backwards through them.
Also make sure you move over digits to higher register when needed (i.e. not
always when reaching 10 but when reaching 24 or 60 for hours/minutes).
So I suggest you code this algorithm yourself.

Categories