Reputation: 950
How can I get the duration of two Strings in the format YYYYMMDDTHHMMSS
?
I´m trying with using the Calendar class and checking the getTimeInMillis()
. Problem I am having with this is that it is not consistent. Any idea what I am doing wrong?
Every time I run this program I get 40-70 lines of output to console when it should be none.
public class DurationTester {
/**
* Get the duration between two given times
* @param time1 yyyymmddThhmmss
* @param time2 yyyymmddThhmmss
* @return minutes between time1 and time2
*/
public static int getDuration(String time1, String time2){
int yyyy1 = Integer.parseInt(time1.substring(0,4));
int mm1 = Integer.parseInt(time1.substring(4,6));
int dd1 = Integer.parseInt(time1.substring(6,8));
int hh1 = Integer.parseInt(time1.substring(9,11));
int min1 = Integer.parseInt(time1.substring(11,13));
int yyyy2 = Integer.parseInt(time2.substring(0,4));
int mm2 = Integer.parseInt(time2.substring(4,6));
int dd2 = Integer.parseInt(time2.substring(6,8));
int hh2 = Integer.parseInt(time2.substring(9,11));
int min2 = Integer.parseInt(time2.substring(11,13));
Calendar cal1 = Calendar.getInstance();
cal1.set(yyyy1, mm1, dd1, hh1, min1, 0);
Calendar cal2 = Calendar.getInstance();
cal2.set(yyyy2, mm2, dd2, hh2, min2, 0);
long milliSec = cal1.getTimeInMillis()-cal2.getTimeInMillis();
long nonNegativeMS = Math.abs(milliSec);
long seconds = nonNegativeMS / 1000;
long minutes = seconds / 60;
return (int)minutes;
}
public static void main(String[] args){
String t1 = "20130108T150000";
String t2 = "20130108T131500";
int errors = 0;
for(int i=0; i<5000; i++){
int duration = getDuration(t1,t2);
if(duration == 104){
System.out.println("ERROR: Should only be 105 ("+errors++ +")");
}
}
}
}
Upvotes: 1
Views: 282
Reputation: 347244
To start with, your date conversion is off Calendar
months are zero indexed (that is Janurary
is actually month 0
), so instead of begin Tue Jan 08 15:00:00 EST 2013
, you dates are actually being converted to Fri Feb 08 15:00:00 EST 2013
, which, in of itself, is not the source of the problem, but is of concern.
Instead, you should be using ...
public static final SimpleDateFormat SDF = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
public static int getDuration(String time1, String time2){
Date date1 = SDF.parse(time1);
Date date2 = SDF.parse(time2);
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1);
Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2);
To convert the String
values back to Date
Now, to the cause of your problem...
Because you are setting the Calendar
values using the set(int year, int month, int date, int hourOfDay, int minute, int second)
, the calendar instance still contains the milliseconds it had when it was created (Calendar.getInstance()
will return a Calendar
set to the date/time it was created), but you are not zeroing out these values.
This leads to errors in your calculations
You shouldn't rely on Calendar
or Date
for calculating durations, they are unreliable over long periods, instead you should use JodaTime
DateTime dt1 = new DateTime(date1);
DateTime dt2 = new DateTime(date2);
Duration duration = new Duration(dt2, dt1);
System.out.println(duration.getStandardDays());
System.out.println(duration.getStandardHours());
System.out.println(duration.getStandardMinutes());
Upvotes: 1
Reputation: 2402
That's a documented bug.
Try clearing the calendar before set:
cal1.clear();
cal1.set(yyyy1, mm1, dd1, hh1, min1, 0);
cal2.clear();
cal2.set(yyyy2, mm2, dd2, hh2, min2, 0);
Upvotes: 2
Reputation: 21
You can use SimpleDateFormat API for parse your String :
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
try {
Date date1 = sdf.parse("20130108T150000");
Date date2 = sdf.parse("20130108T131500");
System.out.println((date1.getTime() - date2.getTime())/1000/60);
} catch (ParseException e) {
e.printStackTrace();
}
}
Upvotes: 2
Reputation: 35557
Try this
String t1 = "20130108T150000";
String t2 = "20130108T131500";
DateFormat df=new SimpleDateFormat("yyyyMMdd'T'HHmmss");
Date date1=df.parse(t1);
Date date2=df.parse(t2);
System.out.println(date2.getTime()-date1.getTime()); // time difference in mil-seconds
Upvotes: 1
Reputation: 520
i would advice to use the SimpleDateFormat
for parsing your String
to date object
SimpleDateFormat date_format = new SimpleDateFormat("yyyyMMdd'T'HHmmSS");
Date dateParsed = date_format.parse(yourStringDate)
You can use the Date.getTime()
function to obtain the date object equivalent in milisecond and perform the difference between two date object
Upvotes: 1