How to get current time from internet in android

If you don't care for millisecond accuracy, and if you are already using google firebase or don't mind using it (they provide a free tier), check this out: https://firebase.google.com/docs/database/android/offline-capabilities#clock-skew

Basically, firebase database has a field that provides offset value between the device time and the firebase server time. You can use this offset to get the current time.

DatabaseReference offsetRef = FirebaseDatabase.getInstance().getReference(".info/serverTimeOffset");
offsetRef.addValueEventListener(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    double offset = snapshot.getValue(Double.class);
    double estimatedServerTimeMs = System.currentTimeMillis() + offset;
  }

  @Override
  public void onCancelled(DatabaseError error) {
    System.err.println("Listener was cancelled");
  }
});

As I said, it will be inaccurate based on network latency.


I think the best solution is to use SNTP, in particular the SNTP client code from Android itself, e.g.: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/net/SntpClient.java/

I believe Android uses SNTP for automatic date/time updates when a cell network is not available (e.g. wifi tablets).

I think it is better then the other solutions because it uses SNTP/NTP rather then the Time protocol (RFC 868) used by the Apache TimeTCPClient. I don't know anything bad about RFC 868, but NTP is newer and seems to have superceeded it and is more widely used. I believe that Android devices that don't have cellular uses NTP.

Also, because it uses sockets. Some of the solutions proposed use HTTP so they will lose something in their accuracy.


You can get time from internet time servers using the below program

import java.io.IOException;

import org.apache.commons.net.time.TimeTCPClient;

public final class GetTime {

    public static final void main(String[] args) {
        try {
            TimeTCPClient client = new TimeTCPClient();
            try {
                // Set timeout of 60 seconds
                client.setDefaultTimeout(60000);
                // Connecting to time server
                // Other time servers can be found at : http://tf.nist.gov/tf-cgi/servers.cgi#
                // Make sure that your program NEVER queries a server more frequently than once every 4 seconds
                client.connect("time.nist.gov");
                System.out.println(client.getDate());
            } finally {
                client.disconnect();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.You would need Apache Commons Net library for this to work. Download the library and add to your project build path.

(Or you can also use the trimmed Apache Commons Net Library here : https://www-us.apache.org/dist//commons/net/binaries/commons-net-3.6-bin.tar.gz This is enough to get time from internet )

2.Run the program. You will get the time printed on your console.


Here is a method that i have created for you you can use this in your code

public String getTime() {
try{
    //Make the Http connection so we can retrieve the time
    HttpClient httpclient = new DefaultHttpClient();
    // I am using yahoos api to get the time
    HttpResponse response = httpclient.execute(new
    HttpGet("http://developer.yahooapis.com/TimeService/V1/getTime?appid=YahooDemo"));
    StatusLine statusLine = response.getStatusLine();
    if(statusLine.getStatusCode() == HttpStatus.SC_OK){
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        response.getEntity().writeTo(out);
        out.close();
        // The response is an xml file and i have stored it in a string
        String responseString = out.toString();
        Log.d("Response", responseString);
        //We have to parse the xml file using any parser, but since i have to 
        //take just one value i have deviced a shortcut to retrieve it
        int x = responseString.indexOf("<Timestamp>");
        int y = responseString.indexOf("</Timestamp>");
        //I am using the x + "<Timestamp>" because x alone gives only the start value
        Log.d("Response", responseString.substring(x + "<Timestamp>".length(),y) );
        String timestamp =  responseString.substring(x + "<Timestamp>".length(),y);
        // The time returned is in UNIX format so i need to multiply it by 1000 to use it
        Date d = new Date(Long.parseLong(timestamp) * 1000);
        Log.d("Response", d.toString() );
        return d.toString() ;
    } else{
        //Closes the connection.
        response.getEntity().getContent().close();
        throw new IOException(statusLine.getReasonPhrase());
    }
}catch (ClientProtocolException e) {
Log.d("Response", e.getMessage());
}catch (IOException e) {
Log.d("Response", e.getMessage());
}
return null;
}

Tags:

Time

Android