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

com.cinchapi.concourse.Timestamp Maven / Gradle / Ivy

Go to download

Concourse is a self-tuning database that is designed for both ad hoc analytics and high volume transactions at scale. Developers use Concourse to quickly build mission critical software while also benefiting from real time insight into their most important data. With Concourse, end-to-end data management requires no extra infrastructure, no prior configuration and no additional coding–all of which greatly reduce costs and allow developers to focus on core business problems.

There is a newer version: 0.11.2
Show newest version
/*
 * Copyright (c) 2013-2019 Cinchapi Inc.
 *
 * 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 com.cinchapi.concourse;

import java.time.Instant;
import java.util.concurrent.TimeUnit;

import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;

import org.joda.time.Chronology;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import com.cinchapi.concourse.annotate.PackagePrivate;
import com.cinchapi.concourse.time.Time;
import com.google.common.base.Preconditions;
import com.google.common.primitives.Longs;

/**
 * A wrapper class for a Unix timestamp with microsecond precision. A
 * {@link Timestamp} is required for historical operations in {@link Concourse}.
 * This class provides interoperability with Joda {@link DateTime} objects with
 * the {@link #fromJoda(DateTime)} and {@link #getJoda()} methods.
 * 
 * @author Jeff Nelson
 */
@Immutable
@ThreadSafe
public final class Timestamp implements Comparable {

    // Joda DateTime uses millisecond instead of microsecond precision, so this
    // class is a wrapper that will handle microseconds so we don't ever lose
    // data that happens within the same millisecond.

    /**
     * The default formatter that is used to display {@link #isDateOnly() date
     * only} timestamps.
     */
    public static final DateTimeFormatter DEFAULT_DATE_ONLY_FORMATTER = DateTimeFormat
            .forPattern("E MMM dd, yyyy");

    /**
     * The default formatter that is used to display objects of this class.
     */
    public static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormat
            .forPattern("E MMM dd, yyyy @ h:mm:ss:SS a z");

    /**
     * Return a {@code Timestamp} that corresponds to the system
     * epoch timestamp with microsecond precision.
     * 
     * @return the timestamp for system epoch
     */
    public static Timestamp epoch() {
        return Timestamp.fromMicros(-1);
    }

    /**
     * Return a {@link Timestamp} that corresponds to the specified
     * {@code instant}.
     * 
     * @param instant an {@linm Instant} instance
     * @return the corresponding {@link Timestamp}
     */
    public static Timestamp fromInstant(Instant instant) {
        return new Timestamp(
                TimeUnit.MILLISECONDS.toMicros(instant.toEpochMilli()));
    }

    /**
     * Return the {@code Timestamp} that corresponds to the provided joda
     * DateTime object.
     * 
     * @param joda a {@link DateTime} object
     * @return the timestamp for {@code joda}
     */
    public static Timestamp fromJoda(DateTime joda) {
        return new Timestamp(joda);
    }

    /**
     * Return a {@code Timestamp} that corresponds to the provided Unix
     * timestamp with microsecond precision.
     * 
     * @param microseconds the number of microseconds since the Unix epoch
     * @return the timestamp for {@code microseconds}
     */
    public static Timestamp fromMicros(long microseconds) {
        return new Timestamp(microseconds);
    }

    /**
     * Take the {@code description} and return a {@link Timestamp} that can be
     * passed to {@link Concourse driver} API methods.
     * 

* Timestamp description are parsed by Concourse Server, so this method only * returns a wrapper that is meant to be passed over the wire. Timestamps * returned from this method are non-operable and will throw * exceptions if you call methods that would return a precise instant (i.e. * {@link #getJoda()} or {@link #getMicros()}). *

* * @param description a relative or absolute natural language description of * an instant. * @return a hollow {@link Timestamp} that wraps the description */ public static Timestamp fromString(String description) { return new Timestamp(description); } /** * Return a {@code Timestamp} set the current system microsecond time using * ISOChronology in the default time zone. * * @return the current timestamp, not null */ public static Timestamp now() { return new Timestamp(Time.now()); } /** * Return a {@code Timestamp} set to the current system microsecond time * using the specified chronology. * * @param chronology the chronology, not null * @return the current timestamp, not null */ public static Timestamp now(Chronology chronology) { long microseconds = Time.now(); return new Timestamp(microseconds, new DateTime(TimeUnit.MILLISECONDS .convert(microseconds, TimeUnit.MICROSECONDS), chronology)); } /** * Return a {@code Timestamp} set to the current system microsecond time * using ISOChronology in the specified time zone. * * @param zone the time zone, not null * @return the current timestamp, not null */ public static Timestamp now(DateTimeZone zone) { long microseconds = Time.now(); return new Timestamp(microseconds, new DateTime(TimeUnit.MILLISECONDS .convert(microseconds, TimeUnit.MICROSECONDS), zone)); } /** * Parses a {@code Timestamp} from the specified string using a formatter. * * @param str the string to parse, not null * @param formatter the formatter to use, not null * @return the parsed timestamp */ public static Timestamp parse(String str, DateTimeFormatter formatter) { return new Timestamp(DateTime.parse(str, formatter)); } /** * Parse a {@link Timestamp} from the specified string that adheres to the * provided {@code format}. * * @param str the string to parse, not {@code null} * @param format the format of the string; see * {@link http://www.joda.org/joda-time/apidocs/org/joda/time/format/DateTimeFormat.html} * for details * @return the parsed timestamp */ public static Timestamp parse(String str, String format) { return parse(str, DateTimeFormat.forPattern(format)); } /** * A relative or absolute description of an instant that is translated to an * actual microsecond timestamp in Concourse Server. By convention, a * {@link Timestamp} object is considered to be {@link #isString() hollow} * if and only if the value of this variable is non-null. */ private final String description; /** * A {@link DateTime} object that corresponds to this {@link Timestamp}. We * use this for the {@link #toString() string} representation and for any * other comparative operations that need to take things like timezones into * account. */ private final DateTime joda; /** * The number of microseconds since the Unix epoch that identify the instant * represented by this {@link Timestamp}. */ private final long microseconds; /** * Construct a new instance. * * @param joda */ private Timestamp(DateTime joda) { this.joda = joda; this.microseconds = TimeUnit.MICROSECONDS.convert(joda.getMillis(), TimeUnit.MILLISECONDS); this.description = null; } /** * Construct a new instance. * * @param microseconds */ private Timestamp(long microseconds) { this.microseconds = microseconds; this.joda = new DateTime(TimeUnit.MILLISECONDS.convert(microseconds, TimeUnit.MICROSECONDS)); this.description = null; } /** * Construct a new instance. * * @param microseconds * @param joda */ private Timestamp(long microseconds, DateTime joda) { this.microseconds = microseconds; this.joda = joda; this.description = null; } /** * Construct a {@link #isString()} instance. * * @param description the description to be resolved into an instant by * Concourse Server */ private Timestamp(String description) { this.microseconds = 0; this.joda = null; this.description = description; } @Override public int compareTo(Timestamp other) { return Longs.compare(getMicros(), other.getMicros()); } @Override public boolean equals(Object obj) { if(obj instanceof Timestamp && !isString()) { return Longs.compare(microseconds, ((Timestamp) obj).microseconds) == 0; } // NOTE: By convention, two hollow timestamps are NEVER equal return false; } /** * Return an {@link Instant} that corresponds to the point on the time-line * represented by this {@link Timestamp}. * * @return the corresponding {@link Instant} */ public Instant getInstant() { return Instant .ofEpochMilli(TimeUnit.MICROSECONDS.toMillis(getMicros())); } /** * Return the Joda {@link DateTime} object that corresponds to this * Timestamp. * * @return the corresponding joda DateTime */ public DateTime getJoda() { Preconditions.checkState(!isString(), "Only Concourse Server can parse a DateTime " + "from a Timestamp created from a string."); return joda; } /** * Return the number of microseconds since the Unix epoch that is * represented by this Timestamp. * * @return the microseconds */ public long getMicros() { Preconditions.checkState(!isString(), "Only Concourse Server can parse microseconds " + "from a Timestamp created from a string."); return microseconds; } @Override public int hashCode() { return isString() ? description.hashCode() : Longs.hashCode(microseconds); } /** * Return {@code true} of this {@link Timestamp} does not have relevant * temporal componet. * * @return {@code true} if this {@link Timestamp} represents a date */ public boolean isDateOnly() { DateTime joda = getJoda(); return joda.getMillisOfDay() == 0; } @Override public String toString() { return isString() ? description : joda.toString(isDateOnly() ? DEFAULT_DATE_ONLY_FORMATTER : DEFAULT_FORMATTER); } /** * The {@link com.cinchapi.concourse.thrift.ConcourseService thrift} API * allows specifying timestamps using either microseconds from the unix * epoch ( {@link Long long}) or a natural language description of an * absolute or relative instant ({@link String}). But we can't define * overloaded methods in the {@link Concourse driver} API that take a long * or String for the timestamp parameter because that signatures would be * ambiguous (i.e. does the method {@link Concourse#select(String, String)} * mean {@code select(key, ccl)} or {@code select(ccl, timestring)}?). *

* Therefore, we allow a {@link Timestamp} to be created * {@link #fromString(String) from a string description}, which will be * translated and resolved by Concourse Server. But these objects are * considered to be hollow because the driver and client code is unable to * use the objects in any way. *

*

* For a hollow Timestamp, use the {@link #toString()} method to get the * description. *

* * @return {@code true} if the timestamp was created * {@link #fromString(String) using a description} */ @PackagePrivate boolean isString() { return description != null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy