All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.diirt.util.time.Timestamp Maven / Gradle / Ivy

/**
 * Copyright (C) 2010-14 diirt developers. See COPYRIGHT.TXT
 * All rights reserved. Use is subject to license terms. See LICENSE.TXT
 */
package org.diirt.util.time;

import java.text.DecimalFormat;
import java.util.Date;

/**
 * Represents a time stamp at nanosecond accuracy. The time is internally stored
 * as a 64 + 32 bit value: number of seconds from the Java/UNIX epoch 
 * (1/1/1970) and the nanoseconds past that instant. 
 * The range is of 292 billion years before and another 292 past the epoch.
 * 

* Note that while TimeStamp are usually created according to system clocks which * may take into account leap seconds, all the math operations on TimeStamps do * not take leap seconds into account. *

JSR 310 compatibility

* This class is essentially equivalent to {@code javax.time.Instant}. * When it will be released, the plan is to phase out * this class in the same way that {@link java.util.Date} is going to be phased out. * As of 2012/05/07, there are still multiple proposal on the table on that will * work, but in all cases it requires having this class implement a single * method interface and make all clients use that single method interface. * * @author carcassi */ public class Timestamp implements Comparable { /* * When the class is initialized, get the current timestamp and nanotime, * so that future instances can be calculated from this reference. */ private static final Timestamp base = Timestamp.of(new Date()); private static final long baseNano = System.nanoTime(); /** * Unix timestamp */ private final long unixSec; /** * Nanoseconds past the timestamp. Must be 0 < nanoSec $lt; 999,999,999 */ private final int nanoSec; private Timestamp(long unixSec, int nanoSec) { if (nanoSec < 0 || nanoSec > 999999999) throw new IllegalArgumentException("Nanoseconds must be between 0 and 999,999,999"); this.unixSec = unixSec; this.nanoSec = nanoSec; } /** * Unix time; seconds from midnight 1/1/1970. * @return unix time */ public long getSec() { return unixSec; } /** * Nanoseconds within the given second. * @return nanoseconds (0 < nanoSec < 999,999,999) */ public int getNanoSec() { return nanoSec; } /** * Returns a new timestamp from Java/UNIX time. * * @param epochSec number of seconds in the Java/UNIX epoch. * @param nanoSec nanoseconds past the given seconds (must be 0 < nanoSec < 999,999,999) * @return a new timestamp */ public static Timestamp of(long epochSec, int nanoSec) { return new Timestamp(epochSec, nanoSec); } /** * Converts a {@link java.util.Date} to a timestamp. Date is accurate to * milliseconds, so the last 6 digits are always going to be zeros. * * @param date the date to convert * @return a new timestamp */ public static Timestamp of(Date date) { if (date == null) return null; long time = date.getTime(); int nanoSec = (int) (time % 1000) * 1000000; long epochSec = (time / 1000); return createWithCarry(epochSec, nanoSec); } /** * Returns a new timestamp for the current instant. The timestamp is calculated * using {@link java.lang.System#nanoTime()}, so it has the accuracy given * by that function. * * @return a new timestamp */ public static Timestamp now() { return base.plus(TimeDuration.ofNanos(System.nanoTime() - baseNano)); } /** * Converts the time stamp to a standard Date. The conversion is done once, * and it trims all precision below milliSec. * * @return a date */ public Date toDate() { return new Date((unixSec)*1000+nanoSec/1000000); } @Override public int hashCode() { return Long.valueOf(nanoSec).hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof Timestamp) { Timestamp other = (Timestamp) obj; return other.nanoSec == nanoSec && other.unixSec == unixSec; } return false; } /** * Defines the natural ordering for timestamp as forward in time. * * @param other another object * @return comparison result */ @Override public int compareTo(Timestamp other) { if (unixSec < other.unixSec) { return -1; } else if (unixSec == other.unixSec) { if (nanoSec < other.nanoSec) { return -1; } else if (nanoSec == other.nanoSec) { return 0; } else { return 1; } } else { return 1; } } /** * Adds the given duration to this timestamp and returns the result. * @param duration a time duration * @return a new timestamp */ public Timestamp plus(TimeDuration duration) { return createWithCarry(unixSec + duration.getSec(), nanoSec + duration.getNanoSec()); } /** * Creates a new time stamp by carrying nanosecs into seconds if necessary. * * @param seconds new seconds * @param ofNanos new nanoseconds (can be the whole long range) * @return the new timestamp */ private static Timestamp createWithCarry(long seconds, long nanos) { if (nanos > 999999999) { seconds = seconds + nanos / 1000000000; nanos = nanos % 1000000000; } if (nanos < 0) { long pastSec = nanos / 1000000000; pastSec--; seconds += pastSec; nanos -= pastSec * 1000000000; } return new Timestamp(seconds, (int) nanos); } /** * Subtracts the given duration to this timestamp and returns the result. * @param duration a time duration * @return a new timestamp */ public Timestamp minus(TimeDuration duration) { return createWithCarry(unixSec - duration.getSec(), nanoSec - duration.getNanoSec()); } private static final DecimalFormat format = new DecimalFormat("000000000"); @Override public String toString() { return unixSec + "." + format.format(nanoSec); } /** * Calculates the time between the reference and this timeStamp. * The resulting duration is the absolute value, so it does not matter * on which object the function is called. * * @param time another time stamp * @return the duration between the two timeStamps */ public TimeDuration durationBetween(Timestamp time) { long nanoSecDiff = time.nanoSec - nanoSec; nanoSecDiff += (time.unixSec - unixSec) * 1000000000; nanoSecDiff = Math.abs(nanoSecDiff); return TimeDuration.ofNanos(nanoSecDiff); } /** * Calculates the time passed from the reference to this timeStamp. * The result is the relative time from the reference to this * timestamp, so that reference + result = this. * * @param reference another time stamp * @return the duration from the reference to this */ public TimeDuration durationFrom(Timestamp reference) { long nanoSecDiff = nanoSec - reference.nanoSec; nanoSecDiff += (unixSec - reference.unixSec) * 1000000000; return TimeDuration.ofNanos(nanoSecDiff); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy