2012-10-25 66 views
14

我正在製作一個應用程序,我想從互聯網上獲取當前時間。如何在Android上從互聯網獲取當前時間

我知道如何使用System.currentTimeMillis設備獲取時間,甚至搜索了很多之後,我沒有得到有關如何從互聯網上獲取任何線索。

+0

檢查[this](http://stackoverflow.com/questions/2817475/java-get-current-date-and-time-from-server-not-system-clock)可能會幫助你 –

+0

對不起,先生,我我對android很陌生,而且這個例子很難理解。 – user1726619

回答

15

您可以使用下面的程序

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.You需要Apache Commons Net庫這個工作得到網絡時間服務器的時間。 Download該庫並添加到您的項目構建路徑。

(或者你也可以在這裏使用的修剪Apache的百科全書網絡庫:https://www.dropbox.com/s/bjxjv7phkb8xfhh/commons-net-3.1.jar這足以從互聯網上獲取時間)

2.Run程序。您將獲得打印在控制檯上的時間。

+0

你能告訴我任何可靠的時間服務器的名稱嗎? – user1726619

+1

@ user1726619所有列出的服務器都是可靠的,因爲它由NIST維護。我用過的那個工作正常。但正如NIST網站所說,你不應該對任何網址進行硬編碼。您可以在屬性文件或sqlite數據庫中提供4或5個時間服務器。然後從第一個url開始,等待結果(或超時)。如果超時,則嘗試下一個鏈接等。如果所有鏈接都失敗(非常難得),您可以向用戶顯示一條消息。 (或從頭開始) – sunil

+1

我在這個網址上沒有發現這樣的地址例外。 – user1726619

1

您將需要訪問以XML或JSON格式提供當前時間的Web服務。

如果您沒有找到這種類型的服務,您可以從網頁(如http://www.timeanddate.com/worldclock/)解析時間,或者使用簡單的PHP頁面在服務器上託管您自己的時間服務。

查看JSoup解析HTML頁面。

+0

請告訴我先生,如何解析本網站的時間,對於像我這樣的初學者會有幫助。提前感謝。 – user1726619

+0

它的服務是非常昂貴的先生。請給我一些空閒時間api服務提供商的鏈接? – user1726619

+0

請看JSoup文檔,嘗試一些代碼,如果遇到問題請回復我們。 –

7

這裏是我創造了你 你可以在你的代碼中使用此

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; 
} 
+0

不錯的代碼示例。但是,您確定您有權在生產應用程序中使用'YahooDemo'應用程序ID嗎? –

+0

雅,我從這裏得到它http://developer.yahoo.com/util/timeservice/V1/getTime.html 你需要一個應用程序ID, http://developer.yahoo.com/faq/index .html#appid 我已經使用了默認鏈接 –

+0

我已經使用了這個方法。但它非常不可靠!通常無法獲得時間 – XXX

1

我認爲最好的辦法是使用SNTP,特別是SNTP客戶端代碼的Android本身,例如方法: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/net/SntpClient.java/

我相信當單元網絡不可用(例如wifi平板電腦)時,Android使用SNTP進行自動日期/時間更新。

我認爲它比其他解決方案更好,因爲它使用SNTP/NTP,而不是Apache TimeTCPClient使用的時間協議(RFC 868)。我對RFC 868並不瞭解,但NTP更新,似乎已經超越了它,並且使用更廣泛。我相信沒有蜂窩的Android設備使用NTP。

另外,因爲它使用套接字。提出的一些解決方案使用HTTP,因此他們會失去準確性。

1

以上都沒有從我這裏工作。這就是我最後與(與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這個:

compile 'com.android.volley:volley:1.0.0' 
+0

但是要從上面的api中獲取響應,這將需要幾秒鐘的時間嗎?如何過去的時間..? – shobhan

+0

這對我來說足夠好 – user3734429

+3

體面的解決方案,如果我們不介意幾秒鐘的不準確。好的折衷。但是我想知道是誰支持timeapi.org以及它有多可能脫機。 – rpattabi

0

如果你不關心毫秒的準確性,如果你已經在使用谷歌火力或不介意使用它(他們提供了一個免費的層),請查看:https://firebase.google.com/docs/database/android/offline-capabilities#clock-skew

基本上,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"); 
    } 
}); 

正如我所說,基於網絡延遲將是不準確的。

+0

此字段將被緩存,所以如果你想多次獲得這個價值,你需要做的'FirebaseDatabase.getInstance()。goOffline()'和'goOnline()' – Niels

+0

哦!謝謝你讓我知道。 – rpattabi

相關問題