Gemalto is now part of the Thales Group, find out more.

You are here

How to obtain the time of the internet with Java (RFC868)

FAQ, March 14, 2014 - 9:19pm, 9746 views

Usually the devie will not be always powered on and connected to the network, it is not a GPS inside device or just we had not implemented the RTC in the PCB.

In these cases in every power the time will be reseted.

How to know the time,

  1. Some netwrok carriers have implementations to obtain the time over USSD, other posibility is to send an SMS to the device; costly in any case.
  2. Implement the NTP(Network Time protocol) using and UDP socket implementation.Recomended for high precition application. It is more hard to implement
  3. Obtain the time from a internet server with protocoll RFC868. This protocoll is easy of implement and there is multiple servers in internet availables. Example of available servers:

time-a.timefreq.bldrdoc.gov
time-b.timefreq.bldrdoc.gov
time-c.timefreq.bldrdoc.gov
utcnist.colorado.edu
time-nw.nist.gov
nist1.nyc.certifiedtime.com
nist1.dc.certifiedtime.com
nist1.sjc.certifiedtime.com
nist1.datum.com
ntp2.cmc.ec.gc.ca
ntps1-0.uni-erlangen.de
ntps1-1.uni-erlangen.de
ntps1-2.uni-erlangen.de
ntps1-0.cs.tu-berlin.de
time.ien.it
ptbtime1.ptb.de
ptbtime2.ptb.de

Who works:

These servers are lisening the ports TCP/UDP 37 for inquiries. Description of the procedure for the socket TCP 37:

  • Perform a connection to the time server using the port TCP 37
  • After the connection the server will send to the module a 4 byte(32 bit) packet with the date/time ( In fact the information received is the seconds trancurred since 00:00:00 1/1/1900)
  • The time server closes the socket

The time information will have a deviation of 0-2 seconds, depending of the connection speed and the transmition times,

How to extract the date of the 4 Bytes:

// Calculate the seconds from 1/1/1990

secondsSince1900 = buffer[0]*16777216 + buffer[1]*65536 + buffer[2]*256 + buffer[3];

//Calculate the seconds since 1/1/1970 and convert the value to miliseconds. Reason the Java Constructor of the Date Class needs the value in milisedonds and since 1/1/1970, that's 2208988800 seconds

miliSecondsSince1970 = secondsSince1900 - Long.parseLong("2208988800");

miliSecondsSince1970 = miliSecondsSince1970 * 1000;

// Obtain the actual time (GMT)

Date = new Date (miliSecondsSince1970);

Sytem.out.println ("Date/Time: " + datetoString());

The complete java code:

//Example to obtain the time from and RFC868 internet server

package src;

import java.util.*;

import java.io.InputStream;
import java.io.OutputStream;

import javax.microedition.io.Connector;
import javax.microedition.io.SocketConnection;

import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class main extends MIDlet 
{
	//Define the necessary class for the connectionn
	SocketConnection scon = null;
	InputStream is = null;
	OutputStream os = null;

	protected void startApp() throws MIDletStateChangeException 
	{
		long[] buffer = new long[4];
		int i=0;
		boolean readedTime = false;
		long secondsSince1900=0;
		long miliSecondsSince1970=0;
		Date date = null;
		
		
		//Some time RFC868 servers.
		String timeServerInternet="time-a.timefreq.bldrdoc.gov";
		/*
		String timeServerInternet="time-a.timefreq.bldrdoc.gov"
		String timeServerInternet="time-b.timefreq.bldrdoc.gov"
		String timeServerInternet="time-c.timefreq.bldrdoc.gov"
		String timeServerInternet="utcnist.colorado.edu"
		String timeServerInternet="time-nw.nist.gov"
		String timeServerInternet="nist1.nyc.certifiedtime.com"
		String timeServerInternet="nist1.dc.certifiedtime.com"
		String timeServerInternet="nist1.sjc.certifiedtime.com"
		String timeServerInternet="nist1.datum.com"
		String timeServerInternet="ntp2.cmc.ec.gc.ca"
		String timeServerInternet="ntps1-0.uni-erlangen.de"
		String timeServerInternet="ntps1-1.uni-erlangen.de"
		String timeServerInternet="ntps1-2.uni-erlangen.de"
		String timeServerInternet="ntps1-0.cs.tu-berlin.de"
		String timeServerInternet="time.ien.it"
		String timeServerInternet="ptbtime1.ptb.de"
		String timeServerInternet="ptbtime2.ptb.de"
		 */
		
		try
		{
			
			System.out.println(“App Started”);

			//Open connection. Use the data related to your carrier
			//Connect_APM
			//connection_user
			//connection_password

			scon = (SocketConnection) Connector.open("socket://" 
				+ timeServerInternet + "37;bearer_type=GPRS;
				access_point=connect_APN;username=connection_user;
				password=connection_password;dns=000.000.000.000;
				timeout=0");

			is = scon.openInputStream();
			os = scon.openOutputStream();

			
			//While until the 32 bits are received. 			
			//No exceptions implemented
			//(server no available, wrong connection data, etc)
			//—>that’s just an example ;)

			while (readedTime==false)
			{
				//Assumption that the data will be received. 
				//As mention not exception control implemented
				if (is.available() == 4) 
				{
					//Read the 4 bytes (32 bits) from the server
					for (i=0;i<4;i++) buffer[i]=is.read();
					//Once finish we can exit of the loop. 
					//Maybe a while implementation is more elegant ;)
					readedTime=true;
				}
				Thread.sleep(10);
			}

			
			//Close the sockets and the connection
			is.close();
			os.close();
			scon.close();

			
			//Calculate the seconds from 1/1/1990

			secondsSince1900=buffer[0]*16777216 + buffer[1]*65536 + 
					buffer[2]*256 + buffer[3];
			
			
			//Calculate the seconds since 1/1/1970
			//Convert the value to miliseconds.
			//Reason the Java Constructor of the 
			//Date Class needs the value in miliseconds and since 1/1/1970
			//that's 2208988800 seconds

			miliSecondsSince1970=secondsSince1900-Long.parseLong("2208988800");
			
			miliSecondsSince1970=miliSecondsSince1970*1000;

			
			//Obtain the actual time (GMT) 

			date = new Date(miliSecondsSince1970);
			System.out.println(“Date/Time:  " + date.toString());
			
			
			//End of the program 

			destroyApp(true);
			
			
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

	}



	protected void pauseApp() {}

	protected void destroyApp(boolean arg0) throws MIDletStateChangeException 
	{
		System.out.println(“End of the application”);		
		notifyDestroyed();
	}

}

Regards

Alopez

            

Alopez's picture
Alopez

Hi,

For the case of UDP implementation the procedure is:

a)Perform a connection to the time server using the port UDP 37
b)Send a empty datagram to the socket UDP 37 of the server
c)The server will send to the module a 4 byte(32 bit) packet with the date/time ( In fact the information received is the seconds trancurred since 00:00:00 1/1/1900)

The server listens for a datagram on port 37. When a datagram
arrives, the server returns a datagram containing the 32-bit time
value. If the server is unable to determine the time at its site, it
should discard the arriving datagram and make no reply.

Regards

Alopez

Somewhere over the rainbow!!! Looking for the Oz Land!!!

GaryG's picture
GaryG

Hi,

I have received the time with no problems but now I am trying to get the time of the EHS6 by using the java.util.Date.getTime(); Even if I try and setTime I get the error.

When debugging the program crashed with the following info:

java.lang.NullPointerException: 0
- Titan.Titan.startApp(Titan.java:51)
- javax.microedition.midlet.MIDletTunnelImpl.callStartApp(), bci=1
- com.sun.midp.midlet.MIDletPeer.startApp(), bci=5
- com.sun.midp.midlet.MIDletStateHandler.startSuite(), bci=261
- com.sun.midp.main.AbstractMIDletSuiteLoader.startSuite(), bci=38
- com.sun.midp.main.CldcMIDletSuiteLoader.startSuite(), bci=5
- com.sun.midp.main.AbstractMIDletSuiteLoader.runMIDletSuite(), bci=134
- com.sun.midp.main.AppIsolateMIDletSuiteLoader.main(), bci=26

Please bear with me as I am new with Java and I am still trying to find my feet.

Regards,

Gary

Alopez's picture
Alopez

Hi,
The way to obtain the date of the Java system can be implemented in this way

import java.util.Date;

public class Tiempo {

public Tiempo() {
// TODO Auto-generated constructor stub
}

public static void main(String[] args) {
// TODO Auto-generated method stub
Date Fecha=new Date();
System.out.println(Integer.toString(Fecha.getHours())); ;
System.out.println(Integer.toString(Fecha.getYear()));
System.out.println(Integer.toString(Fecha.getDay()));
System.out.println(Integer.toString(Fecha.getMonth()));

}

}

Take in consideration that if the device has not implemented the RTC, the date will be reset in each power on cycle

Regards

Alopez

Somewhere over the rainbow!!! Looking for the Oz Land!!!

graydaemon's picture
graydaemon

Hi,

another option is get time as string from TCP port 13 (from e.g. time.nist.gov:13) and parse it, you can try this from PC

---------------

> telnet time.nist.gov 13

56997 14-12-06 15:50:04 00 0 0 842.5 UTC(NIST) *

Connection to host lost

------------------

Sorry, have no pure short and well formatted Java example for this test right now.

Alopez

Contributors

Profile Picture
Alopez