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 08:08:06 +0200 (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 }