Calculating difference in minutes from two timestamps - java

I have two unix time stamps like
currentTimestamp=1213083655;
previousTimestamp=1213083715;
How do I calculate the number of minutes between these two timestamps. Or in other words difference in minutes between both these timestamps.
Currently what I am doing is
(previousTimestamp-currentTimestamp)%60
which is the right away to go because timestamps are time in seconds and doing this will return minutes . But only problem is that when the difference is multiple of 60 then the remainder is 0 and therefore the calculation gives a result of 0 minutes which is wrong. Like in the case of above numbers difference is 60 so result is 0. So what's the best way to do this?
Regards
Ahmar

Use division instead of modulo.
% is the modulo command. You're not getting the number of minutes. You're getting the remaining number of seconds after calculating whole minutes.
/ is the division command. This is what you are looking for.
(previousTimestamp-currentTimestamp)/60
This is the command you want.

You don't want a modulo, but a division. Let's say the difference is 150 seconds. You need to divide it by 60 to find the difference in minutes: 2.5:
double differenceInMinutes = (currentTimestamp - previousTimestamp) / 60d;

You can use JodaTime in your project for date/time operations. To find out the gap between two DateTime in minutes:
DateTime now = DateTime.now();
DateTime dateTime = now.plusMinutes(10);
Minutes minutes = Minutes.minutesBetween(now, dateTime);
System.out.println(minutes.getMinutes());
If you use Maven, you can add JodaTime adding following dependency:
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.3</version>
</dependency>

Why do you use a %?
% gives you module,that not what you're looking for.
/ is what you have to use. A simple division.

The answer by Erhan Bagdemir is correct.
Here is his idea using the Joda-Time library, but adapted to literally solve the problem with values given by the question.
Using Joda-Time 2.3 and Java 7.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// We do not need time zones if our only goal is to count minutes. But realistically we are probably doing other work as well.
// Better to specify a time zone explicitly rather than rely on default.
// Time Zone list… http://joda-time.sourceforge.net/timezones.html (not quite up-to-date, read page for details)
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
// Convert Unix time (seconds since epoch of 1970) to Joda-Time DateTime count of milliseconds since same epoch.
// Note the use of the 'long' type rather than the usual 'int', a common error when working with millisecond counts since epoch.
// Notice the hard-coded "L" on the numbers.
long start = ( 1213083655L * 1000L );
long stop = ( 1213083715 * 1000L );
DateTime dateTimeStart = new DateTime( start, timeZone );
DateTime dateTimeStop = new DateTime( stop, timeZone );
int minutesElapsed = Minutes.minutesBetween( dateTimeStart, dateTimeStop ).getMinutes();
Dump to console…
System.out.println( "dateTimeStart: " + dateTimeStart );
System.out.println( "dateTimeStop: " + dateTimeStop );
System.out.println( "minutesElapsed: " + minutesElapsed );
When run…
dateTimeStart: 2008-06-10T09:40:55.000+02:00
dateTimeStop: 2008-06-10T09:41:55.000+02:00
minutesElapsed: 1

Related

Java millis time with hourly resolution

How do I get java time millis in UTC ignoring the minutes and seconds.
For instance :
If it is October 10 2019, 1:10:59 AM , it should get the Time or millis for
October 10 2019, 1 AM.
Summary:
Instant
.now()
.truncatedTo(
ChronoUnit.HOURS
)
.toEpochMilli()
1570600800000
java.time, the modern Java date and time API has got exactly the method you need: many of the classes have a truncatedTo method for needs like yours.
Instant now = Instant.now();
System.out.println("Rough milliseconds: " + now.toEpochMilli());
Instant currentWholeHour = now.truncatedTo(ChronoUnit.HOURS);
System.out.println("Milliseconds ignoring minutes and seconds: "
+ currentWholeHour.toEpochMilli());
When running this snippet just now the output was:
Rough milliseconds: 1570604053787
Milliseconds ignoring minutes and seconds: 1570600800000
I know very well that the first line is what you asked not to have. I only included it for you to see the difference.
The truncation happens in UTC. If you are in a time zone whose offset is not a whole number of hours from UTC, the results may not be as you had expected. Examples of such time zones include Asia/Kathmandu, America/St_Johns some of the year also Australia/Lord_Howe.
Link: Oracle tutorial: Date Time
You can use LocalDate#atTime:
LocalDate.now().atTime(LocalDateTime.now().getHour(), 0, 0);
This will give you current date with hour and minutes and seconds set to 0.
And to get milliseconds in UTC:
LocalDate.now().atTime(LocalDateTime.now().getHour(), 0, 0).toInstant(ZoneOffset.UTC).toEpochMilli();
Jon Skeet notices, that calling now might give unexpected results in corner cases. To be sure, we can call it once and then convert it to LocalDate with mentioned solution:
var currentTime = LocalDateTime.now();
var currentDate = currentTime.toLocalDate();
Or the other way around - get LocalDate first and use LocalDate#atStartOfDay.
Given that you're interested in UTC milliseconds, and there are a whole number of milliseconds per hour, you can do this with simple arithmetic. For most calendrical computations I really wouldn't recommend that, but in this case I think it's the simplest approach. Something like this:
private static final long MILLISECONDS_PER_HOUR = TimeUnit.HOURS.toMillis(1);
// Injecting a clock makes the method testable. You can use Clock.systemUTC()
// for the system clock.
public static long truncateMillisToHour(Clock clock) {
long millisSinceEpoch = clock.millis();
// Truncate to the nearest hour
long hoursSinceEpoch = millisSinceEpoch / MILLISECONDS_PER_HOUR;
// Then multiply up again
return hoursSinceEpoch * MILLISECONDS_PER_HOUR;
}
Note that if the clock is for before the epoch, this will round up to the nearest hour, but if you're taking the genuine "current time" then that's unlikely to be a problem.
(I wrote this answer before seeing Ole V.V.'s answer with truncatedTo, which is a very nice approach.)

JODA DateTime provide a correct date and time as per daylight saving approach? or we need to add/subtract difference hour count from date [duplicate]

just to verify this: I have this lame and brain dead method to calculate the time zone offset for my current location. I wonder if I need to adjust it when Day Light Saving time comes into question (currently we have Winter Time at my location, CET time zone, so it's hard to verify).
// The local time zone's offset
private int getLocalOffset() {
DateTimeZone defaultZone = DateTimeZone.getDefault();
return defaultZone.getOffset(null) / 1000 / 60 / 60;
}
Thanks for any hint.
Time zones and Daylight Saving Time are a nightmare. You certainly shouldn't take on this task yourself. Let Joda-Time do the heavy lifting.
See this answer to similar question, Using Joda time to get UTC offset for a given date and timezone. The class DateTimeZone offers a getOffset() method.
Example source code in Joda-Time 2.3 in Java 7…
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
org.joda.time.DateTimeZone californiaTimeZone = org.joda.time.DateTimeZone.forID("America/Los_Angeles");
org.joda.time.DateTime now = new org.joda.time.DateTime(californiaTimeZone);
int millisecondOffsetToAddToUtcToGetLocalTime = californiaTimeZone.getOffset( now );
System.out.println( "millisecondOffsetToAddToUtcToGetLocalTime: " + millisecondOffsetToAddToUtcToGetLocalTime );
// Note the casting to doubles to avoid integer truncation. Time zone offsets are NOT always whole hours.
System.out.println( "Offset in decimal hours: " + (double)millisecondOffsetToAddToUtcToGetLocalTime / 1000d / 60d / 60d );
When run at 2013-11-20T01:03:56.464-08:00…
millisecondOffsetToAddToUtcToGetLocalTime: -28800000
millisecondOffsetToAddToUtcToGetLocalTime in hours: -8.0
IMPORTANT That number format -8.0 is incorrect for an offset. Must be either:
-08:00 with the colon and double digits (padded with leading zero).
-08 with leading zero.
Normally, Joda time will take care of DST by itself, so you don't have to worry about it. However, I notice that you are passing null to getOffset(). Given that the time zone offset depends on the date, you really should be passing the date/time at which you are calculating the offset, or you're going to get wrong results.
Also as mentionned in my previous comment: Be aware that some timezones have an offset that isn't a whole number of hours. India for example is at GMT +5:30
Yes, that's fine. To verify that it is correct - instead of passing null pass in a DateTime object to DateTimeZone.getOffset - set the datetime to sometime in summer when you know DST is in effect - you should see the offset value change.

Add a Double variable representing minute into a Date in Java

I have a Origin-Destination matrix representing the elapsed time between 2 point in minute. I wonder what is the best way to add the elapsed time to a Date.
Date clock;
SimpleDateFormat reqDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
clock = reqDF.parse(line[25]);
Double distance = distDB.find_distance(O, D, mode, facility_id);
Date current_time = clock + distance;
Does it makes more easier if I use a Calendar type instead of Date ?
Thanks
tl;dr
Instant.parse( "2016-12-23T01:23:45Z" )
.plusNanos( Math.round(
yourNumberOfMinutesAsDouble *
TimeUnit.MINUTES.toNanos( 1 ) )
)
Avoid old date-time classes.
Actually, you should using neither java.util.Date nor java.util.Calendar. These old legacy classes are notoriously troublesome, confusing, and flawed. Now supplanted by the java.time classes.
For the old classes, the Answer by Jireugi is correct. For java.time classes, read on.
Avoid using a fractional number for elapsed time
Not a good idea using a double or Double to represent elapsed time. Firstly, that type uses floating-point technology which trades away accuracy for speed of execution. So you will often have extraneous extra digits to the right of your decimal fraction.
Secondly, this is an awkward way to handle time, given that we have sixty seconds to a minute, and sixty minutes to an hour, and so on.
In Java, use the Period or Duration classes. See Oracle Tutorial.
In text, use the standard ISO 8601 format PnYnMnDTnHnMnS where P marks the beginning and T separates the years-months-days from the hours-minutes-seconds. So two and a half minutes would be PT2M30S.
Nanoseconds
If we must work with the Double as a number of minutes for elapsed time, let’s convert from your fractional decimal number to a whole number (integer).
Note that the old legacy date-time classes are limited to a resolution of milliseconds while the java.time classes can go as fine as nanoseconds. So we want to convert your Double to a whole number of nanoseconds.
Rather than hard-code a magic number of the number of nanoseconds in a minute for this calculation, let's use the TimeUnit enum. That class can calculate the number of nanoseconds in a minute for us ( 60 * 1_000_000_000L ).
Finally, the Math.round function returns the closest long to the argument, with ties rounding to positive infinity.
long nanoseconds = Math.round(
yourNumberOfMinutesAsDouble *
TimeUnit.MINUTES.toNanos( 1 )
);
Instant
If working with date-time values in UTC, use the Instant class. Each Instant represents a moment on the timeline in UTC with a resolution of nanoseconds.
Instant Instant.parse( "2016-12-23T01:23:45Z" )
Instant future = Instant.plusNanos( nanoseconds );
Duration
Rather than passing around a Double as your elapsed time, I strongly suggest you pass around Duration objects.
Duration duration = Duration.ofNanos( Math.round( yourNumberOfMinutesAsDouble * TimeUnit.MINUTES.toNanos( 1 ) ) );
You can do math with a Duration such as plus and minus.
Instant instant = Instant.parse( "2016-12-23T01:23:45Z" )
Instant future = instant.plus( duration );
You can generate a String representation of the Duration in standard ISO 8601 format such as PT8H6M12.345S by merely calling toString. And Duration can parse such strings as well.
String output = duration.toString(); // PT8H6M12.345S
…or going the other direction…
Duration duration = Duration.parse( "PT8H6M12.345S" );
You could try this using Math.round:
Date clock;
SimpleDateFormat reqDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
clock = reqDF.parse(line[25]);
Double distance = distDB.find_distance(O, D, mode, facility_id);
long clockTimeMs = clock.getTime();
long distTimeInMs = Math.round(distance * 60000);
Date current_time = new Date(clockTimeMs + distTimeInMs);
Here the Date gets converted into a milliseconds timestamp.
Since the distance is in minutes, you need to convert it also into milliseconds by multiplying it by 60 * 1000 (= 60000) before you can add it to the start time ("clock"). Finally a new Date gets created that represents the distance from the start time.
Please find details of the Date class here: https://docs.oracle.com/javase/6/docs/api/java/util/Date.html
If i understood your situation, you want to get current date, then using matrix [i, j] value (which is time - in minutes) you want to update the time to give an indication of - if you start from Origin (i), till what time you would reach to Destination (j).
I would rather use java's Calendar class. it gives you more flexibility. using 'Calendar' class, you can getTime(), which returns 'Date' type instance and then use this class to add/delete your time offset (there are methods provided by this class for such manipulations) and convert the 'Date' back to Calendar.

Best way to convert months into Milliseconds

I'm trying to convert a no of months into milliseconds
For example:
6 months = X milliseconds
There's no fixed answer to that, because it depends on which months those are - and indeed which year it is. Also potentially which time zone you're in, if you want to take account of that. (I'm assuming you mean the Gregorian calendar, by the way - different calendar systems have different month lengths.)
You could get some sort of "reasonable approximation" by assuming 365.25 days in a year, and saying that 6 months is half of that, then find out that many days in milliseconds. But it would only be an approximation.
For "how many milliseconds does it take to get from date/time X to 6 months later" you'd use an API (even Calendar would work for this particular case, although I'd recommend Joda Time or java.time in Java 8):
Set your start date/time, in the appropriate calendar and time zone
Fetch the "milliseconds since the Unix epoch" (which is easy enough to retrieve in any API) and remember it
Add 6 months
Fetch the "milliseconds since the Unix epoch" again, and subtract the earlier value from it
If you know exactly from when to when those 6 months reach, you can use a variety of ways to calculate the duration, using java.util.Calendar, JodaTime, or the JDK1.8 time API.
But if you don't have particular dates in mind, you can take an average duration for your month.
No API in the world can change that fact.
For example, the JDK1.8 time API uses this for the duration of a month in seconds: (from java.time.temporal.ChronoUnit)
MONTHS("Months", Duration.ofSeconds(31556952L / 12)),
31,556,952 is the number of a seconds in a year, based on a year that lasts 365.2425 days.
You can use the same number directly and get the same result as with the time API:
long months = 6;
long seconds = months * 31556952L / 12;
long milliseconds = seconds * 1000;
Result:
15,778,476,000
Calendar today = Calendar.getInstance();
Calendar sixMonthsAhead = Calendar.getInstance();
sixMonthsAhead.add(Calendar.MONTH, 6);
long differenceInMilis = sixMonthsAhead.getTimeInMillis() - today.getTimeInMillis();
You could also use...
sixMonthsAhead.add(Calendar.DATE, 180);
// or 183 days because 365 / 2 is approximately 183.
instead of...
sixMonthsAhead.add(Calendar.MONTH, 6);
for a more accurate result. But like Jon has mentioned, it will always vary depending on what day of the year it is.
The answer by Jon Skeet is correct.
Joda-Time
Assuming you could specify a pair of beginning and ending points on a time line, here is some example code using the Joda-Time 2.3 library.
This code grabs the current moment, adjusts to first of the month, and adjusts to first moment of that day. Then it adds 6 months. Joda-Time is smart about adding the months, taking into account leap year and various lengths of months. This span of 6 months is then represented as an Interval instance. From that we calculate the number of milliseconds. Note that count of milliseconds needs to be a long (64-bit) rather than an int (32-bit) we Java programmers more commonly use. Lastly, for fun, we see what this span of time looks like when formatted in the ISO 8601 standard’s "Duration" format.
DateTimeZone dateTimeZone = DateTimeZone.forID( "Europe/Paris" ); // Better to specify a time zone than rely on JVM’s default.
DateTime start = new DateTime( dateTimeZone ).withDayOfMonth( 1 ).withTimeAtStartOfDay();
DateTime stop = start.plusMonths( 6 );
Interval interval = new Interval( start, stop );
long milliseconds = interval.toDurationMillis(); // A long, not an int.
Period period = interval.toPeriod(); // For fun… ISO 8601 standard's Duration format.
Dump to console…
System.out.println("start: " + start );
System.out.println("stop: " + stop );
System.out.println("interval: " + interval );
System.out.println("milliseconds: " + milliseconds );
System.out.println("period: " + period );
When run…
start: 2014-04-01T00:00:00.000+02:00
stop: 2014-10-01T00:00:00.000+02:00
interval: 2014-04-01T00:00:00.000+02:00/2014-10-01T00:00:00.000+02:00
milliseconds: 15811200000
period: P6M

Sum two dates in Java

How can I add two dates in Java?
Example: The sum of "2010-01-14 19:16:17" "0000-10-03 01:10:05"
would result in "2010-11-17 20:26:22".
I know how to do it using Calendar and adding field by field.
Is any other way to sum them all (year/month/day/hour/minute/second) at once?
If you are using the Date object, you can just do:
Date d1 = ...
Date d2 = ...
long sum = d1.getTime() + d2.getTime();
Date sumDate = new Date(sum);
The code uses the .getTime() method that returns the number of milliseconds since the epoch.
Needless to say the Date class has a lot of problems and should be avoided when possible.
Do you want to sum other types instead?
Update: for Calendar, I would do the following (based on javadocs):
Calendar c1 = ...
Calendar c2 = ...
long sum = c1.getTimeInMillis() + c2.getTimeInMillis();
Calendar sumCalendar = (Calendar)c1.clone();
sumCalendar.setTimeInMillis(sum);
UPDATED: As Steve stated, this works if the Date you presented here assumes that the second date is with respect to the Java epoch. If you do want to start with year "0", then you need to account for that (by subtracting your epoch time).
Don't sum the time in millis of the two dates!
Date d1 = new Date();
Date d2 = new Date();
Date dTotal = new Date(d1.getTime() + d2.getTime());
System.out.println(dTotal); // Incorrect! Misses about 1970 years.
Just clone the Calendar and add the datetime parts one by one.
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
Calendar cTotal = (Calendar) c1.clone();
cTotal.add(Calendar.YEAR, c2.get(Calendar.YEAR));
cTotal.add(Calendar.MONTH, c2.get(Calendar.MONTH) + 1); // Months are zero-based!
cTotal.add(Calendar.DATE, c2.get(Calendar.DATE));
cTotal.add(Calendar.HOUR_OF_DAY, c2.get(Calendar.HOUR_OF_DAY));
cTotal.add(Calendar.MINUTE, c2.get(Calendar.MINUTE));
cTotal.add(Calendar.SECOND, c2.get(Calendar.SECOND));
cTotal.add(Calendar.MILLISECOND, c2.get(Calendar.MILLISECOND));
System.out.println(cTotal.getTime()); // Correct!
Needless to say, JodaTime is smarter and cleaner with this.
As always, I would recommend the Java 8 date/time APIs or Joda for date/time work, since they are much more powerful and intuitive.
You can add durations and periods to a DateTime object trivially. You can add minutes/seconds/months equally easily.
However, you can't add two dates directly, since that doesn't really make sense. This is a powerful illustration of why Joda is a help - it stops you doing stuff that you really shouldn't be doing.
tl;dr
LocalDateTime later =
LocalDateTime
.parse (
"2010-01-14 19:16:17"
.replace ( " " , "T" )
)
.plus( Period.parse ( "P10M3D" ) )
.plus( Duration.parse ( "PT1H10M5S" ) )
;
ISO 8601
The representation of a span-of-time using the same format as a moment is creating confusion. A span is not at all the same as a moment.
Instead of using YYYY-MM-DD HH-MM-SS format for a span of time, I suggest using the standard ISO 8601 format of PnYnMnDTnHnMnS. In this format, the P marks the beginning (for "Period" presumably) and the T separates the years-month-days portion from the hours-minutes-seconds portion.
Example values:
PT1H30M → One and a half hours.
P3Y6M4DT12H30M5S → Three years, six months, four days, twelve hours, thirty minutes, and five seconds.
P10M3DT1H10M5S → Your Question’s duration of 0000-10-03 01:10:05.
java.time
The Question and the other Answers use troublesome old date-time classes now outmoded by the java.time framework built into Java 8 and later. See Oracle Tutorial. Much of the java.time functionality has been back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
The java.time classes use ISO 8601 formats by default when parsing and generating Strings that represent date-time values.
The Question does not provide any time zone info, so here we use the LocalDateTime class. If we know an offset-from-UTC we would use the OffsetDateTime class, and if even better we knew a time zone, we would use the ZonedDateTime class.
Spans of time in java.time are divided amongst a pair of classes. Years-months-days are represented by the Period class, and hours-minutes-seconds are handled by the Duration class.
Combining these times, we can indeed perform date-time math. Here we add a span of time to an starting date-time to get a resulting date-time. And we do so in very few lines of code. The result is indeed that expected by the Question.
We convert the input strings to canonical ISO 8601 format by replacing the SPACE in the middle with a T.
LocalDateTime ldt = LocalDateTime.parse ( "2010-01-14 19:16:17".replace ( " " , "T" ) );
//"0000-10-03 01:10:05"
Period period = Period.parse ( "P10M3D" );
Duration duration = Duration.parse ( "PT1H10M5S" );
LocalDateTime result = ldt.plus ( period ).plus ( duration );
Compare to the result expected in the Question.
LocalDateTime expectation = LocalDateTime.parse ( "2010-11-17 20:26:22".replace ( " " , "T" ) );
Boolean isSame = result.equals ( expectation );
Dump to console.
System.out.println ( "ldt: " + ldt + " + period: " + period + " + duration: " + duration + " is result: " + result + " compared to expectation: " + expectation + " is the same: " + isSame );
ldt: 2010-01-14T19:16:17 + period: P10M3D + duration: PT1H10M5S is result: 2010-11-17T20:26:22 compared to expectation: 2010-11-17T20:26:22 is the same: true
You want to do getTimeInMillis() on both those Calendars so you'll have two honest-to-goodness long values you can add up. You can then take the sum and stash it in a new Calendar using that Calendar's setTimeInMillis() method.
Whether you want to add two Calendars as shown above or two Dates as shown in notnoop's answer is up to you, of course. The effect is similar, it just depends on what you want to do with the result. A Date is mostly just good for storing and/or converting to a String for printing out or displaying, whereas a Calendar will let you fiddle with the individual time values should you so choose.
As others have mentioned, you're committing some conceptual no-no's in using a Date or Calendar, which are meant to store "real" dates and times, e.g. ones in the 20th or 21st century, as intervals, i.e. time spans. The classes in the standard Java library don't give you really useful tools to handle this, which is why the Joda classes were developed. All the cool kids in date/time processing use those; but on the other hand that involves downloading and managing a 3rd party library.
notnoop answer is definitely correct. However, if you are going to do lots of processing of dates, times and intervals, I suggest that you look at class DateUtils in apache commons lang and at joda-time library.
JDK7 will come with better support for some of the features that joda-time provides. Just saying ... it might be a consideration if your app makes heavy usage of this stuff.
You need to define your EPOCH. The Java epoch (like Unix) is 1 Jan 1970 GMT/UTC. I assume you think you're adding ten months, 3 days and some odd hours from 1 Jan 0000 but you have a epoch offset until 1970. The maths may not necessarily work.
Use Calendar or Joda (as mentioned). If you just simply want to add a number of seconds and days (&c) then feel free to add said # of milliseconds to your first date object.
Use calendar class add method to add two dates in java.
Calendar calendar=Calendar.getInstance();
calendar.add(Calendar.Date,23);
calendar.add(Calendar.Month,13);
calendar.add(Calendar.Year,15);
By using add method in Calendar class we can add day,month,year to the existing date.
click here for complete program.
I am occasionally guilty of this practice too, storing time interval in a date object and using getTime() as suggested by notnoop.
It works. Contrary to certain opinion, it certainly works. I just ignore that the interval could be representative of an unintended date. It is a quick and dirty way for me to add an interval, say, [6 years, 6 months, 6 days, 6 hours, 6 minutes, 6 seconds] to a date.

Categories