Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am trying to find difference between 2 times in minutes with following code.not providing complete code:
String dateStart = "03/25/2014 18:03:00";
String dateStop = "03/25/2014 19:45:00";
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Date d1 = null;
Date d2 = null;
d1 = format.parse(dateStart);
d2 = format.parse(dateStop);
long diff = endDate.getTime()-startDate.getTime();
long minutes = diff/(60*1000) % 60;
not sure why it is returnung 14 minutes. instead 102 minutes.
Regards,
chaitu
Joda-Time
In Joda-Time, use the Minutes class. Basically one line of code, calling minutesBetween.
Example Code
Here is some example code in Joda-Time 2.3.
Parsing those strings
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "MM/dd/yyyy HH:mm:ss" ).withZone( timeZone );
DateTime start = formatter.parseDateTime( "03/25/2014 18:03:00" );
DateTime stop = formatter.parseDateTime( "03/25/2014 19:45:00" );
Calculating minutes between
int minutes = Minutes.minutesBetween( start, stop ).getMinutes();
ISO Duration (Period)
Or you may want to generate a string in the ISO 8601 format of Durations: PnYnMnDTnHnMnS. To do so in Joda-Time, use the Period class (yes, date-time terminology is not standardized, used differently by different folks).
Period period = new Period( start, stop );
String output = period.toString();
Results
Dump to console…
System.out.println( "start: " + start );
System.out.println( "stop: " + stop );
System.out.println( "minutes: " + minutes );
System.out.println( "period: " + period );
When run…
start: 2014-03-25T18:03:00.000+01:00
stop: 2014-03-25T19:45:00.000+01:00
minutes: 102
period: PT1H42M
That output of PT1H42M means "one hour and forty-two minutes".
Time Zone
Your question and code ignored the crucial issue of time zone in parsing those strings. You should almost always specify a time zone.
java.time
The new java.time package in Java 8 may have similar features as what you’ve seen here with Joda-Time.
long diff = endDate.getTime()-startDate.getTime();
makes diff the difference between the two times in milliseconds (6120000). To get seconds, divide by 1000 (6120). To get minutes, divide the result of that by 60 (102).
To get utter nonsense, further take mod 60 (gives 42).
(Note that this is a mathematical error, not really a question about Java.)
To get the difference in minutes, you have can use:
long minutes = diff / (60 * 1000);
When you do:
long minutes = diff / (60 * 1000) % 60;
you are getting the difference of minutes between the dates. In other words, you are only considering minutes; not hours, nor days...
The modulus operation in your code isn't needed. Remember that the modulus operator gives you the remainder of an operation. If you take out the "% 60;" part of your code, it should work.
Fixed calculation:
long minutes = diff/(60*1000);
The situation where you'd want to use the modulus operator is if you wanted to express the difference also in units that are greater than a minute, such as hours or days. In this case you'd use the modulus operator to make sure you'd only extract the number of minutes that are less than 60.
Related
I am trying to calculate the difference between two times, which are represented as longs in the Format HHmm 24 hour time. E.g 4:30pm is represented by the long 0430.
I am happy for the difference to be in minutes.
Is there a simple calculation that can be done to achieve this? I am aware of Java's Date class, however I want to avoid having to store dummy date information just for a calculation on time.
Thanks!
Putting aside the fact that this is a really, really bad way to store times, the easiest way to do this is to convert the HHMM time to minutes since the start of the day:
long strangeTimeFormatToMinutes(long time) {
long minutes = time % 100;
long hours = time / 100;
return minutes + 60 * hours;
}
Then just use plain old subtraction to get the difference.
You may also want to add validation that minutes and hours are in the ranges you expect, i.e. 0-59 and 0-23.
You mentioned that you didn't want to use the Date class because it required you to use a dummy date. The LocalTime class does not require that.
LocalTime start = LocalTime.of(6,15,30,200); // h, m, s, nanosecs
LocalTime end = LocalTime.of(6,30,30,320);
Duration d = Duration.between(start, end);
System.out.println(d.getSeconds()/60);
Pad zeros
First convert your integer to a 4-character string, padding with leading zeros.
For example, 430 becomes 0430 and parsed as 04:30. Or, 15 becomes 0015 and parsed as quarter past midnight, 00:15.
String input = String.format( "%04d", yourTimeAsInteger );
LocalDate
The LocalTime class represents a time-of-day value with no date and no time zone.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "HHmm" );
LocalTime ld = LocalTime.parse( input , f ) ;
My english is not perfect, but I hope you can understand me.
I try to get the difference in seconds between two unix timestamps, but it's only return 0.
That's my code
unixOnline = Long.valueOf(online);
unixOffline = Long.valueOf(offline);
DateTimeZone BERLIN = DateTimeZone.forID("Europe/Berlin");
DateTime dateTimeOnline = new DateTime(unixOnline * 1000L, BERLIN);
DateTime dateTimeOffline = new DateTime(unixOffline * 1000L, BERLIN);
int seconds = Seconds.secondsBetween(new LocalDate(dateTimeOnline), new LocalDate(dateTimeOffline)).getSeconds();
System.out.println("Seconds: " + seconds);
Edit:
Online Timestamp: 1457536522
Offline Timestamp: 1457536642
LocalDate has no time component, so if the times are on the same day, they're effectively turned into the same time. Instead, just diff the DateTimes as they are;
int hours = Hours.hoursBetween(dateTimeOnline, dateTimeOffline).getHours();
(or in your case, since the difference is only 2 minutes, you'll only see the result with Minutes or Seconds)
EDIT: Since the question seems to have nothing to do with the time zone BERLIN which is in the code, this answer is a bit over complicated. Instead, use krzydyn's answer if it's just a time diff between UTC times.
Since you already have timestamps in seconds it can be simple calculated by formula:
int hours = (t2-t1)/3600;
Or if you need fractions:
float hours = (t2-t1)/3600f;
Update: (maybe I got suggested by the answer :)
So to get time diff in seconds is even simpler:
long seconds = t2-t1;
Hello I'm able to get the seconds, minutes, hours and days, but when I try to get the years the problem comes up.
I'm using the following code:
Calendar startDate = new GregorianCalendar(year, month, day);
Calendar date = Calendar.getInstance();
long diff = date.getTimeInMillis() - startDate.getTimeInMillis();
long seconds = diff / 1000;
long minutes = seconds / 60;
long hours = minutes / 60;
long days = hours / 24;
double years = date.get(Calendar.YEAR) - startDate.get(Calendar.YEAR);
Let's say the start date is 07/25/1994 and the end date is 07/28/2015
the result that I get is (21.0) instead of the of 20.97 . I need to get the exact age in YEARS for the users so; can you help me guys out?. Thanks!
Use BigDecimal instead of double and long. When you want precise calculations of floating point numbers, always use BigDecimal. Floating point math is not reliable in java. Simple example is System.out.println(2.00 - 1.10); guess what, it doesnt print .90.
You need to cast your variables:
double years = (double) date.get(Calendar.YEAR) - (double) startDate.get(Calendar.YEAR);
Is your question about elapsed time or about decimal number calculation?
If the first, you should know that decimal numbers for elapsed years is somewhat odd. If the second, you should change the title of your Question.
Elapsed Time
For Android, you should be using the Joda-Time library rather than the old java.util.Date/.Calendar classes. The old classes are notoriously troublesome.
The ISO 8601 standard defines string formats for various kinds of date-time values. For a span of time in terms of a count of years, months, days, hours, minutes, and seconds, the format is PnYnMnDTnHnMnS where P defines the beginning and T separates the days portion from hours portion. The Question is about a span of P21Y3D, or 21 years and 3 days. The Joda-Time library uses this standard format for both parsing and generating such strings.
LocalDate start = new LocalDate( 1994, 7, 25 ); // 07/25/1994
LocalDate stop = new LocalDate( 2015, 7, 28 ); // 07/28/2015
Period period = new Period( start, stop );
System.out.println("start: " + start + " to stop: " + stop + " is " + period );
When run.
start: 1994-07-25 to stop: 2015-07-28 is P21Y3D
Decimal Number Calculation
If you are just asking about the decimal numbers, then the answer by Samrat Dutta is correct: Use BigDecimal if you care about accuracy. Otherwise you are using primitives with floating-point calculations. Floating-point trades off accuracy for speed of execution. As a general rule, if in doubt about which to use for business problems, go with BigDecimal rather than floating-point.
What do you mean by "exact age in years"? Here's the number of years with up to 200 decimal places:
21.00752908966461327857631759069130732375085557837097878165639972621492128678986995208761122518822724161533196440793976728268309377138945927446954140999315537303216974674880219028062970568104038329911020
Integer days = Days.daysBetween( start, stop ).getDays( );
BigDecimal daysPerYear = new BigDecimal( 365.25 ); // Approximate.
int scale = 200; // Number of fractional digits desired.
BigDecimal years = new BigDecimal( days ).divide( daysPerYear, scale, RoundingMode.HALF_EVEN ); // Banker's rounding.
System.out.println( "days: " + days + " ÷ " + daysPerYear + " = " + years + " years." );
When run.
days: 7673 ÷ 365.25 = 21.00752908966461327857631759069130732375085557837097878165639972621492128678986995208761122518822724161533196440793976728268309377138945927446954140999315537303216974674880219028062970568104038329911020 years.
As I said, you may find P21Y3D makes more sense than this decimal number.
This question already has an answer here:
How to calculate difference between two dates in years...etc with Joda-Time
(1 answer)
Closed 8 years ago.
I have a long-variable which represents an amount of delay in milliseconds. I want to transform this long to some kind of Date where it says how many hours, minutes, seconds, days, months, years have passed.
When using Date toString() from Java, as in new Date(5).toString, it says 5 milliseconds have passed from 1970. I need it to say 5 milliseconds have passed, and 0 minutes, hours, ..., years.
you cannot get direct values , without any reference date for your requirements, you need define first reference value like below:
String dateStart = "01/14/2012 09:29:58";
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")
Date d1 = format.parse(dateStart);
the above is your reference date , now you need to find the current date and time using following.
long currentDateTime = System.currentTimeMillis();
Date currentDate = new Date(currentDateTime);
Date d2.format(currentDate)
and the difference of these values like long diff=d2-d1 will gives values in milliseconds.
then
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);
and similarly for months and years.
you can also refer the example given on this link for more information http://javarevisited.blogspot.in/2012/12/how-to-convert-millisecond-to-date-in-java-example.html
From what I understand from your question you could achieve your goal by writing a method that will suit your needs i.e.:
static public String dateFromMili (long miliseconds) {
// constants that will hold the number of miliseconds
// in a given time unit (year, month etc.)
final int YEAR_IN_MILISECONDS = 12*30*24*60*60*1000;
final int MONTH_IN_MILISECONDS = 30*24*60*60*1000;
final int DAY_IN_MILISECONDS = 24*60*60*1000;
final int HOUR_IN_MILISECONDS = 60*60*1000;
final int MINUTE_IN_MILISECONDS = 60*1000;
final int SECONDS_IN_MILISECONDS = 1000;
// now use those constants to return an appropriate string.
return miliseconds +" miliseconds, "
+miliseconds/SECONDS_IN_MILISECONDS+" seconds, "
+miliseconds/MINUTE_IN_MILISECONDS+" minutes, "
+miliseconds/HOUR_IN_MILISECONDS+" hours, "
+miliseconds/DAY_IN_MILISECONDS+" days, "
+miliseconds/MONTH_IN_MILISECONDS+" months, "
+miliseconds/YEAR_IN_MILISECONDS+" years have passed";
}
Than you will have to pas the number of miliseconds as a parameter to your new function that will return the desired String (i.e for two seconds):
dateFromMili (2000);
You could also print your answer:
System.out.println(dateFromMili(2000));
The result would look like this:
2000 miliseconds, 2 seconds, 0 minutes, 0 hours, 0 days, 0 months, 0 years have passed
Note that this method will return Strings with integer value (you will not get for example "2.222333 years" but "2 years"). Furthermore, it could be perfected by changing the noun from plural to singular, when the context is appropriate ("months" to "month").
I hope my answer helped.
This is how I solved the problem:
I used a library called Joda-Time (http://www.joda.org/joda-time/) (credits to Keppil!)
Joda-Time has various data-structures for Date and Time. You can represent a date and time by a DateTime-object.
To represent the delay I was looking for, I had two options: a Period data-structure or a Duration data-structure. A good explanation of the difference between those two can be found here: Joda-Time: what's the difference between Period, Interval and Duration? .
I thus used a Duration-object, based on the current date of my DateTime-object. It has all the methods to convert the amount of milliseconds to years, months, weeks, days, hours, minutes and seconds.
I'm not sure what I'm doing wrong, but I've got a piece of code which calculates the number of days between two dates, and which looks something like the following:
final Calendar first = new GregorianCalendar(2010, Calendar.OCTOBER, 1);
final Calendar last = new GregorianCalendar(2010, Calendar.NOVEMBER, 1);
final long difference = last.getTimeInMillis() - first.getTimeInMillis();
final long days = difference / (1000 * 60 * 60 * 24);
System.out.println("difference: " + difference);
System.out.println("days: " + days);
To summarise, the code block above calculates the number of days between 1st October 2010 and 1 November 2010. I'm expecting to see it return 31 days (seeing as there's 31 days in October)
difference: xxxx
days: 31
but instead it's showing 30 days in October!
difference: 2674800000
days: 30
I've managed to narrow it down to between the the dates 2 October 2010 and 3 October 2010, which seems to only have 82800000 milliseconds, instead of a full 86400000 milliseconds (exactly one hour missing).
Does anyone have any ideas what I'm doing wrong? Or is the 2nd October a special date which has one minute less than a regular day?
(86400000 - 82800000)/1000 = 3600, which is one hour. You're seeing daylight savings time, combined with the rounding of integer math
You could get around it by doing the calculations with floating point numbers and rounding at the end, or you could check out a library like Joda time which offers much better date math than what's built in.
You may be better off comparing the year and day or year instead of the milliseconds that pass in a day.
int lastYear= last.get(Calendar.YEAR);
int firstYear= first.get(Calendar.YEAR);
int lastDayofYear = last.get(Calendar.DAY_OF_YEAR);
int firstDayofYear = first.get(Calendar.DAY_OF_YEAR);
int nDaysElapse = lastDayofYear - firstDayofYear;
int nYearsElapse = lastYear- firstYear;
int days = (nYearsElapse*365)+nDaysElapse;
You should read this post to get a better understanding of how Calendar is interrelated with date/time stamps.
Having read that site, my initial questions were:
What do you mean by days? Do you mean '24-hour blocks' or do you mean calendar days? In the same vein, do you care if you are off slightly due to daylight savings etc?
If you mean Calendar days, your best bet is probably to:
final Calendar first = new GregorianCalendar(2010, 9, 1);
final Calendar last = new GregorianCalendar(2010, 10, 1);
Calendar difference = Calendar.getInstance();
difference.setTimeInMillis(last.getTimeInMillis() - first.getTimeInMillis());
int numDays = difference.get(Calendar.DAY_OF_YEAR) - difference.getMinimum(Calendar.DAY_OF_YEAR);
Of course, the above code will only work if the number of days < 365. You will need to create a rolling calculation e.g.
int yearDiff = last.get(Calendar.YEAR) - first.get(Calendar.YEAR);
Calendar tmp = new GregorianCalendar();
tmp.setTimeInMillis(first.getTimeInMillis());
for(int i = 0; i < yearDiff; i++) {
numDays += tmp.getActualMaximum(Calendar.DAY_OF_YEAR);
i++;
tmp.add(Calendar.YEAR, 1);
}
This should allow you to get the number of days in a correct and consistent manner, without worrying about Daylight Savings, Leap Years etc.
That said, JodaTime probably has this functionality built in.
The answer by Brad Mace is correct.
Use a Library
This question is a good example of why you should use a good date-time library wither than roll your own. For Java that means using either Joda-Time or the new java.time package in Java 8.
Joda-Time
Example code in Joda-Time.
DateTimeZone timeZone = DateTimeZone.forID( "Australia/Melbourne" );
DateTime theFirst = new DateTime( 2014, DateTimeConstants.OCTOBER, 1, 0, 0, 0, timeZone ).withTimeAtStartOfDay();
DateTime nextMonth = theFirst.plusMonths( 1 ).withTimeAtStartOfDay();
int days = Days.daysBetween( theFirst, nextMonth ).getDays();
Or if you don't care about time-of-day, use the LocalDate class.
java.time
Java 8 and later comes with a new java.time framework to supplant the old java.util.Date/.Calendar classes. Inspired by Joda-Time, defined by JSR 310, and extended by the ThreeTen-Extra project.
Example code using Java 8. Note that the enum ChronoUnit returns a 64-bit long rather than int.
LocalDate firstOfOctober = LocalDate.of( 2010 , java.time.Month.OCTOBER , 1 );
LocalDate nextMonth = firstOfOctober.plusMonths( 1 );
long daysInMonth = ChronoUnit.DAYS.between( firstOfOctober , nextMonth );
The code you put in your post is calculating the time between September 1 and October 1, not October 1 and November 1. The output is correct for the code you posted.