Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android-獲取網絡時間、獲取特定時區時間、時間同步的方法

android-獲取網絡時間、獲取特定時區時間、時間同步的方法

編輯:關於Android編程

最近整理出android-獲取網絡時間、獲取特定時區時間、時間同步的方法。具體如下:

方法一:

SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
dff.setTimeZone(TimeZone.getTimeZone("GMT+08")); 
String ee = dff.format(new Date());

這個方法獲取的結果是24小時制的,月份也正確。 

這個方法不隨手機時間的變動而變動。也就是說,即使手機設置成別的時區,不是東八區,這個方法返回的也照樣是北京時間!!!這正是我在做項目的時候用到的方法!!徹底解決項目需求!

方法二:

Calendar calendar = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
String rt = sdf.format(calendar.getTime());

這個方法獲取的結果是不是24小時制的,月份也正確。

方法三:

public static String getLocalDatetimeString(String local) { 
  Calendar cal = new GregorianCalendar(TimeZone.getTimeZone(local)); 
  cal.setTimeInMillis(Calendar.getInstance().getTimeInMillis()); 
  String date = cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-" + cal.get(Calendar.DAY_OF_MONTH); 
  String time = cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE) + ":" + cal.get(Calendar.SECOND); 
  return date + " " + time; 
} 

方法調用:

String tt = getLocalDatetimeString("GMT+8"); 

代碼裡也看出來了,這個在月份上加了一個1, 24小時制

以上三種方法驗證如下:

import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;


public class TimeTest {

  /**
   * @param args
   */
  public static void main(String[] args) {
    method1();
    method2();
    method3();
  }

  static void method1(){
    SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
    dff.setTimeZone(TimeZone.getTimeZone("GMT+08")); 
    String ee = dff.format(new Date());
    System.out.println("ee="+ee);
  }

  static void method2(){
    Calendar calendar = Calendar.getInstance();
    SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
    String rt = sdf.format(calendar.getTime());
    System.out.println("TimeTest.method2() rt="+rt);
  }
  static void method3(){
    String local = "GMT+8";
    Calendar cal = new GregorianCalendar(TimeZone.getTimeZone(local)); 
    cal.setTimeInMillis(Calendar.getInstance().getTimeInMillis()); 
    String date = cal.get(Calendar.YEAR) + "-" + (cal.get(Calendar.MONTH) + 1) + "-" + cal.get(Calendar.DAY_OF_MONTH); 
    String time = cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE) + ":" + cal.get(Calendar.SECOND); 
    System.out.println("TimeTest.method3() date="+date+",time="+time);
  }

}

結果如下:

本人采用的是第一種方法,因為第一種方法的時間是不隨手機時間的設置而改變。 

第二種方法也是可以的,不過時間小時是12進制。

第四種方法: 

網上還有這種方法獲取時間:

URL url=new URL("http://www.bjtime.cn");//取得資源對象
    URLConnection uc=url.openConnection();//生成連接對象
    uc.connect(); //發出連接
    long ld=uc.getDate(); //取得網站日期時間
    Date date=new Date(ld); //轉換為標准時間對象
    //分別取得時間中的小時,分鐘和秒,並輸出
    System.out.print(date.getHours()+"時"+date.getMinutes()+"分"+date.getSeconds()+"秒");

這種方式需要開啟一個線程獲取時間,同時也存在著一種風險就是由於網絡問題,獲取不到響應的問題。還有一個重要的問題件就是這個時間的獲取會隨著手機時區的改變而改變。

方法五:

通過網絡或者GPS的方式。

代碼:

LocationManager locMan = (LocationManager) this.getSystemService(MainActivity.LOCATION_SERVICE);
//獲取最近一次知道的時間
long networkTS = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER).getTime();

或者實時的獲取時間:

locMan.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); //獲取當前時間

當我們使用requestLocationUpdates時,我們需要實現LocationListener接口。

在LocationListen的回調onLocationChanged當中獲取時間

@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
long time = location.getTime();
Date date = new Date(time);
System.out.println(time + " NETWORK_PROVIDER " + date);
// System.out.println(STANDARD_TIME + " ");
}

這種方式是利用手機定位系統進行時間的獲取,但是這種方式會隨著手機的設置的時區的變動而改變。

第四種方式和第五種方式,我都在手機端進行了驗證,可以正常獲取時間。方式是沒有問題的。

既然有這麼多方法,大家看著那種方式適合自己的需求,選擇相應的方法。

我還是推薦第一種方法!簡單實用!!!!^_^

今天再在本文基礎上補充一些內容。現在我的項目中有這樣一種需求:就是播放視頻的時候,特別是監控視頻,我想要有時間限制,在一定時間內可以觀看,超出設置的時間,不能觀看。

Android端對於這樣的需求,上面的幾種方法都不行了,因為上面的方法都跟手機系統有關系了,當我改變手機系統的時間,時區等都會造成獲取的時間不對應,跟服務器時間不對。怎麼辦呢?有辦法!!! 

 我是這樣做的,當獲取到信息的時候,比如視頻節點信息的時候,服務器順帶著把服務器當前的時間返回來,有了服務器的時間,剩下的我就利用用戶操作的時間間隔,加上服務器的時間不就是手機所在地當前的時間嗎? 

 那麼時間間隔怎麼算呢?請看下面的SystemClock類幾個方法:

1、System.currentTimeMillis()是一個標准的“牆”時鐘(時間和日期),表示從紀元到現在的毫秒數。該牆時鐘能夠被用戶或電話網絡(見setCurrentTimeMillis(long))設置,所以該時間可能會向前或向後不可預知地跳越。該時鐘應該僅僅被使用在當現實世界的對應的日期和時間是重要的情況,例如一個日歷或鬧鐘應用程序。而間隔時間和經過時間應該使用不同的時鐘。如果你使用System.currentTimeMillis(),可以考慮監聽ACTION為ACTION_TIME_TICK、 ACTION_TIME_CHANGED、ACTION_TIMEZONE_CHANGED 的廣播去監聽時間變化。

2、uptimeMillis()表示自系統啟動時開始計數,以毫秒為單位。返回的是從系統啟動到現在這個過程中的處於非休眠期的時間。當系統進入深度睡眠時(CPU關閉,設備變黑,等待外部輸入裝置)該時鐘會停止。但是該時鐘不會被時鐘調整,閒置或其他節能機所影響。這是大多數間隔時間的基本點,例如Thread.sleep(millls)、Object.wait(millis)和System.nanoTime()。該時鐘被保證是單調的,適用於檢測不包含休眠的間隔時間的情況。大多數的方法接受一個時間戳的值除了uptimeMillis()時鐘。

3、elapsedRealtime() and elapsedRealtimeNanos() 返回系統啟動到現在的時間,包含設備深度休眠的時間。該時鐘被保證是單調的,即使CPU在省電模式下,該時間也會繼續計時。該時鐘可以被使用在當測量時間間隔可能跨越系統睡眠的時間段。

有幾種機制控制事件發生的時間:

1、標准的方法像Thread.sleep(millis) 和 Object.wait(millis)總是可用的,這些方法使用的是uptimeMillis()時鐘,如果設備進入深度休眠,剩余的時間將被推遲直到系統喚醒。這些同步方法可能被Thread.interrupt()中斷,並且你必須處理InterruptedException異常。

2、SystemClock.sleep(millis)是一個類似於Thread.sleep(millis)的實用方法,但是它忽略InterruptedException異常。使用該函數產生的延遲如果你不使用Thread.interrupt(),因為它會保存線程的中斷狀態。

3、Handler可以在一個相對或者絕對的時間設置異步回調,Handler類對象也使用uptimeMillis()時鐘,而且需要一個loop(經常出現在GUI程序中)。

4、AlarmManager可以觸發一次或重復事件,即使設備深度休眠或者應用程序沒有運行。事件可以選擇用 currentTimeMillis或者elapsedRealtime()(ELAPSED_REALTIME)來設置時間,當事件發生會觸發一個廣播。

方法:

1、public static long currentThreadTimeMillis () 返在當前線程運行的毫秒數。

2、public static long elapsedRealtime () 返回系統啟動到現在的毫秒數,包含休眠時間。

3、public static long elapsedRealtimeNanos () 返回系統啟動到現在的納秒數,包含休眠時間。

4、public static boolean setCurrentTimeMillis (long millis) 設置當前的”牆”時間,要求調用進程有許可權限。返回是否成功。

5、public static void sleep (long ms) 等待給定的時間。和Thread.sleep(millis)類似,但是它不會拋出InterruptedException異常。事件被推遲到下一個中斷操作。該方法直到指定的時間過去才返回。

6、public static long uptimeMillis () 返回系統啟動到現在的毫秒數,不包含休眠時間。就是說統計系統啟動到現在的非休眠期時間。

這些方法大家看看就知道啦。

剩下的就是計算事件間隔了:

public static long elapsedRealtime () 返回系統啟動到現在的毫秒數,包含休眠時間 

這個方法就可以計算從服務器返回時間到用戶操作,播放視頻這一段時間的時間間隔。有個這個不就可以做到時間不受手機系統的限制了嗎?

/**
   * 
   * @param ts 形如yyyy-MM-dd hh:mm:ss
   * @param intervalTime long類型
   * @return String HH:mm:ss
   */
  @SuppressLint("SimpleDateFormat")
  public static String getTime(String ts,long intervalTime){
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    Timestamp t=null;
    String tt="";
      try {
      t = new Timestamp(format.parse(ts).getTime());
      long ss = t.getTime();
      long st = ss+intervalTime;
      tt= getTime(st);
    } catch (java.text.ParseException e) {
      e.printStackTrace();
    }
    return tt;
  }
  /**
   * @param mis
   * @return HH:mm:ss
   */
  @SuppressLint("SimpleDateFormat")
  public static String getTime(long mis){
    SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String ee = dff.format(new Date(mis));
    return ee.substring(11);
  }

上面的方法中, ts參數就是服務器返回的當前時間,形如yyyy-MM-dd hh:mm:ss的字符串intervalTime參數,是獲取到服務器響應到用戶進行操作的時間間隔,就是使用上面的elapsedRealtime ()方法獲取兩次時間計算得到。 

方法的返回值String,形如 HH:mm:ss,這樣返回字符串方便比較時間字符。由於視頻事件限制,就是時分秒,不可能涉及到年月日,所以這裡就是直接返回時分秒。

有了這個方法,完美解決了android APP與服務器時間保持基本一致的需求。但是還是存在一定的問題的,因為服務器返回時間不定,可能長可能短,所以時間並不會和服務器的當前時間分秒不差,總會有延時,但是這個延時可以接受,大概最多在10秒左右。可以在時間間隔上稍微加一點就可以了。基本就滿足需求了。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved