如何从Android的互联网获取当前时间
我正在制作一个应用程序,我想从互联网上获取当前时间。
我知道如何从使用System.currentTimeMillis
的设备中获取时间,甚至在search了很多之后,我也没有得到任何关于如何从networking获取它的线索。
您可以使用下面的程序从互联网时间服务器获得时间
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("nist.time.nosc.us"); System.out.println(client.getDate()); } finally { client.disconnect(); } } catch (IOException e) { e.printStackTrace(); } } }
1.你需要Apache Commons Net库才能正常工作。 下载库并添加到您的项目构buildpath。
(或者你也可以在这里使用修剪过的Apache Commons Net Library: https : //www.dropbox.com/s/bjxjv7phkb8xfhh/commons-net-3.1.jar 。这足以让你从互联网上获得时间)
运行程序。 您将获得打印在您的控制台上的时间。
这里是我为你创build的一个方法,你可以在你的代码中使用它
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; }
您将需要访问以XML或JSON格式提供当前时间的Web服务。
如果你没有find这种types的服务,你可以从一个网页parsing时间,比如http://www.timeanddate.com/worldclock/ ,或者使用一个简单的PHP页面在服务器上托pipe自己的时间服务例。
查阅JSoupparsingHTML页面。
我认为最好的解决scheme是使用SNTP,尤其是Android本身的SNTP客户端代码,例如: http : //grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/ 4.1.1_r1 /安卓/ NET / SntpClient.java /
我相信Android在networking不可用时使用SNTP进行自动date/时间更新(例如wifi平板电脑)。
我认为它比其他解决scheme更好,因为它使用SNTP / NTP而不是Apache TimeTCPClient使用的时间协议(RFC 868)。 我对RFC 868并不了解,但是NTP更新,似乎已经超越了它,并且被更广泛地使用。 我相信没有蜂窝的Android设备使用NTP。
另外,因为它使用套接字。 一些提出的解决scheme使用HTTP,所以他们将失去一些准确性。
上面的东西没有从我的工作。 这是我结束了(与Volley);
这个例子也转换到另一个时区。
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;
Gradle中inputVolley:
compile 'com.android.volley:volley:1.0.0'
如果您不关心毫秒准确性,并且您已经使用Google Firebase或者不介意使用它(它们提供免费套餐),请查看: https : //firebase.google.com/docs/database /安卓/离线function#时钟偏斜
基本上,firebase数据库有一个字段,提供设备时间和Firebase服务器时间之间的偏移值。 您可以使用此偏移来获取当前时间。
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"); } });
正如我所说,基于networking延迟将是不准确的。