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

io.opencensus.common.Timestamp Maven / Gradle / Ivy

/*
 * Copyright 2016-17, OpenCensus Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.opencensus.common;

import static io.opencensus.common.TimeUtils.MAX_NANOS;
import static io.opencensus.common.TimeUtils.MAX_SECONDS;
import static io.opencensus.common.TimeUtils.MILLIS_PER_SECOND;
import static io.opencensus.common.TimeUtils.NANOS_PER_MILLI;
import static io.opencensus.common.TimeUtils.NANOS_PER_SECOND;

import com.google.auto.value.AutoValue;
import java.math.BigDecimal;
import java.math.RoundingMode;
import javax.annotation.concurrent.Immutable;

/**
 * A representation of an instant in time. The instant is the number of nanoseconds after the number
 * of seconds since the Unix Epoch.
 *
 * 

Use {@code Tracing.getClock().now()} to get the current timestamp since epoch * (1970-01-01T00:00:00Z). * * @since 0.5 */ @Immutable @AutoValue public abstract class Timestamp implements Comparable { Timestamp() {} /** * Creates a new timestamp from given seconds and nanoseconds. * * @param seconds Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must be * from from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive. * @param nanos Non-negative fractions of a second at nanosecond resolution. Negative second * values with fractions must still have non-negative nanos values that count forward in time. * Must be from 0 to 999,999,999 inclusive. * @return new {@code Timestamp} with specified fields. * @throws IllegalArgumentException if the arguments are out of range. * @since 0.5 */ public static Timestamp create(long seconds, int nanos) { if (seconds < -MAX_SECONDS) { throw new IllegalArgumentException( "'seconds' is less than minimum (" + -MAX_SECONDS + "): " + seconds); } if (seconds > MAX_SECONDS) { throw new IllegalArgumentException( "'seconds' is greater than maximum (" + MAX_SECONDS + "): " + seconds); } if (nanos < 0) { throw new IllegalArgumentException("'nanos' is less than zero: " + nanos); } if (nanos > MAX_NANOS) { throw new IllegalArgumentException( "'nanos' is greater than maximum (" + MAX_NANOS + "): " + nanos); } return new AutoValue_Timestamp(seconds, nanos); } /** * Creates a new timestamp from the given milliseconds. * * @param epochMilli the timestamp represented in milliseconds since epoch. * @return new {@code Timestamp} with specified fields. * @throws IllegalArgumentException if the number of milliseconds is out of the range that can be * represented by {@code Timestamp}. * @since 0.5 */ public static Timestamp fromMillis(long epochMilli) { long secs = floorDiv(epochMilli, MILLIS_PER_SECOND); int mos = (int) floorMod(epochMilli, MILLIS_PER_SECOND); return create(secs, (int) (mos * NANOS_PER_MILLI)); // Safe int * NANOS_PER_MILLI } /** * Returns the number of seconds since the Unix Epoch represented by this timestamp. * * @return the number of seconds since the Unix Epoch. * @since 0.5 */ public abstract long getSeconds(); /** * Returns the number of nanoseconds after the number of seconds since the Unix Epoch represented * by this timestamp. * * @return the number of nanoseconds after the number of seconds since the Unix Epoch. * @since 0.5 */ public abstract int getNanos(); /** * Returns a {@code Timestamp} calculated as this {@code Timestamp} plus some number of * nanoseconds. * * @param nanosToAdd the nanos to add, positive or negative. * @return the calculated {@code Timestamp}. For invalid inputs, a {@code Timestamp} of zero is * returned. * @throws ArithmeticException if numeric overflow occurs. * @since 0.5 */ public Timestamp addNanos(long nanosToAdd) { return plus(0, nanosToAdd); } /** * Returns a {@code Timestamp} calculated as this {@code Timestamp} plus some {@code Duration}. * * @param duration the {@code Duration} to add. * @return a {@code Timestamp} with the specified {@code Duration} added. * @since 0.5 */ public Timestamp addDuration(Duration duration) { return plus(duration.getSeconds(), duration.getNanos()); } /** * Returns a {@link Duration} calculated as: {@code this - timestamp}. * * @param timestamp the {@code Timestamp} to subtract. * @return the calculated {@code Duration}. For invalid inputs, a {@code Duration} of zero is * returned. * @since 0.5 */ public Duration subtractTimestamp(Timestamp timestamp) { long durationSeconds = getSeconds() - timestamp.getSeconds(); int durationNanos = getNanos() - timestamp.getNanos(); if (durationSeconds < 0 && durationNanos > 0) { durationSeconds += 1; durationNanos = (int) (durationNanos - NANOS_PER_SECOND); } else if (durationSeconds > 0 && durationNanos < 0) { durationSeconds -= 1; durationNanos = (int) (durationNanos + NANOS_PER_SECOND); } return Duration.create(durationSeconds, durationNanos); } /** * Compares this {@code Timestamp} to the specified {@code Timestamp}. * * @param otherTimestamp the other {@code Timestamp} to compare to, not {@code null}. * @return the comparator value: zero if equal, negative if this timestamp happens before * otherTimestamp, positive if after. * @throws NullPointerException if otherTimestamp is {@code null}. */ @Override public int compareTo(Timestamp otherTimestamp) { int cmp = TimeUtils.compareLongs(getSeconds(), otherTimestamp.getSeconds()); if (cmp != 0) { return cmp; } return TimeUtils.compareLongs(getNanos(), otherTimestamp.getNanos()); } // Returns a Timestamp with the specified duration added. private Timestamp plus(long secondsToAdd, long nanosToAdd) { if ((secondsToAdd | nanosToAdd) == 0) { return this; } long epochSec = TimeUtils.checkedAdd(getSeconds(), secondsToAdd); epochSec = TimeUtils.checkedAdd(epochSec, nanosToAdd / NANOS_PER_SECOND); nanosToAdd = nanosToAdd % NANOS_PER_SECOND; long nanoAdjustment = getNanos() + nanosToAdd; // safe int + NANOS_PER_SECOND return ofEpochSecond(epochSec, nanoAdjustment); } // Returns a Timestamp calculated using seconds from the epoch and nanosecond fraction of // second (arbitrary number of nanoseconds). private static Timestamp ofEpochSecond(long epochSecond, long nanoAdjustment) { long secs = TimeUtils.checkedAdd(epochSecond, floorDiv(nanoAdjustment, NANOS_PER_SECOND)); int nos = (int) floorMod(nanoAdjustment, NANOS_PER_SECOND); return create(secs, nos); } // Returns the result of dividing x by y rounded using floor. private static long floorDiv(long x, long y) { return BigDecimal.valueOf(x).divide(BigDecimal.valueOf(y), 0, RoundingMode.FLOOR).longValue(); } // Returns the floor modulus "x - (floorDiv(x, y) * y)" private static long floorMod(long x, long y) { return x - floorDiv(x, y) * y; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy