0

I am trying to build a sample application which will show a proof of concept for synchronizing the time with an RFC 868 compliant time server.

So far, using the Java Socket API, I am able to connect and query the server and do get the response from the server, but it is not in human readable format.

The response I get is: �)6 I think the response is coming in binary format (not sure though). RFC 868 says that Send the time as a 32 bit binary number.

My questions are:

  1. How do I parse this response?
  2. Apart from this approach of mine, I'd like to know if there is any other recommended approach which I should take to achieve this.

Thanks in advance.

3
  • 32 bits makes 4 bytes (32/8). Have an int variable defined as 0, then in a loop each time shift it 8 bits and apply bitwise OR to it with the next subsequent byte from the stream. Commented Apr 6, 2012 at 12:01
  • Why RFC 868? Almost everything uses NTP these days. Commented Apr 6, 2012 at 13:52
  • @Zoredache: Yep, I agree with you. Its just for my learning purpose... i.e. I want to learn about this protocol! Commented Apr 7, 2012 at 8:30

2 Answers 2

2

1) How do I parse this response?

Check out the source code of TimeTCPClient from Apache Commons Net library:

public long getTime() throws IOException {
  DataInputStream input;
  input = new DataInputStream(_input_);
  return (input.readInt() & 0xffffffffL);
}

public Date getDate() throws IOException {
  return new Date((getTime() - SECONDS_1900_TO_1970)*1000L);
}

2) Apart from this approach of mine, I'd like to know if there is any other recommended approach which I should take to achieve this.

Use Apache Commons Net Library, check out the API of TimeTCPClient.

Apache Commons Net home page, hope this helps.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you that really helped! When I update the time by 1 second inside a thread.. it actually starts with the correct time, but then eventually starts lagging behind few milliseconds, which subsequently becomes few seconds, and grows on. Is this something common with RFC 868 compliant time servers? Thanks
2

As stated in the RFC this is the seconds since 1900-01-01T00:00:00. For Java convert it to a Long,change the base date to 1970-01-01T00:00:00, and multiply by 1000 to get the date. Then you can create a new Date using this value.

Wrap your socket input stream to a DataInputStream and read an into rfsOffset (I used a constant). Then you can do something like:

int rfcOffset = -752253627; // Fri Apr 06 11:00:32 EDT 2012
// Current offsets will be negative convert to long positive value
long offsetSecs = rfcOffset + 4294967296L; 
System.out.println(offsetSecs);
// Adjust time base from 1900 to 1970 and convert to millis
long offsetMillis = ( offsetSecs - 2208988800L)* 1000L; 
System.out.println(offsetMillis);
Date rfcDate = new Date(offsetMillis);
System.out.println(rfcDate.toString());

Note: this only works until 2036 and time will be off by some number of milliseconds.

EDIT: RFC 868 is an old protocol and is no longer considered a good time source for synchronization. A good time source will us NTP and will return the correct second. It may be off a few milliseconds, but is normally accurate withing 10 milliseconds. Many hardware clocks drift significantly, and I have seen significant drift from systems with inaccurate clocks (even with NTP running(). NTP will correct a drifting clock, but needs a few minutes to determine the required shift.

EDIT2: While RFC 868 is old, it may be good enough to set the time on a cell phone to the nearest second without requiring a background process. This shouldn't be necessary if your cell phone can sync to a signal sent by your provider.

7 Comments

ah.. just wanted to confirm - When I update the time by 1 second inside a thread.. it actually starts with the correct time, but then eventually starts lagging behind few milliseconds, which subsequently becomes few seconds, and grows on. Is this something common with RFC 868 compliant time servers? Thanks.
As noted above, this sounds like a clock drift problem on your source.
Hi, I am not too sure if I understood you but do you mean the Time Server when you say source. If yes, then I'd like to say that I only query the Time Server once, and then using the initial timestamp, I update the time by each second inside a thread.
Yes I meant the Time Server when I said source. If you are doing what I think you are doing, then I would expect the time to drift. The rate of drift will depend on how long it takes to do your update process, and how busy your computer is. Java Garbage Collection can add additional drift.
I didn't see your code. If you do something like update display, sleep 1.0, add 1 second to time you are not accounting for the time your update and increment take. Also the sleep is not guaranteed to end immediately at the end of the wait time. It is tricky to get this right. To do it right you need to determine the required sleep time before each sleep. This involves checking the device's clock.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.