How can I format this date? - java

I have a date that has the format:
"yyyy-MM-dd'T'HH:mm:ss'Z'"
I'd like to convert it to something similar to:
"3 minutes ago"
How can I go about doing this?

See this SO question:
How can I calculate a time span in Java and format the output?

Ugly, but does the trick.. and yes, a duplicate! :(
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
c.set(2010, 10, 20, 22, 37, 12);
Date start = c.getTime();
Date end = new Date();
long diff = (end.getTime() - start.getTime()) / 1000;
long days = diff / (60 * 60 * 24);
long hours = diff / (60 * 60) - days * 24;
long minutes = diff / 60 - (hours * 60 + days * 24 * 60);
long seconds = diff % 60;
String output = "";
if (days >= 1)
output += days + " day" + ((days > 1) ? "s" : "");
if (hours >= 1)
output += " " + hours + " hour" + ((hours > 1) ? "s" : "");
if (minutes >= 1)
output += " " + minutes + " minute" + ((minutes > 1) ? "s" : "");
if (seconds >= 1)
output += " " + seconds + " second" + ((seconds > 1) ? "s" : "");
output = output.trim();
System.out.println(output);
}

For oarsing the date, check How to parse a date?
For displaying it in a nicer format, check for PrettyTime.

Related

How to find the difference between times

I am trying to make a program for to find the difference between two hours.
The program searching in to the database of mongoDB all the hours and it must find every time the difference between them. But I do not know how to give the second value to take it every time in the loop.
Until now i make to find one time and to subtract from one standar.
How i can put to searching for the first two values of time in a loop...every time.
Thank you very much for your help!!!
int count = 1;
int start = 1;
while (cursorEvents.hasNext()) {
DBObject documentInEventCollection = cursorEvents.next();
if("pageLoad".equals(documentInEventCollection.get("type"))){
System.out.println("URL(" + count + "): " + documentInEventCollection.get("url").toString());
System.out.println("time-start(" + start + "): " + documentInEventCollection.get("timeStamp").toString());
count++;
start++;
try {
String timeStart = (documentInEventCollection.get("timeStamp").toString());
String timeStop = ("2015-07-24;12:26:54");
SimpleDateFormat format = new SimpleDateFormat("yyyy-dd-MM;HH:mm:ss");
Date d1 = null;
Date d2 = null;
d1 = format.parse(timeStart);
d2 = format.parse(timeStop);
//in milliseconds
long diff = d2.getTime() - d1.getTime();
long diffSeconds = diff / 1000 % 60;
long diffMinutes = diff / (60 * 1000) % 60;
long diffHours = diff / (60 * 60 * 1000) % 24;
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.print(diffDays + " days, ");
System.out.print(diffHours + " hours, ");
System.out.print(diffMinutes + " minutes, ");
System.out.print(diffSeconds + " seconds.");
} catch (Exception e) {
e.printStackTrace();
}
}
}
I use follow solution to calculate a time different:
//Compute the time diff
Map<TimeUnit, Long> deltaTime = computeDiff(now.getTime(), target.getTime());
//Get the specific values
long d = deltaTime.get(TimeUnit.DAYS);
long m = deltaTime.get(TimeUnit.MINUTES);
long s = deltaTime.get(TimeUnit.SECONDS);
Methode code:
private static Map<TimeUnit, Long> computeDiff(Date start, Date end) {
long diffMilTime = end.getTime() - start.getTime();
List<TimeUnit> units = new ArrayList<>(EnumSet.allOf(TimeUnit.class));
Collections.reverse(units);
Map<TimeUnit, Long> result = new LinkedHashMap<>();
long restMilTime = diffMilTime;
for (TimeUnit unit : units) {
long diff = unit.convert(restMilTime, TimeUnit.MILLISECONDS);
long diffInMilliesForUnit = unit.toMillis(diff);
restMilTime = restMilTime - diffInMilliesForUnit;
result.put(unit, diff);
}
return result;
}

Subtracting time Strings in Java

I have two times in String format. 9:00 AM and 10:00 AM. I want to subtract them. the difference must be 1 hour. I tried the following code to do that but i am not getting the desired results:
String time1 = "9:00 AM";
String time2 = "10:00 AM";
SimpleDateFormat formatter = new SimpleDateFormat("h:mm a");
Date d1 = formatter.parse(time1);
Date d2 = formatter.parse(time2);
long timeDiff = d2.getTime() - d1.getTime();
Date diff = new Date(timeDiff);
System.out.println(formatter.format(diff));
How can i do that ?
Try something like:
long timeDiff = d2.getTime() - d1.getTime();
System.out.println((timeDiff / 3600000) + " hour/s " + (timeDiff % 3600000) / 60000 + " minutes");
Output
1 hour/s 5 minutes
Use Joda time! See this question
DateTimeFormatter formatter = DateTimeFormat.forPattern("H:mm a");
DateTime time1 = formatter.parseDateTime("9:00 AM");
DateTime time2 = formatter.parseDateTime("10:00 AM");
Duration duration = new Duration(time1, time2);
System.out.printf("%s hour(s), %s minute(s)%n", duration.getStandardHours(), duration.getStandardMinutes());
Your approach seems to be correct.
Only thing you should not do is, changing timeDiff to new Date.
Rather, change it to get time in minutes and hours as follows
Ex : -
long diffMinutes = timeDiff / (60 * 1000) % 60;
long diffHours = timeDiff / (60 * 60 * 1000) % 24;
System.out.println(diffHours+" hours "+ diffMinutes +" minutes");
here is the complete code You can refer to if you want more proper display of time difference,
import java.util.*;
import java.lang.*;
import java.io.*;
import java.text.*;
/* Name of the class has to be "Main" only if the class is public. */
class TimeDiffTester
{
public static String show(long value, String showAs) {
if(value == 0) {
return "";
} else {
return Math.abs(value) +" "+showAs+" ";
}
}
public static void getDifferenceInTime(String time1, String time2) throws java.lang.Exception {
SimpleDateFormat formatter = new SimpleDateFormat("h:mm a");
Date d1 = formatter.parse(time1);
Date d2 = formatter.parse(time2);
long timeDiff = d2.getTime() - d1.getTime();
long diffDays = timeDiff / (24 * 60 * 60 * 1000);
long diffHours = timeDiff / (60 * 60 * 1000) % 24;
long diffMinutes = timeDiff / (60 * 1000) % 60;
long diffSeconds = timeDiff / 1000 % 60;
String difference = show(diffDays, "days") + show(diffHours, "hours") + show(diffMinutes, "minutes") + show(diffSeconds, "seconds");
if(diffDays < 0 || diffHours < 0 || diffMinutes < 0 || diffSeconds < 0) {
System.out.println("-"+difference);
} else {
System.out.println("+"+difference);
}
}
public static void main (String[] args) throws java.lang.Exception
{
String time1 = "4:30 PM";
String time2 = "5:00 PM";
getDifferenceInTime(time1,time2);
}
}
Here is best example given.
1000 milliseconds = 1 second
60 seconds = 1 minute
60 minutes = 1 hour
24 hours = 1 day
public static void main(String[] args) {
String dateStart = "01/14/2012 09:29:58";
String dateStop = "01/15/2012 10:31:48";
//HH converts hour in 24 hours format (0-23), day calculation
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Date d1 = null;
Date d2 = null;
try {
d1 = format.parse(dateStart);
d2 = format.parse(dateStop);
//in milliseconds
long diff = d2.getTime() - d1.getTime();
long diffSeconds = diff / 1000 % 60;
long diffMinutes = diff / (60 * 1000) % 60;
long diffHours = diff / (60 * 60 * 1000) % 24;
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.print(diffDays + " days, ");
System.out.print(diffHours + " hours, ");
System.out.print(diffMinutes + " minutes, ");
System.out.print(diffSeconds + " seconds.");
} catch (Exception e) {
e.printStackTrace();
}
}
Please find reference link for this example
http://www.mkyong.com/java/how-to-calculate-date-time-difference-in-java/

Java: convert seconds to minutes, hours and days [duplicate]

This question already has answers here:
Convert seconds value to hours minutes seconds?
(22 answers)
Closed 6 years ago.
The task is:
The output should look like this (it is a good idea to echo back the input): You entered 500,000 seconds, which is 5 days, 18 hours, 53 minutes and 20 seconds. (5 days 18:53:20 hours)
How should I do it? What is the easiest way to understand and do it?
Also the instructor said "no hard coding" which I'm not exactly sure what is, but I think he wants us to assign them constants.
An example using the built-in TimeUnit.
long uptime = System.currentTimeMillis();
long days = TimeUnit.MILLISECONDS
.toDays(uptime);
uptime -= TimeUnit.DAYS.toMillis(days);
long hours = TimeUnit.MILLISECONDS
.toHours(uptime);
uptime -= TimeUnit.HOURS.toMillis(hours);
long minutes = TimeUnit.MILLISECONDS
.toMinutes(uptime);
uptime -= TimeUnit.MINUTES.toMillis(minutes);
long seconds = TimeUnit.MILLISECONDS
.toSeconds(uptime);
With basic Java arithmetic calculations:
First consider the following values:
1 minute = 60 seconds
1 hour = 3600 seconds (60 * 60)
1 day = 86400 second (24 * 3600)
First divide the input by 86400. If you you can get a number greater than 0, this is the number of days.
Again divide the remained number you get from the first calculation by 3600. This will give you the number of hours.
Then divide the remainder of your second calculation by 60 which is the number of minutes
Finally the remained number from your third calculation is the number of seconds
The code snippet is as follows:
int input = 500000;
int numberOfDays;
int numberOfHours;
int numberOfMinutes;
int numberOfSeconds;
numberOfDays = input / 86400;
numberOfHours = (input % 86400) / 3600 ;
numberOfMinutes = ((input % 86400) % 3600) / 60
numberOfSeconds = ((input % 86400) % 3600) % 60;
It should be like:
public static void calculateTime(long seconds) {
int day = (int)TimeUnit.SECONDS.toDays(seconds);
long hours = TimeUnit.SECONDS.toHours(seconds) - (day *24);
long minute = TimeUnit.SECONDS.toMinutes(seconds) -
(TimeUnit.SECONDS.toHours(seconds)* 60);
long second = TimeUnit.SECONDS.toSeconds(seconds) -
(TimeUnit.SECONDS.toMinutes(seconds) *60);
System.out.println(
"Day " + day + " Hour " + hours + " Minute " + minute +
" Seconds " + second);
}
Explanation:
TimeUnit.SECONDS.toHours(seconds) will give you direct conversion from seconds to hours with out consideration for days. Minus the hours for days you already got i.e., day24*. You now got remaining hours.
The same for minute and second. You need to subtract the already got hour and minutes, respectively.
The simplest way:
Scanner in = new Scanner(System.in);
System.out.println("Enter seconds ");
int s = in.nextInt();
int sec = s % 60;
int min = (s / 60) % 60;
int hours = (s / 60) / 60;
System.out.println(hours + ":" + min + ":" + sec);
Have a look at the class:
org.joda.time.DateTime
This allows you to do things like:
old = new DateTime();
new = old.plusSeconds(500000);
System.out.println("Hours: " + (new.Hours() - old.Hours()));
However, your solution probably can be simpler:
You need to work out how many seconds in a day, divide your input by the result to get the days, and subtract it from the input to keep the remainder.
You then need to work out how many hours in the remainder, followed by the minutes,
and the final remainder is the seconds.
This is the analysis done for you, and now you can focus on the code.
You need to ask what s/he means by "no hard coding". Generally it means pass parameters, rather than fixing the input values. There are many ways to do this, depending on how you run your code. Properties are a common way in Java.
You should try this
import java.util.Scanner;
public class Time_converter {
public static void main(String[] args) {
Scanner input = new Scanner (System.in);
int seconds;
int minutes;
int hours;
System.out.print("Enter the number of seconds: ");
seconds = input.nextInt();
hours = seconds / 3600;
minutes = (seconds % 3600) / 60;
int seconds_output = (seconds % 3600) % 60;
System.out.println("The time entered in hours,minutes and seconds is:");
System.out.println(hours + " hours: " + minutes + " minutes: " + seconds_output + " seconds");
}
}
You can use the Java enum TimeUnit to perform your math and avoid any hard-coded values. Then we can use String.format(String, Object...) and a pair of StringBuilder(s) as well as a DecimalFormat to build the requested output. Something like,
Scanner scanner = new Scanner(System.in);
System.out.println("Please enter a number of seconds: ");
String str = scanner.nextLine().replace("\\,", "").trim();
long secondsIn = Long.parseLong(str);
long dayCount = TimeUnit.SECONDS.toDays(secondsIn);
long secondsCount = secondsIn - TimeUnit.DAYS.toSeconds(dayCount);
long hourCount = TimeUnit.SECONDS.toHours(secondsCount);
secondsCount -= TimeUnit.HOURS.toSeconds(hourCount);
long minutesCount = TimeUnit.SECONDS.toMinutes(secondsCount);
secondsCount -= TimeUnit.MINUTES.toSeconds(minutesCount);
StringBuilder sb = new StringBuilder();
sb.append(String.format("%d %s, ", dayCount, (dayCount == 1) ? "day"
: "days"));
StringBuilder sb2 = new StringBuilder();
sb2.append(sb.toString());
sb2.append(String.format("%02d:%02d:%02d %s", hourCount, minutesCount,
secondsCount, (hourCount == 1) ? "hour" : "hours"));
sb.append(String.format("%d %s, ", hourCount, (hourCount == 1) ? "hour"
: "hours"));
sb.append(String.format("%d %s and ", minutesCount,
(minutesCount == 1) ? "minute" : "minutes"));
sb.append(String.format("%d %s.", secondsCount,
(secondsCount == 1) ? "second" : "seconds"));
System.out.printf("You entered %s seconds, which is %s (%s)%n",
new DecimalFormat("#,###").format(secondsIn), sb, sb2);
Which, when I enter 500000, outputs the requested (manual line break added for post) -
You entered 500,000 seconds, which is 5 days, 18 hours,
53 minutes and 20 seconds. (5 days, 18:53:20 hours)
I started doing some pseudocode and came up with this:
import java.util.Scanner;
public class Project {
public static void main(String[] args) {
// Variable declaration
Scanner scan = new Scanner(System.in);
final int MIN = 60, HRS = 3600, DYS = 84600;
int input, days, seconds, minutes, hours, rDays, rHours;
// Input
System.out.println("Enter amount of seconds!");
input = scan.nextInt();
// Calculations
days = input/DYS;
rDays = input%DYS;
hours = rDays/HRS;
rHours = rDays%HRS;
minutes = rHours/MIN;
seconds = rHours%MIN;
// Output
if (input >= DYS) {
System.out.println(input + " seconds equals to " + days + " days " + hours + " hours " + minutes + " minutes " + seconds + " seconds");
}
else if (input >= HRS && input < DYS) {
System.out.println(input + " seconds equals to " + hours + " hours " + minutes + " minutes " + seconds + " seconds");
}
else if (input >= MIN && input < HRS) {
System.out.println(input + " seconds equals to " + minutes + " minutes " + seconds + " seconds");
}
else if (input < MIN) {
System.out.println(input + " seconds equals to seconds");
}
scan.close();
}

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

Calculation of times off milliseconds to time

This code below is used to format milliseconds. The calculations are off by a long shot. I need some help with it. Output of my code is below as well as the milliseconds into a Date class.
public static void main(String[] args) {
System.out.println("Wrong Time: " + getTime(999999999 * 599));
}
//Being called into this method is milliseconds = 598999999401
public static String getTime(long miliseconds) {
int years = (int) ((miliseconds / (1000*60*60*24*7*52*12)));
int months = (int) (miliseconds / (1000*60*60*24*7*52) % 12);
int weeks = (int) ((miliseconds / (1000*60*60*24*7)) % 52);
int days = (int) ((miliseconds / (1000*60*60*24)) % 7);
int hours = (int) ((miliseconds / (1000*60*60)) % 24);
int minutes = (int) ((miliseconds / (1000*60)) % 60);
int seconds = (int) (miliseconds / 1000) % 60;
Date date = new Date(598999999401L);//This gets the real time
System.out.println("Right Time: " + date.getYear() + " years " + (int)(date.getMonth() % 12) + " months " + (int)(date.getDay() % 52) + " weeks "
+ (int)(date.getDay() % 7) + " days " + (int)(date.getHours() % 24) + " hours " + (int)(date.getMinutes() % 60) + " minutes " +
+ (int)(date.getSeconds() % 60) + " seconds");
return (years <= 0 ? "" : years + " year" + (years != 1 ? "s" : "")) +
(months <= 0 ? "" : " " + months + " month" + (months != 1 ? "s" : "")) +
(weeks <= 0 ? "" : " " + weeks + " week" + (weeks != 1 ? "s" : "")) +
(days <= 0 ? "" : " " + days + " day" + (days != 1 ? "s" : "")) +
(hours <= 0 ? "" : " " + hours + " hour" + (hours != 1 ? "s" : "")) +
(minutes <= 0 ? "" : " " + minutes + " minute" + (minutes != 1 ? "s" : "")) +
(seconds <= 0 ? "" : " " + seconds + " second" + (seconds != 1 ? "s" : ""));
}
Correct Output(Date class)
Right Time: 88 years 11 months 6 weeks 6 days 14 hours 53 minutes 19 seconds
Wrong Output(My method)
Wrong Time: 1 month 3 weeks 2 days 3 hours 25 minutes 45 seconds
UPDATE 1 (NEW CALCULATIONS)(Still has logic errors):
int years = (int) ((miliseconds / (1000*60*60*24*7*4*12)));
int months = (int) (miliseconds / (1000*60*60*24*7*4) % 12);
int weeks = (int) ((miliseconds / (1000*60*60*24*7)) % 4);
int days = (int) ((miliseconds / (1000*60*60*24)) % 7);
int hours = (int) ((miliseconds / (1000*60*60)) % 24);
int minutes = (int) ((miliseconds / (1000*60)) % 60);
int seconds = (int) (miliseconds / 1000) % 60;
Two issues.
Your code seems to reflect a belief that there are 52 weeks in a month. These are the two lines at fault.
int years = (int) ((miliseconds / (1000*60*60*24*7*52*12)));
int months = (int) (miliseconds / (1000*60*60*24*7*52) % 12);
Also, you're using int where you should be using long. The maximum int number of milliseconds is just under 25 days, so you can never do date/time arithmetic with int.
One problem is int overflow since your main method is using int literals, not longs. Try:
System.out.println("Wrong Time: " + getTime(999999999L * 599L));
Also, don't use magic numbers. Use constants that make sense and that make your code self-commenting:
private static final int MILI_PER_SEC = 1000;
private static final int SEC_PER_MIN = 60;
private static final int MIN_PER_HR = 60;
private static final int HR_PER_DAY = 24;
private static final int DAYS_PER_YR = 365;
and then,
int years = (int) (miliseconds / (MILI_PER_SEC * SEC_PER_MIN * MIN_PER_HR *
HR_PER_DAY * DAYS_PER_YR));
Also, your calculations are all off. You shouldn't be using weeks in the year calculation at all. Use constants, have them make sense. And how do you know that the "correct" result is in fact correct? You are using deprecated code, and Date doesn't use miliseconds the way that you think that it does. It calculates the date relative to January 1, 1970, 00:00:00 GMT as per the Date API.

Categories