减去两个java.sql.timestamp得出的年份不正确

减去两个java.sql.timestamp得出的年份不正确,java,sql,date,timestamp,Java,Sql,Date,Timestamp,我试图从sql中获取时间戳,需要计算两个时间戳之间的差异 //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) { Timesta

我试图从sql中获取时间戳,需要计算两个时间戳之间的差异

//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
}

Unix时间戳是一种用于描述时间瞬间的系统,定义为自1970年1月1日以来经过的秒数


因此,如果你减去它并对其进行转换,它将显示自1970年以来经过的时间。

关于1970年的日期,通常所有日期都是一个数字,表示自1970年1月1日午夜以来的毫秒数,因此如果你将与类似日期之间的差异显示为一个日期,那么你将得到1970年代的数据。您需要将答案视为毫秒,并将天、小时、分钟计算为时间。希望这有帮助。

表达

new Timestamp( Math.abs(diff/(1000*60*60*24)));
从域的角度来看,它在语义上是错误的。为什么?您尝试将一个时间量(实际上是未固定在时间轴上的持续时间,以毫秒为单位)转换为一个时间点,该时间点在此处固定为从UNIX epoch(1970-01-01)开始计数。这就像几何术语中长度到点的转换

两个时间戳之间的差异不应该是一个新的时间戳,而应该是一个持续时间(这里是以毫秒为单位的diff变量)。这取决于你如何将其正常化为几年或几个月

OP回复后更新 清洁Joda溶液:

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解决方案

此外,您还可以使用my library,该库包含一个可本地化的
PrettyTime
-类,用于自版本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);
}

无论如何,我使用JodaTime库来计算两个时间戳之间的差异。谢谢大家的帮助

作为解决方案,修改后的代码现在是:

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;
}

返回的wflTime是1970-01-01 05:30:00.007,为什么有1970?它被认为是默认时间。我没有收到你的密码。但是这是sqlString与==比较的默认日期时间,很少是好的,请参见第行“if(VEH_NUM==vehicleneum){”正确,除非我对“一般”有异议。各种计算机系统使用了大约。至于计数,Unix系统使用了从纪元开始的秒数(给我们,java.util.Date/Joda-Time使用毫秒,java 8中的新java.Time包使用纳秒。是的,我应该更具体一些。或者甚至可以使用而不是
等于
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;
}