package org.apache.commons.net.ntp; /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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. */ import java.lang.ref.SoftReference; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.TimeZone; /*** * TimeStamp class represents the Network Time Protocol (NTP) timestamp * as defined in RFC-1305 and SNTP (RFC-2030). It is represented as a * 64-bit unsigned fixed-point number in seconds relative to 0-hour on 1-January-1900. * The 32-bit low-order bits are the fractional seconds whose precision is * about 200 picoseconds. Assumes overflow date when date passes MAX_LONG * and reverts back to 0 is 2036 and not 1900. Test for most significant * bit: if MSB=0 then 2036 basis is used otherwise 1900 if MSB=1. *
* Methods exist to convert NTP timestamps to and from the equivalent Java date * representation, which is the number of milliseconds since the standard base * time known as "the epoch", namely January 1, 1970, 00:00:00 GMT. *
* * @author Jason Mathews, MITRE Corp * @version $Revision: 658518 $ $Date: 2008-05-21 02:04:30 +0100 (Wed, 21 May 2008) $ * @see java.util.Date */ public class TimeStamp implements java.io.Serializable, Comparable // TODO add comparable type? { /** * baseline NTP time if bit-0=0 -> 7-Feb-2036 @ 06:28:16 UTC */ protected static final long msb0baseTime = 2085978496000L; /** * baseline NTP time if bit-0=1 -> 1-Jan-1900 @ 01:00:00 UTC */ protected static final long msb1baseTime = -2208988800000L; /** * Default NTP date string format. E.g. Fri, Sep 12 2003 21:06:23.860. * Seejava.text.SimpleDateFormat
for code descriptions.
*/
public final static String NTP_DATE_FORMAT = "EEE, MMM dd yyyy HH:mm:ss.SSS";
/*
* Caches for the DateFormatters used by various toString methods.
*/
private static SoftReferencelong
value
* represented by this TimeStamp
object. That is, the hashcode
* is the value of the expression:
* * * @return a hash code value for this object. */ @Override public int hashCode() { return (int) (ntpTime ^ (ntpTime >>> 32)); } /*** * Compares this object against the specified object. * The result is* (int)(this.ntpValue()^(this.ntpValue() >>> 32)) *
true
if and only if the argument is
* not null
and is a Long
object that
* contains the same long
value as this object.
*
* @param obj the object to compare with.
* @return true
if the objects are the same;
* false
otherwise.
*/
@Override
public boolean equals(Object obj)
{
if (obj instanceof TimeStamp) {
return ntpTime == ((TimeStamp) obj).ntpValue();
}
return false;
}
/***
* Converts this TimeStamp
object to a String
.
* The NTP timestamp 64-bit long value is represented as hex string with
* seconds separated by fractional seconds by a decimal point;
* e.g. c1a089bd.fc904f6d <=> Tue, Dec 10 2002 10:41:49.986
*
* @return NTP timestamp 64-bit long value as hex string with seconds
* separated by fractional seconds.
*/
@Override
public String toString()
{
return toString(ntpTime);
}
/***
* Left-pad 8-character hex string with 0's
*
* @param buf - StringBuffer which is appended with leading 0's.
* @param l - a long.
*/
private static void appendHexString(StringBuffer buf, long l)
{
String s = Long.toHexString(l);
for (int i = s.length(); i < 8; i++)
buf.append('0');
buf.append(s);
}
/***
* Converts 64-bit NTP timestamp value to a String
.
* The NTP timestamp value is represented as hex string with
* seconds separated by fractional seconds by a decimal point;
* e.g. c1a089bd.fc904f6d <=> Tue, Dec 10 2002 10:41:49.986
*
* @return NTP timestamp 64-bit long value as hex string with seconds
* separated by fractional seconds.
*/
public static String toString(long ntpTime)
{
StringBuffer buf = new StringBuffer();
// high-order second bits (32..63) as hexstring
appendHexString(buf, (ntpTime >>> 32) & 0xffffffffL);
// low-order fractional seconds bits (0..31) as hexstring
buf.append('.');
appendHexString(buf, ntpTime & 0xffffffffL);
return buf.toString();
}
/***
* Converts this TimeStamp
object to a String
* of the form:
* * See java.text.SimpleDataFormat for code descriptions. * * @return a string representation of this date. */ public String toDateString() { DateFormat formatter = null; if (simpleFormatter != null) { formatter = simpleFormatter.get(); } if (formatter == null) { // No cache yet, or cached formatter GC'd formatter = new SimpleDateFormat(NTP_DATE_FORMAT, Locale.US); formatter.setTimeZone(TimeZone.getDefault()); simpleFormatter = new SoftReference* EEE, MMM dd yyyy HH:mm:ss.SSS
TimeStamp
object to a String
* of the form:
* * See java.text.SimpleDataFormat for code descriptions. * * @return a string representation of this date in UTC. */ public String toUTCString() { DateFormat formatter = null; if (utcFormatter != null) formatter = utcFormatter.get(); if (formatter == null) { // No cache yet, or cached formatter GC'd formatter = new SimpleDateFormat(NTP_DATE_FORMAT + " 'UTC'", Locale.US); formatter.setTimeZone(TimeZone.getTimeZone("UTC")); utcFormatter = new SoftReference* EEE, MMM dd yyyy HH:mm:ss.SSS UTC
TimeStamp
to be compared.
* @return the value 0
if the argument TimeStamp is equal to
* this TimeStamp; a value less than 0
if this TimeStamp
* is numerically less than the TimeStamp argument; and a
* value greater than 0
if this TimeStamp is
* numerically greater than the TimeStamp argument
* (signed comparison).
*/
public int compareTo(TimeStamp anotherTimeStamp)
{
long thisVal = this.ntpTime;
long anotherVal = anotherTimeStamp.ntpTime;
return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1));
}
/***
* Compares this TimeStamp to another Object. If the Object is a TimeStamp,
* this function behaves like compareTo(TimeStamp)
. Otherwise,
* it throws a ClassCastException
(as TimeStamps are comparable
* only to other TimeStamps).
*
* @param o the Object
to be compared.
* @return the value 0
if the argument is a TimeStamp
* numerically equal to this TimeStamp; a value less than
* 0
if the argument is a TimeStamp numerically
* greater than this TimeStamp; and a value greater than
* 0
if the argument is a TimeStamp numerically
* less than this TimeStamp.
* @exception ClassCastException if the argument is not a
* TimeStamp
.
* @see java.lang.Comparable
*/
public int compareTo(Object o)
{
return compareTo((TimeStamp) o);
}
}