View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  
21  package org.apache.directory.server.ntp.messages;
22  
23  
24  import java.nio.ByteBuffer;
25  import java.text.SimpleDateFormat;
26  import java.util.Date;
27  import java.util.TimeZone;
28  
29  
30  /**
31   * NTP timestamps are represented as a 64-bit unsigned fixed-point number,
32   * in seconds relative to 0h on 1 January 1900. The integer part is in the
33   * first 32 bits and the fraction part in the last 32 bits. In the fraction
34   * part, the non-significant low order can be set to 0.
35   * 
36   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
37   * @version $Rev: 547539 $, $Date: 2007-06-15 08:08:06 +0200 (Fr, 15 Jun 2007) $
38   */
39  public class NtpTimeStamp
40  {
41      /**
42       * The number of milliseconds difference between the Java epoch and
43       * the NTP epoch ( January 1, 1900, 00:00:00 GMT ).
44       */
45      private static final long NTP_EPOCH_DIFFERENCE = -2208988800000L;
46  
47      private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );
48      private static final SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS z" );
49  
50      static
51      {
52          dateFormat.setTimeZone( UTC_TIME_ZONE );
53      }
54  
55      private long seconds = 0;
56      private long fraction = 0;
57  
58  
59      /**
60       * Creates a new instance of NtpTimeStamp that represents the time "right now."
61       */
62      public NtpTimeStamp()
63      {
64          this( new Date() );
65      }
66  
67  
68      /**
69       * Creates a new instance of NtpTimeStamp that represents the given {@link Date}.
70       *
71       * @param date
72       */
73      public NtpTimeStamp( Date date )
74      {
75          long msSinceStartOfNtpEpoch = date.getTime() - NTP_EPOCH_DIFFERENCE;
76  
77          seconds = msSinceStartOfNtpEpoch / 1000;
78          fraction = ( ( msSinceStartOfNtpEpoch % 1000 ) * 0x100000000L ) / 1000;
79      }
80  
81  
82      /**
83       * Creates a new instance of NtpTimeStamp from encoded data in a {@link ByteBuffer}.
84       *
85       * @param data
86       */
87      public NtpTimeStamp( ByteBuffer data )
88      {
89          for ( int ii = 0; ii < 4; ii++ )
90          {
91              seconds = 256 * seconds + makePositive( data.get() );
92          }
93  
94          for ( int ii = 4; ii < 8; ii++ )
95          {
96              fraction = 256 * fraction + makePositive( data.get() );
97          }
98      }
99  
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 }