calculate elapsed time and display it in Java - java

There seems to be no easy answer in stackoverflow for this problem. I simply want to get the difference between two Calendar instances and display in HH:mm:ss.SSS
So far, I have
SimpleDateFormat dateFormat = new
SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Calendar start = Calendar.getInstance();
say("start time:"+dateFormat.format(start.getTime()));
and
Calendar ending = Calendar.getInstance();
say("ending time:"+dateFormat.format(ending.getTime()));
long milli = ending.getTime().getTime()
- start.getTime().getTime();
long sec = milli / 1000; // millisec to sec
say("elapsed time: " + sec + "." + milli );
which does work to display the two times.
start time: 2018-03-02 15:44:41.194
*** program runs ***
ending time:2018-03-02 15:44:41.198
elapsed time: 0.4
But shouldn't it be saying 0.004 seconds?
And PLEASE no JodaTime answers. This shop does not support that.

Instant start = Instant.now();
And
Instant end = Instant.now();
long milli = ChronoUnit.MILLIS.between(start, end);
System.out.format(Locale.ENGLISH, "elapsed time: %.3f%n", milli / 1000.0);
On my computer this printed
elapsed time: 0.004
Formatting with String.format or System.out.format() also works with your way of measuring the milliseconds, of course.
Using Java 9 you can (at least on some computers) have more decimals if you want:
System.out.println("elapsed time: "
+ ChronoUnit.NANOS.between(start, end) / (double) TimeUnit.SECONDS.toNanos(1));
I got
elapsed time: 0.003739

I wrote a little function for you, it returns a number as a string filled with as many "0" as you want.
public String getStringNumber(long number, int displaySize) {
String str = new String();
int length = String.valueOf(number).length();
while (length++ < displaySize)
str += "0";
str += number;
return str;
}
Now you can just replace in your code
say("elapsed time: " + sec + "." + getStringNumber(milli, 4));

I finally arrived on this solution. It is awkward and not very elegant, but it works.
Calendar ending = Calendar.getInstance();
say("ending time:"+dateFormat.format(ending.getTime()));
long milli = ending.getTime().getTime()
- start.getTime().getTime();
long hrs = TimeUnit.MILLISECONDS.toHours(milli) % 24;
long
min = TimeUnit.MILLISECONDS.toMinutes(milli) % 60;
long sec
= TimeUnit.MILLISECONDS.toSeconds(milli) % 60;
long mls = milli % 1000;
String elaps =
String.format("%02d:%02d:%02d.%03d", hrs,
min, sec, mls);
say("Elapsed time: " + elaps);
Here is the explanation: I convert the two Calendar variables to long, and subtract. Then I format the Long to a string in format hh:mm:ss.SSS which is what I wanted in the first place.
Here is the output
ending time:2018-03-05 15:07:17.923
Elapsed time: 00:01:15.964

Okay, so, simply off the top of my head, without trying to perform anything kind of fancy, you could make use of the Java 8 date/time API, which provides the capability to calculate the different between two points in time.
So, taking your input, and running it through the code below, it outputs
2018-03-02T15:44:41.194
2018-03-02T15:44:41.198
0.004
Now, personally, I'd take the concept and simply create a DurationFormatter which could take a Duration and spit out your required format, but the idea here is to give you a jumping point to start from.
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class Test {
public static void main(String[] args) {
String startTime = "2018-03-02 15:44:41.194";
String endTime = "2018-03-02 15:44:41.198";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
LocalDateTime startDateTime = LocalDateTime.parse(startTime, formatter);
LocalDateTime endDateTime = LocalDateTime.parse(endTime, formatter);
System.out.println(startDateTime);
System.out.println(endDateTime);
Duration duration = Duration.between(startDateTime, endDateTime);
long hours = duration.toHours();
duration = duration.minusHours(hours);
long mins = duration.toMinutes();
duration = duration.minusMinutes(mins);
long secs = duration.getSeconds();
duration = duration.minusSeconds(secs);
long millis = duration.toMillis();
StringBuilder sb = new StringBuilder(12);
if (hours > 0) {
sb.append(pad(hours, 2));
}
if (mins == 0 && sb.length() > 0) {
sb.append(":00");
} else if (mins > 0) {
if (hours > 0) {
sb.append(":");
}
sb.append(pad(mins, 2));
}
if (secs == 0 & sb.length() > 0) {
sb.append(":00");
} else if (secs > 0) {
if (mins > 0) {
sb.append(":");
}
sb.append(pad(secs, 2));
}
if (millis == 0 & sb.length() > 0) {
sb.append(".00");
} else if (millis > 0) {
if (secs > 0 || sb.length() > 0) {
sb.append(".");
} else if (sb.length() == 0) {
sb.append("0.");
}
sb.append(pad(millis, 3));
}
System.out.println(sb.toString());
}
public static String pad(long value, long length) {
return String.format("%0" + length + "d", value);
}
}
Now, if we change the input to something like...
String startTime = "2018-03-02 15:44:41.194";
String endTime = "2018-03-08 15:44:41.198";
It outputs
144:00:00.004
Or if we use
String startTime = "2018-03-02 15:44:41.194";
String endTime = "2018-03-08 15:15:41.198";
It outputs
143:31:00.004
Or
String startTime = "2018-03-02 15:44:41.194";
String endTime = "2018-03-08 15:15:50.198";
It outputs
143:31:09.004
Or
2018-03-02T15:44:41.194
2018-03-02T15:50:41.194
It outputs
06:00.00
... to me, this is where it gets weird, technically it's correct (6 mins), but from the format, it's hard to deduce exactly what it means
This is where I might be tempted to use something more like String.format("%02d:%02d:%02d.%04d", hours, mins, secs, millis) which will output 00:06:00.0000, but that all comes do to you needs. You will need to decide how best to take the raw information and present it based on your needs, but there are a couple of different ideas

Related

Calculate Rate per hour based on Time

import java.text.SimpleDateFormat;
import java.util.Date;
public class Rate_Per_Hour {
public static void main(String[] args) {
String TimeStart = "09.30.00 am";
String TimeEnd= "10.10.00 am";
SimpleDateFormat format = new SimpleDateFormat("hh.mm.ss a");
int total=0;
Date d1 = null;
Date d2 = null;
try {
d1 = format.parse(TimeStart);
d2 = format.parse(TimeEnd);
long diff = d2.getTime() - d1.getTime();
long diffHours = diff / (60 * 60 * 1000) % 24;
long diffMinutes = diff / (60 * 1000) % 60;
if (diffMinutes <= 30) {
total = 20;
}
else if (diffHours <=1){
total = 35;
}
System.out.println("Rs." +total);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
I want output like this:
(Fixed rate per hour for this is Rs.35 )
For 30 min = Rs.20
For 40 min = Rs.25 and so on......
For 1 hour = Rs.35
For 1 hour 10 min = Rs.40
Please help me, figure out how I can do this.
Since the rate increases by 5 every 10 minutes, so just use a simple function to return the rate:
public double rate(int minutes)
{
return 20 + 5*((minutes - 30)/10);
}
Calculate the number of minutes and then pass it as an argument in that function to get the rate. Also, try to keep your code as short as possible but at the same time, simple.
if you need something more flexible rather than fixed rate you could implement an enum with predefined stops
you could define any rate you want for a given time.
for example if long running tasks shall gain higher rates (from your question it was not obvious to me if this rate shall be just the calculated value as in Manish Kundu's answer or if other values might get assigned.)
with this code you could assign higher rates for long running jobs (for example in computer games, jobs that are harder to achieve you return a higher rate or you lower the rate because the player took too much time...)
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
public class TimeMain {
private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("hh.mm.ss[ ]a");
public enum Rate {
STOP0(0, 0, 0), // default
STOP1(0, 30, 20), // 30 mins -> Rs.20
STOP2(0, 40, 25), // 40 mins -> Rs.25
STOP3(1, 0, 35), // 1 hour -> Rs.35
STOP4(1, 10, 40); // 1 hour 10 minutes -> Rs.40
int minutes = 0;
int rate = 0;
/*
* hours is actually not needed as 1h10 = 70mins...
*/
private Rate(int hours, int minutes, int rate) {
this.minutes = minutes + hours * 60;
this.rate = rate;
}
public static Rate from(String timeStart, String timeEnd) {
LocalTime time1 = LocalTime.parse(timeStart.toUpperCase(), dateTimeFormatter);
LocalTime time2 = LocalTime.parse(timeEnd.toUpperCase(), dateTimeFormatter);
long minutesBetween = ChronoUnit.MINUTES.between(time1, time2);
for (int i = 0; i < Rate.values().length; i++) {
Rate r = Rate.values()[i];
if (r.minutes > minutesBetween) {
return Rate.values()[i-1];
}
}
return STOP0;
}
public String toString() {
return String.format("Rs.%s", rate);
}
}
public static void main(String... args) {
String timeStart = "09.30.00 am";
String timeEnd = "10.10.00 am";
System.out.println(Rate.from(timeStart, timeEnd));
}
}

customize android Date like twitter and instagram news feed

how can I customize the date format in an android development to be like that of twitter and instagram. What i have below my current code, but I don't like the format it produces like "11 minutes ago" or "34 minutes ago". I prefer the twitter format like "11m" or "34m". Please anyone know how i can format my date like that?
Date createdAt = message.getCreatedAt();//get the date the message was created from parse backend
long now = new Date().getTime();//get current date
String convertedDate = DateUtils.getRelativeTimeSpanString(
createdAt.getTime(), now, DateUtils.SECOND_IN_MILLIS).toString();
mPostMessageTimeLabel.setText(convertedDate); //sets the converted date into the message_item.xml view
Had the same problem. Instead of using a library I figured I could probably write my own version and have it be a little more understandable as to what is happening (and be able to tweak it a bit if needed).
Here is the utility method I made (helpful Log statements for Android users to test it out included):
public static String convertLongDateToAgoString (Long createdDate, Long timeNow){
Long timeElapsed = timeNow - createdDate;
// For logging in Android for testing purposes
/*
Date dateCreatedFriendly = new Date(createdDate);
Log.d("MicroR", "dateCreatedFriendly: " + dateCreatedFriendly.toString());
Log.d("MicroR", "timeNow: " + timeNow.toString());
Log.d("MicroR", "timeElapsed: " + timeElapsed.toString());*/
// Lengths of respective time durations in Long format.
Long oneMin = 60000L;
Long oneHour = 3600000L;
Long oneDay = 86400000L;
Long oneWeek = 604800000L;
String finalString = "0sec";
String unit;
if (timeElapsed < oneMin){
// Convert milliseconds to seconds.
double seconds = (double) ((timeElapsed / 1000));
// Round up
seconds = Math.round(seconds);
// Generate the friendly unit of the ago time
if (seconds == 1) {
unit = "sec";
} else {
unit = "secs";
}
finalString = String.format("%.0f", seconds) + unit;
} else if (timeElapsed < oneHour) {
double minutes = (double) ((timeElapsed / 1000) / 60);
minutes = Math.round(minutes);
if (minutes == 1) {
unit = "min";
} else {
unit = "mins";
}
finalString = String.format("%.0f", minutes) + unit;
} else if (timeElapsed < oneDay) {
double hours = (double) ((timeElapsed / 1000) / 60 / 60);
hours = Math.round(hours);
if (hours == 1) {
unit = "hr";
} else {
unit = "hrs";
}
finalString = String.format("%.0f", hours) + unit;
} else if (timeElapsed < oneWeek) {
double days = (double) ((timeElapsed / 1000) / 60 / 60 / 24);
days = Math.round(days);
if (days == 1) {
unit = "day";
} else {
unit = "days";
}
finalString = String.format("%.0f", days) + unit;
} else if (timeElapsed > oneWeek) {
double weeks = (double) ((timeElapsed / 1000) / 60 / 60 / 24 / 7);
weeks = Math.round(weeks);
if (weeks == 1) {
unit = "week";
} else {
unit = "weeks";
}
finalString = String.format("%.0f", weeks) + unit;
}
return finalString;
}
Usage:
Long createdDate = 1453394736888L; // Your Long
Long timeNow = new Date().getTime();
Log.d("MicroR", convertLongDateToAgoString(createdDate, timeNow));
// Outputs:
// 1min
// 3weeks
// 5hrs
// etc.
Feel free to test this out and let me know if you find any issues!
I might be a bit late, but i write it down for somebody who is looking for a solution.
Using PrettyTime you can obtain formatted dates like "2 months ago" and so on.
To fit your needs you have to feed it with a custom TimeFormat object, there is no need to create a new TimeUnit object since we are formatting normal time units.
To do this just create your TimeFormat object for minutes for example:
public class CustomMinuteTimeFormat implements TimeFormat {
#Override
public String format(Duration duration) {
return Math.abs(duration.getQuantity()) + "m";
}
#Override
public String formatUnrounded(Duration duration) {
return format(duration);
}
#Override
public String decorate(Duration duration, String time) {
return time;
}
#Override
public String decorateUnrounded(Duration duration, String time) {
return time;
}
}
Then Instantiate a new PrettyTime instance and set your formatter.
PrettyTime pretty = new PrettyTime();
//This line of code is very important
pretty.registerUnit(new Minute(), new CustomMinuteTimeFormat());
//Use your PrettyTime object as usual
pretty.format(yourDateObject);
This will output "2m" if time elapsed is 2 minutes.

How to sum times in Java?

I'm working on a report that calculates a sum of the data in it and some of the data are timestamps, for example:
----------------------
| Activity | Time |
----------------------
| 1 | 11:00:00 |
-----------------------
| 2 | 12:00:00 |
-----------------------
| 3 | 13:00:00 |
-----------------------
| Total | 36:00:00 |
----------------------
I'm trying to sum timestamps as below:
final DateFormat dt = new SimpleDateFormat("HH:mm:ss");
final Calendar c = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
c.setTimeInMillis(0);
for (final String t : timestampsList) {
c.add(Calendar.MILLISECOND, (int) dt.parse(t).getTime());
}
The variable timestampsList is an ArrayList of String's, all respecting the pattern used by the SimpleDateFormat object. The problem with the given code is that I can't generate the value of the sum of the timestamps, by using the same SimpleDateFormat what I get is an hour in the pattern informed in a future date.
I also have seen Joda Time Duration class but I'm not familiar with this lib and I 'don't know if I'm in a correct path that will lead me to the right answer.
Does anyone know how to handle it by using J2SE or Joda Time?
I would just parse these Strings myself, convert them to
seconds or milliseconds and sum them up. See answer 2 below.
ANSWER 1
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
public class Test051 {
public static void main(String[] args) throws Exception {
String pt = "1970-01-01-";
ArrayList<String> timestampsList = new ArrayList<String>();
timestampsList.add("01:00:05");
timestampsList.add("01:00:05");
timestampsList.add("10:00:05");
final DateFormat dt = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
final Calendar sum = Calendar.getInstance();
sum.setTimeInMillis(0);
long tm0 = new SimpleDateFormat("yyyy-MM-dd").parse(pt).getTime();
System.out.println("tm0 = " + tm0);
for (final String t : timestampsList) {
// System.out.println(dt.parse(pt + t).getTime());
Date x = dt.parse(pt + t);
// System.out.println(x.getTime());
sum.add(Calendar.MILLISECOND, (int)x.getTime());
sum.add(Calendar.MILLISECOND, (int)-tm0);
}
long tm = sum.getTime().getTime();
System.out.println("tm = " + tm);
tm = tm / 1000;
long hh = tm / 3600;
tm %= 3600;
long mm = tm / 60;
tm %= 60;
long ss = tm;
System.out.println(format(hh) + ":" + format(mm) + ":" + format(ss));
}
private static String format(long s){
if (s < 10) return "0" + s;
else return "" + s;
}
}
ANSWER 2
import java.util.ArrayList;
public class Test051 {
public static void main(String[] args) throws Exception {
ArrayList<String> timestampsList = new ArrayList<String>();
timestampsList.add("01:00:05");
timestampsList.add("01:00:05");
timestampsList.add("10:00:05");
long tm = 0;
for (String tmp : timestampsList){
String[] arr = tmp.split(":");
tm += Integer.parseInt(arr[2]);
tm += 60 * Integer.parseInt(arr[1]);
tm += 3600 * Integer.parseInt(arr[0]);
}
long hh = tm / 3600;
tm %= 3600;
long mm = tm / 60;
tm %= 60;
long ss = tm;
System.out.println(format(hh) + ":" + format(mm) + ":" + format(ss));
}
private static String format(long s){
if (s < 10) return "0" + s;
else return "" + s;
}
}
ANSWER 3
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
public class Test051 {
public static void main(String[] args) throws Exception {
ArrayList<String> timestampsList = new ArrayList<String>();
timestampsList.add("01:00:00");
timestampsList.add("02:00:00");
timestampsList.add("03:00:00");
timestampsList.add("04:00:00");
timestampsList.add("02:00:00");
timestampsList.add("04:00:00");
Date dt0 = new SimpleDateFormat("yyyy-MM-dd").parse("1970-01-01");
// Check very carefully the output of this one.
System.out.println(dt0.getTime());
final DateFormat dt = new SimpleDateFormat("HH:mm:ss");
final Calendar c = Calendar.getInstance();
c.setTimeInMillis(0);
for (final String t : timestampsList) {
c.add(Calendar.MILLISECOND, (int) dt.parse(t).getTime());
c.add(Calendar.MILLISECOND, (int)-dt0.getTime());
}
// We need to add this back. This is basically the time zone offset.
c.add(Calendar.MILLISECOND, (int)dt0.getTime());
System.out.println(c.getTime().getTime());
System.out.println(c.getTimeInMillis());
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(c.getTime()));
System.out.println(new SimpleDateFormat("HH:mm:ss").format(c.getTime()));
}
}
If you don't wanna use peter petrov solution to parse your String yourself, the way to do it with Calendar and SimpleDateFormat is as follow :
List<String> timestampsList = new ArrayList<String>();
timestampsList.add("11:00:00");
timestampsList.add("12:00:00");
timestampsList.add("13:00:00");
final DateFormat dt = new SimpleDateFormat("HH:mm:ss");
final Calendar c = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
long milliseconds = 0;
c.clear();
long startingMS = c.getTimeInMillis();
for (final String t : timestampsList) {
milliseconds = milliseconds + (dt.parse(t).getTime() - startingMS);
}
System.out.println(milliseconds + " milliseconds");
System.out.println(milliseconds / 1000 + " seconds");
System.out.println(milliseconds / 1000 / 60 + " minutes");
System.out.println(milliseconds / 1000 / 60 / 60 + " hours");
Or use
long startingMS = dt.parse("00:00:00").getTime();
for (final String t : timestampsList) {
milliseconds = milliseconds + (dt.parse(t).getTime() - startingMS);
}
instead, removing the need for the Calendar.
Both result in :
129600000 milliseconds
129600 seconds
2160 minutes
36 hours
Note that you might wanna make the results a double not to miss part of the time.
This is a original code from petrov with some edits made by me. Since it's quite dificult to discuss in comments providing big snippets of code I posted it as an answer so we can discuss petrov's other considerations.
public static void somaTempos(final String[] listaTempos) throws ParseException {
long tm = 0;
final DateFormat dt = new SimpleDateFormat("HH:mm:ss");
final Calendar c = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
for (String tmp : listaTempos) {
c.setTime(dt.parse(tmp));
tm += c.get(Calendar.SECOND) + 60 * c.get(Calendar.MINUTE) + 3600 * c.get(Calendar.HOUR_OF_DAY);
}
final long l = tm % 3600;
System.out.println(SIGRUtil.format(tm / 3600) + ':' + SIGRUtil.format(l / 60) + ':' + SIGRUtil.format(l % 60));
}
private static String format(long s) {
if (s < 10) {
return "0" + s;
}
return String.valueOf(s);
}
UPDATE: An alternative that also solves my problem:
public static String sumTimes(final String[] timestampList) {
long milliseconds = 0;
final DateFormat dt = new SimpleDateFormat("HH:mm:ss");
dt.setLenient(false);
try {
final long timezoneOffset = dt.parse("00:00:00").getTime();
for (final String t: timestampList) {
milliseconds += (dt.parse(t).getTime() - timezoneOffset);
}
} catch (final ParseException e) {
throw new BusinessException(
"One of the timestamps in the timestamp list cannot be applied to the HH:mm:ss pattern.", e);
}
((SimpleDateFormat) dt).applyPattern(":mm:ss");
return new StringBuilder(8).append(milliseconds / 3600000).append(
dt.format(new Date(milliseconds))).toString();
}
Actually, the API gives me for free the minutes and the seconds by only reaplying another pattern in the DateFormat after calculating the sum of the time stamps, without forgetting to consider the timezone offset in this calculation, my real problem was how to calculate the number of hours which really is the less dificult part.
Any suggestions of improvements?
If those data input Strings represent durations in hours:minutes:seconds without any date or time-of-day, then the other answers are working much too hard.
Generally, the old java.util.Date and .Calendar classes are notoriously troublesome and should be avoided. Specifically here, those classes have no notion of a span of time. Instead you should be using either Joda-Time or maybe java.time.
Joda-Time
Joda-Time offers three classes to represent a span of time: Interval, Period, and Duration. The first is tied to points along the timeline of the Universe. The other two are not.
The Period and Duration classes are very close cousins. Period is a tuple with a number of years, months, days, hours, minutes, and seconds. Duration is a number of milliseconds with no concept of fields such as days or seconds.
Joda-Time uses the ISO 8601 standard for its defaults in parsing and generating strings. For period/duration time, this means the PnYnMnDTnHnMnS format. The P means "period" and the T is a separator between date and time portions.
Here is some example code in Joda-Time 2.3. Basically a couple of lines: parsePeriod & durationSum.plus seen below.
Simulate input strings.
List<String> durationStrings = new ArrayList<String>();
durationStrings.add( "11:00:00" ); // Number of hours/minutes/seconds. Not time-of-day.
durationStrings.add( "12:00:00" );
durationStrings.add( "13:00:00" ); // Expect sum of 36 hours = 11 + 12 + 13.
Define a formatter to parse those strings. Joda-Time might have such a formatter built-in, but I could not locate it. So I defined one.
PeriodFormatter formatter = new PeriodFormatterBuilder()
.appendHours()
.appendSeparator( ":" )
.appendMinutes()
.appendSeparator( ":" )
.appendSeconds()
.toFormatter();
Loop the input strings, parsing each one, then adding its duration to the sum.
Duration durationSum = Duration.ZERO; // Initializing to empty amount. Add to this in loop below.
for ( String durationString : durationStrings ) {
Period period = formatter.parsePeriod( durationString );
Duration duration = period.toStandardDuration();
durationSum = durationSum.plus( duration );
System.out.println( "period: " + period );
System.out.println( "duration: " + duration );
}
System.out.println( "durationSum: " + durationSum );
System.out.println( "durationSum as Period: " + durationSum.toPeriod() );
When run…
period: PT11H
duration: PT39600S
period: PT12H
duration: PT43200S
period: PT13H
duration: PT46800S
durationSum: PT129600S
durationSum as Period: PT36H

How to get time in 12hr format from a long value in java

I have a long value which have values as given bellow,
e.g.
timeInLong = 1000 (which means 10:00 AM)
timeInLong = 1337 (which means 01:37 PM)
I need a smart way to convert above types of values and get time as 10:00AM and 01:37PM in string format.
Can someone please tell me how to do this?
Code -
Long timeInLong = 1000l;
SimpleDateFormat dateFormat = new SimpleDateFormat("HHmm");
Date date = dateFormat.parse(Long.toString(timeInLong));
System.out.println(new SimpleDateFormat("hh:mm a").format(date));
Result -
10:00 AM
Try:
SimpleDateFormat readerFormat = "HHmm";
SimpleDateFormat writerFormat = "hh:mma";
Date date = readerFormat.parse(Long.toString(timeInLong));
String toPrint = writerFormat.format(date);
I would do something like this:
SimpleDateFormat formatA = new SimpleDateFormat("hhmm");
SimpleDateFormat formatB = new SimpleDateFormat("hh:mm a");
Date intermediate = formatA.parse(String.valueOf(1337));
String result = formatB.format(intermediate);
int timeInLong = 1337;
Calendar c = Calendar.getInstance();
c.set(Calendar.MINUTE, timeInLong % 100);
c.set(Calendar.HOUR_OF_DAY, timeInLong / 100);
System.out.println(new SimpleDateFormat("HH:mm a", Locale.US).format(c.getTime()));
Alternative and efficient oneliner if you want to avoid the SimpleDateFormat import:
String toTimeString(long time) {
return ((time < 1300) ? time / 100 : time / 100 - 12)
+ ":" + time % 100
+ ((time < 1200) ? " AM" : " PM");
}
It seams too easy, but what about:
int hours = timeInLong / 100;
int minutes = timeInLong % 100;
boolean isPM = false;
if (hours > 12) {
isPM = true
}
if (hours > 13) {
hours -= 12;
}
String result = String.format("%02d:%02d %s", hours, minutes, (isPM ? "PM" : "AM"));
Did I miss something?

How can I calculate a time difference in Java?

I want to subtract two time periods say 16:00:00 from 19:00:00. Is there any Java function for this? The results can be in milliseconds, seconds, or minutes.
Java 8 has a cleaner solution - Instant and Duration
Example:
import java.time.Duration;
import java.time.Instant;
...
Instant start = Instant.now();
//your code
Instant end = Instant.now();
Duration timeElapsed = Duration.between(start, end);
System.out.println("Time taken: "+ timeElapsed.toMillis() +" milliseconds");
String time1 = "16:00:00";
String time2 = "19:00:00";
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
Date date1 = format.parse(time1);
Date date2 = format.parse(time2);
long difference = date2.getTime() - date1.getTime();
Difference is in milliseconds.
I modified sfaizs post.
To get pretty timing differences, then
// d1, d2 are dates
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.");
Java 8
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTime1= LocalDateTime.parse("2014-11-25 19:00:00", formatter);
LocalDateTime dateTime2= LocalDateTime.parse("2014-11-25 16:00:00", formatter);
long diffInMilli = java.time.Duration.between(dateTime1, dateTime2).toMillis();
long diffInSeconds = java.time.Duration.between(dateTime1, dateTime2).getSeconds();
long diffInMinutes = java.time.Duration.between(dateTime1, dateTime2).toMinutes();
Just like any other language; convert your time periods to a unix timestamp (ie, seconds since the Unix epoch) and then simply subtract.
Then, the resulting seconds should be used as a new unix timestamp and read formatted in whatever format you want.
Ah, give the above poster (genesiss) his due credit, code's always handy ;)
Though, you now have an explanation as well :)
import java.util.Date;
...
Date d1 = new Date();
...
...
Date d2 = new Date();
System.out.println(d2.getTime()-d1.getTime()); //gives the time difference in milliseconds.
System.out.println((d2.getTime()-d1.getTime())/1000); //gives the time difference in seconds.
and, to show in a nicer format, you can use:
DecimalFormat myDecimalFormatter = new DecimalFormat("###,###.###");
System.out.println(myDecimalFormatter.format(((double)d2.getTime()-d1.getTime())/1000));
Besides the most common approach with Period and Duration objects you can widen your knowledge with another way for dealing with time in Java.
Advanced Java 8 libraries.
ChronoUnit for Differences.
ChronoUnit is a great way to determine how far apart two Temporal values are. Temporal includes LocalDate, LocalTime and so on.
LocalTime one = LocalTime.of(5,15);
LocalTime two = LocalTime.of(6,30);
LocalDate date = LocalDate.of(2019, 1, 29);
System.out.println(ChronoUnit.HOURS.between(one, two)); //1
System.out.println(ChronoUnit.MINUTES.between(one, two)); //75
System.out.println(ChronoUnit.MINUTES.between(one, date)); //DateTimeException
First example shows that between truncates rather than rounds.
The second shows how easy it is to count different units.
And the last example reminds us that we should not mess up with dates and times in Java :)
public class timeDifference {
public static void main(String[] args) {
try {
Date startTime = Calendar.getInstance().getTime();
Thread.sleep(10000);
Date endTime = Calendar.getInstance().getTime();
long difference = endTime.getTime() - startTime.getTime();
long differenceSeconds = difference / 1000 % 60;
long differenceMinutes = difference / (60 * 1000) % 60;
long differenceHours = difference / (60 * 60 * 1000) % 24;
long differenceDays = difference / (24 * 60 * 60 * 1000);
System.out.println(differenceDays + " days, ");
System.out.println(differenceHours + " hours, ");
System.out.println(differenceMinutes + " minutes, ");
System.out.println(differenceSeconds + " seconds.");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
I found this cleaner.
Date start = new Date();
//Waiting for 10 seconds
Thread.sleep(10000);
Date end = new Date();
long diff = end.getTime() - start.getTime();
String TimeTaken = String.format("[%s] hours : [%s] mins : [%s] secs",
Long.toString(TimeUnit.MILLISECONDS.toHours(diff)),
TimeUnit.MILLISECONDS.toMinutes(diff),
TimeUnit.MILLISECONDS.toSeconds(diff));
System.out.println(String.format("Time taken %s", TimeTaken));
Output
Time taken [0] hours : [0] mins : [10] secs
The painful way is to convert to millis and do the subtraction and then back to whatever seconds or so you want. The better way is to use JodaTime.
String start = "12:00:00";
String end = "02:05:00";
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
Date date1 = format.parse(start);
Date date2 = format.parse(end);
long difference = date2.getTime() - date1.getTime();
int minutes = (int) TimeUnit.MILLISECONDS.toMinutes(difference);
if(minutes<0)minutes += 1440;
Now minutes will be the correct duration between two time (in minute).
import java.text.SimpleDateFormat;
import java.util.Date;
public class Main {
public static void main(String[] args) throws Exception {
String time1 = "12:00:00";
String time2 = "12:01:00";
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
Date date1 = format.parse(time1);
Date date2 = format.parse(time2);
long difference = date2.getTime() - date1.getTime();
System.out.println(difference/1000);
}
}
It throws exception handles parsing exceptions.
This can be easily done using Java 8 LocalTime;
String time1 = "16:00:00";
String time2 = "19:00:00";
long seconds = Duration.between(LocalTime.parse(time1), LocalTime.parse(time2)).getSeconds()
Duration also supports toMillis(), toMinutes() which can be used in place of getSeconds() to get milliseconds or minutes
Аlternative option if time from different days is taken, for example: 22:00 and 01:55.
public static long getDiffTime(Date date1, Date date2){
if (date2.getTime() - date1.getTime() < 0) {// if for example date1 = 22:00, date2 = 01:55.
Calendar c = Calendar.getInstance();
c.setTime(date2);
c.add(Calendar.DATE, 1);
date2 = c.getTime();
} //else for example date1 = 01:55, date2 = 03:55.
long ms = date2.getTime() - date1.getTime();
//235 minutes ~ 4 hours for (22:00 -- 01:55).
//120 minutes ~ 2 hours for (01:55 -- 03:55).
return TimeUnit.MINUTES.convert(ms, TimeUnit.MILLISECONDS);
}
Try this:
public String timeDifference8(String startTime, String endTime) {
LocalTime initialTime = LocalTime.parse(startTime);
LocalTime finalTime =LocalTime.parse(endTime);
StringJoiner joiner = new StringJoiner(":");
long hours = initialTime.until( finalTime, ChronoUnit.HOURS);
initialTime = initialTime.plusHours( hours );
long minutes = initialTime.until(finalTime, ChronoUnit.MINUTES);
initialTime = initialTime.plusMinutes( minutes );
long seconds = initialTime.until( finalTime, ChronoUnit.SECONDS);
joiner.add(String.valueOf(hours));
joiner.add(String.valueOf(minutes));
joiner.add(String.valueOf(seconds));
return joiner.toString();
}
import java.sql.*;
class Time3 {
public static void main(String args[]){
String time1 = "01:03:23";
String time2 = "02:32:00";
long difference ;
Time t1 = Time.valueOf(time1);
Time t2 = Time.valueOf(time2);
if(t2.getTime() >= t1.getTime()){
difference = t2.getTime() - t1.getTime() -19800000;
}
else{
difference = t1.getTime() - t2.getTime() -19800000;
}
java.sql.Time time = new java.sql.Time(difference);
System.out.println(time);
}
}
/*
* Total time calculation.
*/
private void getTotalHours() {
try {
// TODO Auto-generated method stub
if (tfTimeIn.getValue() != null && tfTimeOut.getValue() != null) {
Long min1 = tfTimeOut.getMinutesValue();
Long min2 = tfTimeIn.getMinutesValue();
Long hr1 = tfTimeOut.getHoursValue();
Long hr2 = tfTimeIn.getHoursValue();
Long hrsTotal = new Long("0");
Long minTotal = new Long("0");
if ((hr2 - hr1) == 1) {
hrsTotal = (long) 1;
if (min1 != 0 && min2 == 0) {
minTotal = (long) 60 - min1;
} else if (min1 == 0 && min2 != 0) {
minTotal = min2;
} else if (min1 != 0 && min2 != 0) {
minTotal = min2;
Long minOne = (long) 60 - min1;
Long minTwo = min2;
minTotal = minOne + minTwo;
}
if (minTotal >= 60) {
hrsTotal++;
minTotal = minTotal % 60;
}
} else if ((hr2 - hr1) > 0) {
hrsTotal = (hr2 - hr1);
if (min1 != 0 && min2 == 0) {
minTotal = (long) 60 - min1;
} else if (min1 == 0 && min2 != 0) {
minTotal = min2;
} else if (min1 != 0 && min2 != 0) {
minTotal = min2;
Long minOne = (long) 60 - min1;
Long minTwo = min2;
minTotal = minOne + minTwo;
}
if (minTotal >= 60) {
minTotal = minTotal % 60;
}
} else if ((hr2 - hr1) == 0) {
if (min1 != 0 || min2 != 0) {
if (min2 > min1) {
hrsTotal = (long) 0;
minTotal = min2 - min1;
} else {
Notification.show("Enter A Valid Time");
tfTotalTime.setValue("00.00");
}
}
} else {
Notification.show("Enter A Valid Time");
tfTotalTime.setValue("00.00");
}
String hrsTotalString = hrsTotal.toString();
String minTotalString = minTotal.toString();
if (hrsTotalString.trim().length() == 1) {
hrsTotalString = "0" + hrsTotalString;
}
if (minTotalString.trim().length() == 1) {
minTotalString = "0" + minTotalString;
}
tfTotalTime.setValue(hrsTotalString + ":" + minTotalString);
} else {
tfTotalTime.setValue("00.00");
}
}
catch (Exception e) {
e.printStackTrace();
}
}
class TimeCalculator
{
String updateTime;
public TimeCalculator(String time)
{
// Time should be in 24 hours format like 15/06/2016 17:39:20
this.updateTime = time;
}
public String getTimeDifference()
{
String td = null;
// Get Current Time
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
Date currentDate = new Date();
Calendar calendar = new GregorianCalendar();
calendar.setTime(currentDate);
int c_year = calendar.get(Calendar.YEAR);
int c_month = calendar.get(Calendar.MONTH) + 1;
int c_day = calendar.get(Calendar.DAY_OF_MONTH);
// Get Editing Time
Date edit_date = sdf.parse(updateTime);
Calendar edit_calendar = new GregorianCalendar();
edit_calendar.setTime(edit_date);
int e_year = edit_calendar.get(Calendar.YEAR);
int e_month = edit_calendar.get(Calendar.MONTH) + 1;
int e_day = edit_calendar.get(Calendar.DAY_OF_MONTH);
if(e_year == c_year && e_month == c_month && e_day == c_day)
{
int c_hours = calendar.get(Calendar.HOUR_OF_DAY);
int c_minutes = calendar.get(Calendar.MINUTE);
int c_seconds = calendar.get(Calendar.SECOND);
int e_hours = edit_calendar.get(Calendar.HOUR_OF_DAY);
int e_minutes = edit_calendar.get(Calendar.MINUTE);
int e_seconds = edit_calendar.get(Calendar.SECOND);
if(c_hours == e_hours && c_minutes == e_minutes && c_seconds == e_seconds)
{
td = "just now";
return td;
}
else if(c_hours == e_hours && c_minutes == e_minutes)
{
int d_seconds = c_seconds-e_seconds;
td = String.valueOf(d_seconds);
td = td + " seconds ago";
return td;
}
else if(c_hours == e_hours && c_minutes != e_minutes)
{
int d_minutes = c_minutes-e_minutes;
int d_seconds;
if(c_seconds>e_seconds)
{
d_seconds = c_seconds-e_seconds;
}
else
{
d_seconds = e_seconds-c_seconds;
}
td = "00:" + String.valueOf(d_minutes) + ":" + String.valueOf(d_seconds) + " ago";
return td;
}
else
{
int d_minutes, d_seconds, d_hours;
d_hours = c_hours-e_hours;
if(c_minutes>e_minutes)
{
d_minutes = c_minutes - e_minutes;
}
else
{
d_minutes = e_minutes - c_minutes;
}
if(c_seconds>e_seconds)
{
d_seconds = c_seconds - e_seconds;
}
else
{
d_seconds = e_seconds - c_seconds;
}
td = String.valueOf(d_hours) + ":" + String.valueOf(d_minutes) + ":" + String.valueOf(d_seconds) + " ago";
return td;
}
}
else if(e_year == c_year && e_month == c_month && c_day == e_day+1)
{
td = "yesterday";
return td;
}
else
{
td = updateTime;
return td;
}
}
}
using Instant
Instant start = Instant.parse("2017-10-03T10:15:30.00Z");
Instant end = Instant.parse("2017-10-04T11:35:31.00Z");
long duration = Duration.between(start, end).toMillis();
long minutes = TimeUnit.MILLISECONDS.toMinutes(duration)*60;
String time = String.format("%02d hours, %02d min, %02d sec",
TimeUnit.MILLISECONDS.toHours(duration),
TimeUnit.MILLISECONDS.toMinutes(duration) - TimeUnit.MILLISECONDS.toHours(duration) * 60,
TimeUnit.MILLISECONDS.toSeconds(duration) - minutes);
;
System.out.println("time = " + time);

Categories

Resources