Reputation: 23
I am trying to get timestamp form sql and need to calculate the difference between two time stamp.
//startDate = 2014-07-10 16:07:00.0
//endDate = 2014-07-11 04:07:00.0
//END_DATE = 2014-07-18 08:07:00.0
private Timestamp calculateWflTime(String vehicleNum, Timestamp startDate,
Timestamp endDate) {
Timestamp t1 = new Timestamp (END_DATE.getTime()); //2014-07-18 08:07:00.0
Timestamp t2 = new Timestamp (startDate.getTime()); //2014-07-10 16:07:00.0
Timestamp wflTime = null;
long diff=0;
if(VEH_NUM == vehicleNum){
diff = t1.getTime()-t2.getTime();//diff(END_DATE,startDate);
}
wflTime = new Timestamp( Math.abs(diff/(1000*60*60*24)));
return wflTime; //1970-01-01 05:30:00.007
}
Upvotes: 0
Views: 1210
Reputation: 44061
The expression
new Timestamp( Math.abs(diff/(1000*60*60*24)));
is semantically wrong from a domain point of view. Why? You try to convert an amount of time (indeed a duration in milliseconds not anchored on the timeline) to a time point which is fixed here to count from UNIX epoch (1970-01-01). It is like conversion of a length to a point in geometric terms.
The difference between two timestamps should not be a new timestamp but just a duration (here your diff-variable in milliseconds). And it is up to you how you want to normalize it to years and months.
Clean Joda solution:
public static void main(String... args) {
Timestamp t1 = new Timestamp(0);
Timestamp t2 = new Timestamp(86400000 + 7261000);
System.out.println(getDurationJoda(t1, t2));
// output: 1 day, 2 hours, 1 minute, 1 second.
}
public static String getDurationJoda(Timestamp start, Timestamp end) {
LocalDateTime ldtStart = new LocalDateTime(start);
LocalDateTime ldtEnd = new LocalDateTime(end);
Period p = new Period(ldtStart, ldtEnd, PeriodType.dayTime());
PeriodFormatter fmt =
new PeriodFormatterBuilder()
.appendDays().appendSuffix(" day, ", " days, ")
.appendHours().appendSuffix(" hour, ", " hours, ")
.appendMinutes().appendSuffix(" minute, ", " minutes, ")
.appendSeconds().appendSuffix(" second.", " seconds.").toFormatter();
return fmt.print(p);
}
Time4J-solution
Furthermore, you have this alternative using my library Time4J which contains a localizable PrettyTime
-class for duration formatting since version 1.2:
private static final IsoUnit DAYS = CalendarUnit.DAYS;
private static final IsoUnit HOURS = ClockUnit.HOURS;
private static final IsoUnit MINUTES = ClockUnit.MINUTES;
private static final IsoUnit SECONDS = ClockUnit.SECONDS;
public static void main(String... args) {
Timestamp t1 = new Timestamp(0);
Timestamp t2 = new Timestamp(86400000 + 7261000);
System.out.println(getDurationTime4J(t1, t2));
// output: 1 day, 2 hours, 1 minute, and 1 second
}
public static String getDurationTime4J(Timestamp start, Timestamp end) {
PlainTimestamp startTS = TemporalTypes.SQL_TIMESTAMP.transform(start);
PlainTimestamp endTS = TemporalTypes.SQL_TIMESTAMP.transform(end);
Duration<?> duration =
Duration.in(DAYS, HOURS, MINUTES, SECONDS).between(startTS, endTS);
return PrettyTime.of(Locale.ENGLISH).print(duration, TextWidth.WIDE);
}
Last but not least, try to evaluate your string condition before formatting the duration and use equals() instead of ==, for example:
if (VEH_NUM.equals(vehicleNum)) {
// call getDuration(..., ...)
} else {
// return zero duration string
}
Upvotes: 1
Reputation: 23
anyways I used JodaTime library to calculate the difference between two time stamps. Thank you all for the help.
as a solution, the modified code is now :
private String calculateWflTime(String vehicleNum, Timestamp startDate,
Timestamp endDate) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String days = null, hours = null, minutes = null, seconds = null;
Date d1 = null;
Date d2 = null;
Timestamp wflTime = null;
if(VEH_NUM == vehicleNum){
String dateStart = END_DATE.toString();
String dateStop = startDate.toString();
try {
d1 = format.parse(dateStart);
d2 = format.parse(dateStop);
DateTime dt1 = new DateTime(d1);
DateTime dt2 = new DateTime(d2);
days = Days.daysBetween(dt1, dt2).getDays() + " days, ";
hours = Hours.hoursBetween(dt1, dt2).getHours() % 24 + " hours, ";
minutes = Minutes.minutesBetween(dt1, dt2).getMinutes() % 60 + " minutes, ";
seconds = Seconds.secondsBetween(dt1, dt2).getSeconds() % 60 + " seconds.";
} catch (Exception e) {
e.printStackTrace();
}
}
return days+hours+minutes+seconds;
}
Upvotes: 0
Reputation: 1
Regarding the 1970 date, generally all dates are a number representing the number of milliseconds since midnight on 1-jan-1970, so if you display the difference between to similar dates as a date then you will get something in the 1970s. You need to treat the answer as milliseconds and work out the days,hours,minutes as a time. Hope this helps.
Upvotes: 0
Reputation: 699
Unix timestamp is a system for describing instants in time, defined as the number of seconds that have elapsed since 1 January 1970.
So if you substract it and transform it, it shows you the time elapsed since 1970.
Upvotes: 0