io.sentry.SentryNanotimeDate Maven / Gradle / Ivy
package io.sentry;
import java.util.Date;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Uses {@link Date} in cominbation with System.nanoTime().
*
* A single date only offers millisecond precision but diff can be calculated with up to
* nanosecond precision. This increased precision can also be used to calculate a new end date for a
* transaction where start date is sent with ms precision and end date is added to it with ns
* precision leading to an end timestamp with ns precision that can be used to gain ns precision
* transaction durations.
*
*
This is a workaround for older versions of Java (before 9) and Android API (lower than 26)
* that allows for higher precision than {@link Date} alone would.
*/
public final class SentryNanotimeDate extends SentryDate {
private final @NotNull Date date;
private final long nanos;
public SentryNanotimeDate() {
this(DateUtils.getCurrentDateTime(), System.nanoTime());
}
public SentryNanotimeDate(final @NotNull Date date, final long nanos) {
this.date = date;
this.nanos = nanos;
}
@Override
public long diff(final @NotNull SentryDate otherDate) {
if (otherDate instanceof SentryNanotimeDate) {
final @NotNull SentryNanotimeDate otherNanoDate = (SentryNanotimeDate) otherDate;
return nanos - otherNanoDate.nanos;
}
return super.diff(otherDate);
}
@Override
public long nanoTimestamp() {
return DateUtils.dateToNanos(date);
}
@Override
public long laterDateNanosTimestampByDiff(final @Nullable SentryDate otherDate) {
if (otherDate != null && otherDate instanceof SentryNanotimeDate) {
final @NotNull SentryNanotimeDate otherNanoDate = (SentryNanotimeDate) otherDate;
if (compareTo(otherDate) < 0) {
return nanotimeDiff(this, otherNanoDate);
} else {
return nanotimeDiff(otherNanoDate, this);
}
} else {
return super.laterDateNanosTimestampByDiff(otherDate);
}
}
@Override
@SuppressWarnings("JavaUtilDate")
public int compareTo(@NotNull SentryDate otherDate) {
if (otherDate instanceof SentryNanotimeDate) {
final @NotNull SentryNanotimeDate otherNanoDate = (SentryNanotimeDate) otherDate;
final long thisDateMillis = date.getTime();
final long otherDateMillis = otherNanoDate.date.getTime();
if (thisDateMillis == otherDateMillis) {
return Long.valueOf(nanos).compareTo(otherNanoDate.nanos);
} else {
return Long.valueOf(thisDateMillis).compareTo(otherDateMillis);
}
} else {
return super.compareTo(otherDate);
}
}
private long nanotimeDiff(
final @NotNull SentryNanotimeDate earlierDate, final @NotNull SentryNanotimeDate laterDate) {
final long nanoDiff = laterDate.nanos - earlierDate.nanos;
return earlierDate.nanoTimestamp() + nanoDiff;
}
}