Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate the difference between two Java java.sql.Timestamps?

Tags:

java

timestamp

Please include the nanos, otherwise it would be trivial:

long diff = Math.abs(t1.getTime () - t2.getTime ());

[EDIT] I want the most precise result, so no doubles; only integer/long arithmetic. Also, the result must be positive. Pseudo code:

Timestamp result = abs (t1 - t2);

Examples:

t1 = (time=1001, nanos=1000000), t2 = (time=999, nanos=999000000)
 -> diff = (time=2, nanos=2000000)

Yes, milliseconds in java.sql.Timestamp are duplicated in the time and the nanos par, so 1001 milliseconds means 1 second (1000) and 1 milli which is in the time part and the nanos part because 1 millisecond = 1000000 nanoseconds). This is much more devious than it looks.

I suggest not to post an answer without actually testing the code or having a working code sample ready :)

like image 388
Aaron Digulla Avatar asked Feb 24 '09 15:02

Aaron Digulla


People also ask

How can I find the difference between two timestamps in sql?

To calculate the difference between the timestamps in MySQL, use the TIMESTAMPDIFF(unit, start, end) function. The unit argument can be MICROSECOND , SECOND , MINUTE , HOUR , DAY , WEEK , MONTH , QUARTER , or YEAR .

How do you find the difference between two timestamps?

If you'd like to calculate the difference between the timestamps in seconds, multiply the decimal difference in days by the number of seconds in a day, which equals 24 * 60 * 60 = 86400 , or the product of the number of hours in a day, the number of minutes in an hour, and the number of seconds in a minute.

How do you subtract a Timestamp in Java?

String a = timeSt. get(0); // timeSt is an ArrayList which includes all the timeStamps String b = timeSt. get(timeSt. size()-1); // This method aims finding the difference of the first and the last elements(timestamps) of the ArrayList (in seconds) long i = Long.

What is the difference between Java sql time and Java sql Timestamp in Java?

Time represents SQL TIME and only contains information about hour, minutes, seconds and milliseconds without date component. java. sql. Timestamp represents SQL TIMESTAMP which contains both Date and Time information to the nanoseconds precision.


2 Answers

After one hour and various unit tests, I came up with this solution:

public static Timestamp diff (java.util.Date t1, java.util.Date t2)
{
    // Make sure the result is always > 0
    if (t1.compareTo (t2) < 0)
    {
        java.util.Date tmp = t1;
        t1 = t2;
        t2 = tmp;
    }

    // Timestamps mix milli and nanoseconds in the API, so we have to separate the two
    long diffSeconds = (t1.getTime () / 1000) - (t2.getTime () / 1000);
    // For normals dates, we have millisecond precision
    int nano1 = ((int) t1.getTime () % 1000) * 1000000;
    // If the parameter is a Timestamp, we have additional precision in nanoseconds
    if (t1 instanceof Timestamp)
        nano1 = ((Timestamp)t1).getNanos ();
    int nano2 = ((int) t2.getTime () % 1000) * 1000000;
    if (t2 instanceof Timestamp)
        nano2 = ((Timestamp)t2).getNanos ();

    int diffNanos = nano1 - nano2;
    if (diffNanos < 0)
    {
        // Borrow one second
        diffSeconds --;
        diffNanos += 1000000000;
    }

    // mix nanos and millis again
    Timestamp result = new Timestamp ((diffSeconds * 1000) + (diffNanos / 1000000));
    // setNanos() with a value of in the millisecond range doesn't affect the value of the time field
    // while milliseconds in the time field will modify nanos! Damn, this API is a *mess*
    result.setNanos (diffNanos);
    return result;
}

Unit tests:

    Timestamp t1 = new Timestamp (0);
    Timestamp t3 = new Timestamp (999);
    Timestamp t4 = new Timestamp (5001);
    // Careful here; internally, Java has set nanos already!
    t4.setNanos (t4.getNanos () + 1);

    // Show what a mess this API is...
    // Yes, the milliseconds show up in *both* fields! Isn't that fun?
    assertEquals (999, t3.getTime ());
    assertEquals (999000000, t3.getNanos ());
    // This looks weird but t4 contains 5 seconds, 1 milli, 1 nano.
    // The lone milli is in both results ...
    assertEquals (5001, t4.getTime ());
    assertEquals (1000001, t4.getNanos ());

    diff = DBUtil.diff (t1, t4);
    assertEquals (5001, diff.getTime ());
    assertEquals (1000001, diff.getNanos ());

    diff = DBUtil.diff (t4, t3);
    assertEquals (4002, diff.getTime ());
    assertEquals (2000001, diff.getNanos ());
like image 60
Aaron Digulla Avatar answered Sep 29 '22 05:09

Aaron Digulla


I use this method to get difference between 2 java.sql.Timestmap

/**
 * Get a diff between two timestamps.
 *
 * @param oldTs The older timestamp
 * @param newTs The newer timestamp
 * @param timeUnit The unit in which you want the diff
 * @return The diff value, in the provided time unit.
 */
public static long getDateDiff(Timestamp oldTs, Timestamp newTs, TimeUnit timeUnit) {
    long diffInMS = newTs.getTime() - oldTs.getTime();
    return timeUnit.convert(diffInMS, TimeUnit.MILLISECONDS);
}

// Examples:
// long diffMinutes = getDateDiff(oldTs, newTs, TimeUnit.MINUTES);
// long diffHours = getDateDiff(oldTs, newTs, TimeUnit.HOURS);
like image 20
AechoLiu Avatar answered Sep 29 '22 05:09

AechoLiu