インターネットから現在時刻を取得したいアプリを作っています。
を使ってデバイスから時間を取得する方法を知っていSystem.currentTimeMillis
て、たくさん検索した後でも、インターネットから時間を取得する方法については何の手がかりも得られませんでした。
あなたは以下のプログラムを使用してインターネットタイムサーバーから時間を得ることができます
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.これを機能させるには、 ApacheCommonsNetライブラリが必要です。ライブラリをダウンロードして、プロジェクトのビルドパスに追加します。
(または、ここでトリミングされたApache Commons Net Libraryを使用することもできます:https ://www-us.apache.org/dist//commons/net/binaries/commons-net-3.6-bin.tar.gzこれで十分ですインターネットから時間を取得します)
2.プログラムを実行します。あなたはあなたのコンソールに印刷された時間を得るでしょう。
これが私があなたのために作成したメソッドですあなたはあなたのコードでこれを使うことができます
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;
}
ミリ秒の精度を気にせず、すでにgoogle firebaseを使用している場合、または使用してもかまわない場合(無料枠が提供されます)、https ://firebase.google.com/docs/databaseをチェックしてください。 / android / offset-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");
}
});
私が言ったように、それはネットワークの待ち時間に基づいて不正確になります。
最善の解決策は、SNTP、特にAndroid自体のSNTPクライアントコードを使用することだと思います。例:http: //grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/ 4.1.1_r1 / android / net / SntpClient.java /
Androidは、セルラーネットワークが利用できない場合(wifiタブレットなど)の日付/時刻の自動更新にSNTPを使用していると思います。
Apache TimeTCPClientで使用されるTimeプロトコル(RFC 868)ではなくSNTP / NTPを使用するため、他のソリューションよりも優れていると思います。RFC 868について悪いことは何も知りませんが、NTPはより新しく、それに取って代わったようで、より広く使用されています。セルラーを持たないAndroidデバイスはNTPを使用していると思います。
また、ソケットを使用しているためです。提案されたソリューションのいくつかはHTTPを使用しているため、精度が低下します。
XMLまたはJSON形式で現在の時刻を提供するWebサービスにアクセスできる必要があります。
このようなタイプのサービスが見つからない場合は、http://www.timeanddate.com/worldclock/などのWebページから時刻を解析するか、次の単純なPHPページを使用してサーバー上で独自の時刻サービスをホストできます。例。
HTMLページの解析については、JSoupを確認してください。
上記の何も私からはうまくいきませんでした。これが私が(ボレーで)最終的に得たものです。
この例も別のタイムゾーンに変換されます。
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'
Stackoverflowにはすでに明確な答えがあります
https://stackoverflow.com/a/71274296/11789675
このURLを呼び出すか、GETAPIとして使用します
http://worldtimeapi.org/api/timezone/Asia/Kolkata
応答は次のようになります
{
"abbreviation": "IST",
"client_ip": "45.125.117.46",
"datetime": "2022-02-26T10:50:43.406519+05:30",
}
私はボレーを使用しました..そしてサーバー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);
}
時間を取った後。目的に使用できません。(目的)すべての製品の終了時刻があり、現在の時刻と製品の終了時刻を比較する必要があります。有効な場合は、カートに追加できます。