001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020
021 package org.apache.directory.server.ntp.messages;
022
023
024 import java.nio.ByteBuffer;
025 import java.text.SimpleDateFormat;
026 import java.util.Date;
027 import java.util.TimeZone;
028
029
030 /**
031 * NTP timestamps are represented as a 64-bit unsigned fixed-point number,
032 * in seconds relative to 0h on 1 January 1900. The integer part is in the
033 * first 32 bits and the fraction part in the last 32 bits. In the fraction
034 * part, the non-significant low order can be set to 0.
035 *
036 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
037 * @version $Rev: 547539 $, $Date: 2007-06-15 09:08:06 +0300 (Fri, 15 Jun 2007) $
038 */
039 public class NtpTimeStamp
040 {
041 /**
042 * The number of milliseconds difference between the Java epoch and
043 * the NTP epoch ( January 1, 1900, 00:00:00 GMT ).
044 */
045 private static final long NTP_EPOCH_DIFFERENCE = -2208988800000L;
046
047 private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );
048 private static final SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS z" );
049
050 static
051 {
052 dateFormat.setTimeZone( UTC_TIME_ZONE );
053 }
054
055 private long seconds = 0;
056 private long fraction = 0;
057
058
059 /**
060 * Creates a new instance of NtpTimeStamp that represents the time "right now."
061 */
062 public NtpTimeStamp()
063 {
064 this( new Date() );
065 }
066
067
068 /**
069 * Creates a new instance of NtpTimeStamp that represents the given {@link Date}.
070 *
071 * @param date
072 */
073 public NtpTimeStamp( Date date )
074 {
075 long msSinceStartOfNtpEpoch = date.getTime() - NTP_EPOCH_DIFFERENCE;
076
077 seconds = msSinceStartOfNtpEpoch / 1000;
078 fraction = ( ( msSinceStartOfNtpEpoch % 1000 ) * 0x100000000L ) / 1000;
079 }
080
081
082 /**
083 * Creates a new instance of NtpTimeStamp from encoded data in a {@link ByteBuffer}.
084 *
085 * @param data
086 */
087 public NtpTimeStamp( ByteBuffer data )
088 {
089 for ( int ii = 0; ii < 4; ii++ )
090 {
091 seconds = 256 * seconds + makePositive( data.get() );
092 }
093
094 for ( int ii = 4; ii < 8; ii++ )
095 {
096 fraction = 256 * fraction + makePositive( data.get() );
097 }
098 }
099
100
101 /**
102 * Writes this {@link NtpTimeStamp} to the given {@link ByteBuffer}.
103 *
104 * @param buffer
105 */
106 public void writeTo( ByteBuffer buffer )
107 {
108 byte[] bytes = new byte[8];
109
110 long temp = seconds;
111 for ( int ii = 3; ii >= 0; ii-- )
112 {
113 bytes[ii] = ( byte ) ( temp % 256 );
114 temp = temp / 256;
115 }
116
117 temp = fraction;
118 for ( int ii = 7; ii >= 4; ii-- )
119 {
120 bytes[ii] = ( byte ) ( temp % 256 );
121 temp = temp / 256;
122 }
123
124 buffer.put( bytes );
125 }
126
127
128 public String toString()
129 {
130 long msSinceStartOfNtpEpoch = seconds * 1000 + ( fraction * 1000 ) / 0x100000000L;
131 Date date = new Date( msSinceStartOfNtpEpoch + NTP_EPOCH_DIFFERENCE );
132
133 synchronized ( dateFormat )
134 {
135 return "org.apache.ntp.message.NtpTimeStamp[ date = " + dateFormat.format( date ) + " ]";
136 }
137 }
138
139
140 public boolean equals( Object o )
141 {
142 if ( this == o )
143 {
144 return true;
145 }
146
147 if ( !( o instanceof NtpTimeStamp ) )
148 {
149 return false;
150 }
151
152 NtpTimeStamp that = ( NtpTimeStamp ) o;
153 return ( this.seconds == that.seconds ) && ( this.fraction == that.fraction );
154 }
155
156
157 private int makePositive( byte b )
158 {
159 int byteAsInt = b;
160 return ( byteAsInt < 0 ) ? 256 + byteAsInt : byteAsInt;
161 }
162 }