How to get current time from internet in android
Asked Answered
N

8

37

I am making an app in which I want to get the current time from internet.

I know how to get the time from the device using System.currentTimeMillis, and even after searching a lot, I did not get any clue about how to get it from internet.

Nonintervention answered 25/10, 2012 at 8:40 Comment(2)
Check this may help youCentimeter
Sorry Sir,i am new to android and that example is difficult to understand.Nonintervention
P
29

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.

Pullet answered 25/10, 2012 at 10:9 Comment(5)
Can you please tell me the name of any reliable time server ?Nonintervention
@Nonintervention all the listed servers are reliable ones, as it is maintained by NIST. The one i have used is working fine. But as NIST site says, you should not hardcode any urls. You can provide 4 or 5 time servers in a property file or sqlite db. Then start from the first url and wait for result (or time-out). If it got timedout, then try the next link and so on. If all links failed (very rare chance), you can show a message to user. (or start from beginning)Pullet
I am getting no such address found exception on this web address.Nonintervention
have you solved this issue as of now ? which web address are you talking about ?Pullet
Since those links on the answers are obsolete .. use this link to download : java2s.com/Code/Jar/c/Downloadcommonsnet33jar.htmGiagiacamo
M
8

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;
}
Mitzvah answered 25/10, 2012 at 10:10 Comment(3)
Nice code sample. However, are you sure you are authorized to use the YahooDemo app id in a production application ?Bascomb
Ya, I got it from here developer.yahoo.com/util/timeservice/V1/getTime.html you need to have an App ID, developer.yahoo.com/faq/index.html#appid I have used the default linkMitzvah
I have used this method. But it very unreliable! Often can't get timeNeff
D
8

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.

Daystar answered 14/12, 2016 at 10:11 Comment(4)
This field will be cached, so if you want to get this value multiple times, you need to do FirebaseDatabase.getInstance().goOffline() and goOnline()Homogenous
Oh! Thanks for letting me know.Daystar
Thanks, this was really helpfulPippy
Can we get date in firebase as same? could you help regarding thisAvulsion
A
3

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.

Analogous answered 26/1, 2013 at 0:28 Comment(0)
A
1

You will need to have access to a webservice that provides current time in XML or JSON format.

If you don't find such type of service, you could parse the time from a web page, like http://www.timeanddate.com/worldclock/, or host your own time service on a server using a simple PHP page for example.

Check out JSoup for the parsing of HTML pages.

Astrodynamics answered 25/10, 2012 at 9:17 Comment(4)
Please tell me sir how to parse time from this website.It will be very helpful for a beginner like me.Thanks in advance.Nonintervention
Its services are very costly sir.Can you please give me the link of some free time api service provider?Nonintervention
Please have a look at JSoup documentation, try some code, and get back to us if you encounter problems.Bascomb
Note that although you can parse TimeAndDate using Jsoup, the source of that webpage says "scripts and programs that download content transparent to the user are not allowed without permission". Make sure you ask for permission to avoid any legal actions against you in the future.Airplane
G
1

Nothing from the above worked from me. This is what I ended up with (with Volley);
This example also converts to another timezone.

    Long time = null;
    RequestQueue queue = Volley.newRequestQueue(this);
    String url ="http://www.timeapi.org/utc/now";

    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    try {
                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
                        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
                        Date date = simpleDateFormat.parse(response);

                        TimeZone tz = TimeZone.getTimeZone("Israel");
                        SimpleDateFormat destFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        destFormat.setTimeZone(tz);

                        String result = destFormat.format(date);

                        Log.d(TAG, "onResponse: " + result.toString());
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.w(TAG, "onErrorResponse: "+ error.getMessage());
        }
    });
    queue.add(stringRequest);
    return time;

Import Volley in gradle:

compile 'com.android.volley:volley:1.0.0'
Gemoets answered 13/7, 2016 at 12:5 Comment(2)
But to fetch the response from the above api , it will take to few seconds right ? how about the elapsed time ..??Bores
Decent solution if we don't mind few seconds inaccuracy. Good trade off. But I wonder who backs timeapi.org and how likely it can go offline.Daystar
S
0

There is a clear answer available already in Stackoverflow

https://mcmap.net/q/426655/-how-to-get-network-datetime-now

Call this url or use as GET API

http://worldtimeapi.org/api/timezone/Asia/Kolkata

the response will be like

{
  "abbreviation": "IST",
  "client_ip": "45.125.117.46",
  "datetime": "2022-02-26T10:50:43.406519+05:30",
 }
Switchman answered 26/2, 2022 at 5:40 Comment(0)
Q
0

This thing works best for my apps. I use jsoup to search the google time and gets current time and then I compare the phone time with google time. So if these time are different you can stop user using a dialogbox or alertbox to tell them the times have changed. You can implement in MainActivity to check this condition. Here is a snippet so you get the idea more clearly.

public class HomeActivity extends AppCompatActivity {
    //phoneDate and phoneTime to get current phone date and time
    String phoneDate = new SimpleDateFormat("dd MMM yyyy ").format(clnd.getTime()).trim();
    String phoneTime = new SimpleDateFormat("hh:mm a").format(clnd.getTime()).trim();
    String googleDate;
    String googleTime ;
    @Override
    protected void onCreate(Bundle _savedInstanceState) {
    super.onCreate(_savedInstanceState);
    setContentView(R.layout.home);
    Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        try  {
                        //URL to search time
                        String url = "https://www.google.co.in/search?q=time";

                        Document document  = Jsoup.connect(url).get();
                        org.jsoup.select.Elements time = document.getElementsByClass("gsrt vk_bk FzvWSb YwPhnf");
                        org.jsoup.select.Elements date = document.getElementsByClass("KfQeJ");

                        Log.d("HTML", "google date" + String.format(date.text()));
                        Log.d("HTML", "google time" + time.text());

                        googleDate = date.text().trim();
                        googleTime = time.text().trim();
                        //'0'is not present when hour is single digit 
                        char second = googleTime.charAt(1);
                        if(second == ':'){
                        googleTime = "0" + googleTime;
                    }
                    Log.d("Proper format", "google time" + googleTime);

                    Log.d("Date", "your current url when webpage loading.." + phoneDate);
                    Log.d("Time", "your current url when webpage loading.." + phoneTime);

                    if(googleDate.contains(phoneDate) && googleTime.equals(phoneTime)){
                        Log.d("Time", "your current url when webpage loading.." + " true");
                    }else{
                        Log.d("Time", "your current url when webpage loading.." + " false");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
    }   
}
Quipster answered 20/5, 2022 at 13:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.