Java获取网络时间

通过网页 Head 来获取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private static String getWebsiteDatetime(String webUrl){
try {
URL url = new URL(webUrl);// 取得资源对象
URLConnection uc = url.openConnection();// 生成连接对象
uc.connect();// 发出连接
long ld = uc.getDate();// 读取网站日期时间
Date date = new Date(ld);// 转换为标准时间对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);// 输出北京时间
return sdf.format(date);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

获取网页时间戳

(如果本地和网页时间相差不多,以后都以本地为主)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public static final String URL_CHECK_TIME = "http://www.taobao.com";
private static boolean useLocal;// 是否使用本地时间
private static long deltaTime; // 本机时间-网络时间;

public static void resetTimeStamp() {
useLocal = false;
deltaTime = 0;
}

/**
* 获取时间戳(首次从网上获取时间,和本地比较,如果相差在一定的范围内,以后的调用就直接使用本地的,如果相差很大,以后都以网页时间为准)
*
* @return 返回的是以秒为单位的时间字符串
*/
public static String getTimeStamp() {
final long phoneTime = System.currentTimeMillis() / 1000;

String result = String.valueOf(phoneTime);
if (!useLocal) {
// 之所以使用线程,是因为在Android中不允许在主线程中开启网络请求(NetworkOnMainThreadException)
new Thread(new Runnable() {
@Override
public void run() {
try {
URLConnection uc = new URL(URL_CHECK_TIME).openConnection();// 生成连接对象
uc.connect();// 发出连接
long webSiteTime = uc.getDate() / 1000;// 读取网站日期时间

// 获取到了网站时间,就进行比较
// 如果在范围内,下一次直接使用本地手机时间;
long currentTime = System.currentTimeMillis() / 1000;
useLocal = Math.abs(currentTime - webSiteTime) < 5 * 60;
deltaTime = currentTime - webSiteTime;

} catch (Exception e) {
Log.e(TAG, "getTimeStamp: ", e);
resetTimeStamp();
}

}
}).start();

result = String.valueOf(phoneTime - deltaTime);
}

Log.i(TAG, "getTimeStamp: 本次使用了本机时间?" + useLocal);
return result;
}

监听时间和日期变化

onCreate中添加注册

1
2
3
4
5
// 监听用户对时间和日期的修改;
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_DATE_CHANGED);
registerReceiver(mReceiver, filter);

onDestroy中取消注册

1
unregisterReceiver(mReceiver);

mReceiver实现

1
2
3
4
5
6
7
8
9
10
11
12
13
BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
// 时间发生变化后,重新设置时间戳
case Intent.ACTION_TIME_CHANGED:
case Intent.ACTION_DATE_CHANGED:
Log.i(TAG, "onReceive: Time or Date changed");
Utime.resetTimeStamp();
Utime.getTimeStamp();
}
}
};

直接获取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class Utime {
private static final String URL_BASE = "https://sj.qq.com/";

/**
* 根据url这个网址来获取时间戳(如果获取此网络时间失败,使用本地时间)
* 返回的是以秒为单位的时间字符串
*
* @param url url
*/
public static String getTimeStamp(String url) {

final String urlRrBase = getBaseUrl(url);
final long currentTimeMillis = System.currentTimeMillis() / 1000;

try {
URLConnection uc = new URL(urlRrBase).openConnection();// 生成连接对象
uc.connect();// 发出连接
long webTimeMillis = uc.getDate();
long webTime = webTimeMillis / 1000;// 读取网站日期时间
return String.valueOf(webTime);
} catch (Exception e) {
return String.valueOf(currentTimeMillis);
}
}

private static String getBaseUrl(String url) {
if (TextUtils.isEmpty(url)) {
return URL_BASE;
}

try {
URI uri = new URI(url);
return uri.getScheme() + "://" + uri.getHost();
} catch (Exception e) {
return URL_BASE;
}

}
}

参考资料