This question already has answers here:
Calculate Difference between two times in Android
(7 answers)
Closed 9 years ago.
I have two times, a start and a stop time, in the format of 05:00 (HH:MM). I need the difference between the two times.Suppose if start time is 05:00 and end time is 15:20, then how do I calculate the time difference between two which will be 10 Hours 20 minutes. Should I convert them into datetime object and use the milliseconds to get the time difference or is there any better approach to do this?
Use Joda Time. You want the LocalTime type to represent your start and stop times, then create a Period between them.
I don't know whether there's a cut-down version of Joda Time available for Android (it may be a little big otherwise, if your app is otherwise small) but it will make things much simpler than using the plain JDK libraries. You can do that, of course - converting both into milliseconds, finding the difference and then doing the arithmetic. It would just be relatively painful :(
Sample code:
import org.joda.time.*;
public class Test {
public static void main(String args[]) {
LocalTime start = new LocalTime(5, 0);
LocalTime end = new LocalTime(15, 20);
Period period = new Period(start, end, PeriodType.time());
System.out.println(period.getHours()); // 10
System.out.println(period.getMinutes()); // 20
}
}
And just using JDK classes:
import java.util.*;
import java.util.concurrent.*;
import java.text.*;
public class Test {
public static void main(String args[]) throws ParseException {
DateFormat format = new SimpleDateFormat("HH:mm", Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
Date start = format.parse("05:00");
Date end = format.parse("15:20");
long difference = end.getTime() - start.getTime();
long hours = TimeUnit.MILLISECONDS.toHours(difference);
long minutes = TimeUnit.MILLISECONDS.toMinutes(difference) % 60;
System.out.println("Hours: " + hours);
System.out.println("Minutes: " + minutes);
}
}
Note that this assumes that end is after start - you'd need to work out the desired results for negative times.
Related
This question already has answers here:
LocalTime() difference between two times
(2 answers)
Closed 3 years ago.
I've looked at just about all the other posts pertaining to my question without finding a similar issue as mine.
I'm trying to get the time between two fields using this code.
LocalTime timeFrom = LocalTime.parse("16:00");
LocalTime timeTo = LocalTime.parse("00:00");
System.out.println(Duration.between(timeFrom,timeTo).toHours());
The issue I'm having is that the print out is negative 16 hours. What I want to accomplish is to get the amount of time from 4pm (which is 1600) to 12am (which is 00:00).
The result that I'm looking for would be 8 hours.
I have an idea of taking 1 minute from the 00:00, then getting the duration between those then just simply adding the 1 minute back to it, but I was thinking there must be an easier way.
After pondering I feel like I was looking for a programmer solution instead of a simple one...
The answer to this is just adding 24 hours back to the negative result!
LocalTime timeFrom = LocalTime.parse("16:00");
LocalTime timeTo = LocalTime.parse("00:00");
long elapsedMinutes = Duration.between(timeFrom, timeTo).toMinutes();
//at this point Duration for hours is -16.
//checking condition
if(timeTo.toString().equalsIgnoreCase("00:00")){
//condition met, adding 24 hours(converting to minutes)
elapsedMinutes += (24 * 60);
}
long elapsedHours = elapsedMinutes / 60;
long excessMinutes = elapsedMinutes % 60;
System.out.println("Hours: " + elapsedHours);
System.out.println("Minutes: " + excessMinutes);
I propose to check if the result is negative, then you don't limit the code to check for exact string equality, and 00:01 will still come out 8 hours:
import java.time.Duration;
import java.time.LocalTime;
public class StackOverflowTest {
public static void main(String[] args) {
String from = "16:00";
String to = "00:01";
LocalTime timeFrom = LocalTime.parse(from);
LocalTime timeTo = LocalTime.parse(to);
Duration duration = Duration.between(timeFrom,timeTo);
if (duration.isNegative()) duration = duration.plusDays(1);
System.out.println(duration.toHours());
}
/*
Prints:
8
*/
}
Or perhaps or more reader-friendly option:
...snip
Duration duration;
if (timeFrom.isBefore(timeTo)) {
duration = Duration.between(timeFrom,timeTo);
} else {
duration = Duration.between(timeFrom,timeTo).plusDays(1);
}
This question already has answers here:
Parse date or datetime both as LocalDateTime in Java 8
(4 answers)
Closed 3 years ago.
I'm using a Java DateTimeFormatter in order to parse dates and datetimes. I construct it with a DateTimeFormatterBuilder dtfb, and then try to get epoch seconds from it as follows:
dtfb.toFormatter().withZone(ZoneId.of("America/New_York"))
.parse(timeStr)
.getLong(ChronoField.INSTANT_SECONDS)
However, this only works if timeStr is specific enough to identify one particular second. For example, this works: "1997.10.10 23:45:23", but this does not "1997.10.10", as there's no hour minute second information. I'm wondering if there's a way in Java to systematically "round down" and return the first timestamp that fits the constraints. For example, in this failing case I'd want the answer to be the timestamp at "1997.10.10 00:00:00". Basically just keep filling in zeros in smaller and smaller time units until it's specific enough to give me a second. Is this possible?
I think this might be what you want to do. I tried with ChronoField.SECOND_OF_DAY, but that results in a java.time.DateTimeException: Conflict found: HourOfDay 23 differs from HourOfDay 0 while resolving when using your example with a timestamp.
Note that you must start the building with the formatting string. If you use .parseDefaulting prior to .appendPattern, you get a java.time.format.DateTimeParseException.
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.ZoneId;
class Testing {
public static void main(String[] args) {
DateTimeFormatterBuilder dtfb =
new DateTimeFormatterBuilder()
.appendPattern("yyyy.dd.MM[ HH:mm:ss]")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0);
String timeStr = "1997.10.10";
// String timeStr = "1997.10.10 00:00:01";
// String timeStr = "1997.10.10 23:45:23";
Long instant =
dtfb.toFormatter().withZone(ZoneId.of("America/New_York"))
.parse(timeStr)
.getLong(ChronoField.INSTANT_SECONDS);
System.out.println(instant);
}
}
This question already has answers here:
How to calculate "time ago" in Java?
(33 answers)
Closed 7 years ago.
I want to display how long ago something happened. For example
24 minutes ago //discard seconds
3 hours ago //discard minutes
5 days ago // discard hours
3 weeks ago // discard days
All I have is a long timestamp and so I am free to use java.util.Date or jodatime or whatever other Time android uses. I am having such a hard time getting it right. I try to use jodatime with minus but I can't quite get the right answer yet.
One approach is for me to do the whole thing myself: first subtract my timestamp from now and then do some arithmetics. But I would rather avoid that route if possible.
Android provides the utility class DateUtils for all such requirements. If I've understood your requirement correctly, you need to use the DateUtils#getRelativeTimeSpanString() utility method.
From the docs for
CharSequence getRelativeTimeSpanString (long time, long now, long minResolution)
Returns a string describing 'time' as a time relative to 'now'. Time spans in the past are formatted like "42 minutes ago". Time spans in the future are formatted like "In 42 minutes".
You'll be passing your timestamp as time and System.currentTimeMillis() as now. The minResolution specifies the minimum timespan to report.
For example, a time 3 seconds in the past will be reported as "0 minutes ago" if this is set to MINUTE_IN_MILLIS. Pass one of 0, MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS, WEEK_IN_MILLIS
You can use the following code :
public class TimeAgo {
public static final List<Long> times = Arrays.asList(
TimeUnit.DAYS.toMillis(365),
TimeUnit.DAYS.toMillis(30),
TimeUnit.DAYS.toMillis(1),
TimeUnit.HOURS.toMillis(1),
TimeUnit.MINUTES.toMillis(1),
TimeUnit.SECONDS.toMillis(1) );
public static final List<String> timesString = Arrays.asList("year","month","day","hour","minute","second");
public static String toDuration(long duration) {
StringBuffer res = new StringBuffer();
for(int i=0;i< Lists.times.size(); i++) {
Long current = Lists.times.get(i);
long temp = duration/current;
if(temp>0) {
res.append(temp).append(" ").append( Lists.timesString.get(i) ).append(temp > 1 ? "s" : "").append(" ago");
break;
}
}
if("".equals(res.toString()))
return "0 second ago";
else
return res.toString();
}
}
Just call the toDuration() method with your long timestamp as parameter.
You can also use DateUtils.getRelativeTimeSpanString() . You can read the documentation here Date Utils
I'm developing an application where the user sends a time duration in this format "YY : MM : DD : HH : mm : ss" ex . 1yr 2months 3days 4hrs 5mins 6sec will be specified as
1:2:3:4:5:6
From this value , i have to convert the duration into seconds. I want to know whether there is any inbuilt java class to specify time duration in this format?
The ISO 8601 standard defines a string representation for a span of time as PnYnMnDTnHnMnS where P marks the beginning and T separates the date portion from the time portion.
For example, "P3Y6M4DT12H30M5S" represents a duration of "three years, six months, four days, twelve hours, thirty minutes, and five seconds".
An hour and a half would be PT1H30M.
The Joda-Time library has the Period class that both parses and generates that format by default.
Search StackOverflow for more.
Java-8 introduced java.time.Duration and java.time.Period as part of JSR-310 implementation but there has been a long wait for a type combining period and duration as specified at ISO_8601#Durations.
However, javax.xml.datatype.Duration has been there since Java-6 and we can use this to achieve what you want to. The assumption is that your text is always in the format, y:M:d:H:m:s e.g. 1:2:3:4:5:6.
Demo:
import java.util.Calendar;
import java.util.concurrent.TimeUnit;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
public class Main {
public static void main(String[] args) throws DatatypeConfigurationException {
String[] durationParts = "1:2:3:4:5:6".split(":");
char[] symbols = "YMDHMS".toCharArray();
StringBuilder sb = new StringBuilder("P");
for (int i = 0; i < durationParts.length; i++) {
sb.append(durationParts[i]).append(symbols[i]);
if (i == 2) {
sb.append("T");
}
}
String strIso8601Duration = sb.toString();
System.out.println(strIso8601Duration);
Duration duration = DatatypeFactory.newInstance().newDuration(strIso8601Duration);
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
long seconds = TimeUnit.MILLISECONDS.toSeconds(duration.getTimeInMillis(calendar));
System.out.println(seconds);
}
}
Output:
P1Y2M3DT4H5M6S
36907506
This question already has an answer here:
Closed 12 years ago.
Possible Duplicate:
warning message/pop out for date/time
I have a form where a user need to enter date and time (2 different fields) and the time cannot be in future. It can either be current time or time in past only to 12 hours before. So I want to add a warning message when the time is older than 12 hours. How will be the calculation of this in Java. Please help me out!
If you want Java this should work. JODA is good, but it is another lib dependency.
` import java.util.Calendar;
import junit.framework.TestCase;
import static java.lang.System.out;
public class DateCheck extends TestCase {
public void testCheckBefore(){
//Gets the current time
Calendar c = Calendar.getInstance();
//Let's make it 13:00 just to make the example simple.
c.set(Calendar.HOUR_OF_DAY, 13);
out.println(c.getTime());
Calendar old = Calendar.getInstance();
old.set(Calendar.HOUR_OF_DAY, 0);
if(old.after(c)) {
throw new IllegalArgumentException("You entered a date in the future");
}
assertTrue(olderThanTwelveHours(c, old));
// Let's change to 5 in the morning.
old.set(Calendar.HOUR_OF_DAY, 5);
assertFalse(olderThanTwelveHours(c, old));
}
private boolean olderThanTwelveHours(Calendar c, Calendar old) {
long startTime= c.getTimeInMillis();
long oldTime = old.getTimeInMillis();
long timeDiff = startTime - oldTime;
if(timeDiff > (12 * 60 * 60 * 1000)) {
out.println("You're too late");
return true;
}
return false;
}
}`
You are basically wanting to calculate the hours difference between 2 dates. You can easily do that using JodaTime hoursBetween method.