【问题标题】:How to get current time from internet in android如何在android中从互联网获取当前时间
【发布时间】:2012-10-15 09:50:33
【问题描述】:

我正在制作一个应用程序,我想在其中从互联网获取当前时间。

我知道如何使用System.currentTimeMillis从设备上获取时间,即使经过大量搜索,我也没有得到任何关于如何从互联网上获取时间的线索。

【问题讨论】:

  • 检查this可能对你有帮助
  • 对不起先生,我是android新手,这个例子很难理解。

标签: android time


【解决方案1】:

您需要能够访问以 XML 或 JSON 格式提供当前时间的网络服务。

如果您没有找到此类服务,您可以从网页解析时间,例如http://www.timeanddate.com/worldclock/,或者使用简单的 PHP 页面在服务器上托管您自己的时间服务。

查看 JSoup 以解析 HTML 页面。

【讨论】:

  • 请告诉我先生如何从这个网站解析时间。这对像我这样的初学者非常有帮助。提前谢谢。
  • 它的服务很贵,先生,能给我一些空闲时间api服务商的链接吗?
  • 请查看 JSoup 文档,尝试一些代码,如果遇到问题,请与我们联系。
  • 请注意,尽管您可以使用 Jsoup 解析 TimeAndDate,但该网页的来源说“未经许可,不允许下载对用户透明的内容的脚本和程序”。请务必征得您的许可,以避免将来对您采取任何法律行动。
【解决方案2】:

您可以使用以下程序从互联网时间服务器获取时间

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.您需要Apache Commons Net 库才能使其工作。 Download 库并添加到您的项目构建路径。

(或者你也可以在这里使用修剪过的 Apache Commons Net Library:https://www-us.apache.org/dist//commons/net/binaries/commons-net-3.6-bin.tar.gz 这足以从互联网上获取时间)

2.运行程序。您将在控制台上打印时间。

【讨论】:

  • 你能告诉我任何可靠的时间服务器的名称吗?
  • @user1726619 所有列出的服务器都是可靠的,因为它由 NIST 维护。我用过的那个工作正常。但正如 NIST 网站所说,您不应该对任何 url 进行硬编码。您可以在属性文件或 sqlite db 中提供 4 或 5 个时间服务器。然后从第一个 url 开始,等待结果(或超时)。如果超时,请尝试下一个链接,依此类推。如果所有链接都失败(非常罕见的机会),您可以向用户显示一条消息。 (或从头开始)
  • 我在这个网址上没有发现此类地址异常。
  • 你现在解决这个问题了吗?你说的是哪个网址?
  • 由于答案上的那些链接已过时..使用此链接下载:java2s.com/Code/Jar/c/Downloadcommonsnet33jar.htm
【解决方案3】:

这是我为您创建的方法 你可以在你的代码中使用它

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

【讨论】:

【解决方案4】:

我认为最好的解决方案是使用 SNTP,尤其是 Android 本身的 SNTP 客户端代码,例如: 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,因此它们的准确性会有所损失。

【讨论】:

    【解决方案5】:

    上面没有任何东西对我有用。这就是我最终得到的结果(使用 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 中导入 Volley:

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

    【讨论】:

    • 但是要从上面的 api 中获取响应,需要几秒钟的时间,对吧?过去的时间怎么样..??
    • 如果我们不介意几秒钟的误差,这是一个不错的解决方案。很好的权衡。但我想知道谁支持 timeapi.org,它下线的可能性有多大。
    【解决方案6】:

    如果您不关心毫秒精度,并且您已经在使用 google firebase 或不介意使用它(他们提供免费层),请查看: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");
      }
    });
    

    正如我所说,它会因网络延迟而变得不准确。

    【讨论】:

    • 这个字段会被缓存,所以如果要多次获取这个值,需要做FirebaseDatabase.getInstance().goOffline()goOnline()
    • 哦!谢谢你告诉我。
    • 谢谢,这真的很有帮助
    【解决方案7】:

    我使用了 volley.. 并从 Server api (php) 获得了时间..

             public void GetServerTime() {
    
            StringRequest volleyrequest = new StringRequest(Request.Method.GET, url, new 
             Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
    
                try {
    
                    JSONObject jObject = new JSONObject(response);
                    result = jObject.toString();
    
                } catch (JSONException | ParseException e) {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(), "Data Conversion Failed.", Toast.LENGTH_LONG).show();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
                Log.w("onErrorResponse", "" + error.getMessage());
                Toast.makeText(getApplicationContext(), "NO Internet connection! Please check your network.", Toast.LENGTH_LONG).show();
            }
        });
    
        RequestQueue queue = Volley.newRequestQueue(ProductDetailActivity.this);
        queue.add(volleyrequest);
    }
    

    得到时间之后。我无法用于我的目的.. (我的目的) 我有每个产品的结束时间,我必须将我的当前时间与产品结束时间进行比较。如果它有效,则可以将其添加到购物车中。

    【讨论】:

    • 这比已经发布的其他 10 多个回复有什么好处?
    • 先生,我已经检查了所有对我不起作用的解决方案?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    • 2016-08-28
    • 1970-01-01
    相关资源
    最近更新 更多