Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android中關於日期時間與時區的使用總結

Android中關於日期時間與時區的使用總結

編輯:關於Android編程

 在開發Android的過程中,出現過幾次由於日期時間導致的問題,而且主要是由於時區的原因導致,所以一直想總結一下,形成一個良好的開發規范。   一、Unix時間戳     Unix時間戳(Unix timestamp),或稱Unix時間(Unix time)、POSIX時間(POSIX time),是一種時間表示方法,定義為從格林威治時間1970年01月01日00時00分00秒起至現在的總秒數。Unix時間戳不僅被使用在Unix系統、類Unix系統中,也在許多其他操作系統中被廣泛采用。   二、關於時間標准和時區     1、原子時:International Atomic Time (IAT)       又稱國際原子時,是一種通過原子鐘得到的時間標准,原子鐘是世界上已知最准確的時間測量和頻率標准,原子鐘在 37 億年的誤差不超過 1 秒。     2、世界時:Universal Time(UT)       是一種以格林尼治子夜起算的平太陽時。世界時是以地球自轉為基准得到的時間尺度,其精度受到地球自轉不均勻變化和極移的影響,為了解決這種影響,1955年國際天文聯合會定義了UT0、UT1和UT2三個系統,他們三者之間是遞進的關系,後者都是發現前者的一些度量差別,通過修正得到更均勻的時標。       在格林尼治子午線上的平太陽時稱為世界時(UT0),又叫格林尼治平時(GMT)。格林尼治標准時間(舊譯格林尼治平均時間或格林威治標准時間,英語:Greenwich Mean Time,GMT)是指位於英國倫敦郊區的皇家格林尼治天文台的標准時間,因為本初子午線被定義在通過那裡的經線。自1924年2月5日開始,格林尼治天文台每隔一小時會向全世界發放調時信息。     2、協調世界時:Coordinated Universal Time(UTC)       又稱世界標准時間、世界統一時間。是經過平均太陽時(以格林威治時間GMT為准)、地軸運動修正後的新時標以及以“秒”為單位的國際原子時所綜合精算而成的時間,計算過程相當嚴謹精密,因此若以“世界標准時間”的角度來說,UTC比GMT更精准。其誤差值必須保持在0.9秒以內,若大於0.9秒則由位於巴黎的國際地球自轉事務中央局發布閏秒,使UTC與地球自轉周期一致。       基本上UTC的本質強調的是比GMT更精確的世界時間標准,UTC中多一個閏秒的調整,以確保協調世界時(UTC)與格林尼治平時(GMT)相差不會超過0.9秒,並在有需要的時候在協調世界時(UTC)內加上正或負閏秒。       UTC被應用在大多數的計算機以及網絡標准中。     3、夏令時與冬令時:Daylight Saving Time(DST)       又稱“日光節約時制”和“夏令時間”,是一種為節約能源而人為規定地方時間的制度,在這一制度實行期間所采用的統一時間稱為“夏令時間”。一般在天亮早的夏季人為將時間提前一小時,可以使人早起早睡,減少照明量,以充分利用光照資源,從而節約照明用電。各個采納夏時制的國家具體規定不同。目前全世界有近110個國家每年要實行夏令時。自2011年3月27日開始俄羅斯永久使用夏令時,把時間撥快一小時,不再調回。       簡單來說,使用夏令時和冬令時即在夏季將時間撥快一個小時,等到冬季再將時間撥慢一個小時。     4、CST       CST同時代表澳大利亞、美國、中國、古巴四個國家的標准時間,時區分別為:        澳洲中部時間,Central Standard Time (Australia) UT+9:30      中部標准時區(北美洲),Central Standard Time (North America) UT-6:00      北京時間,China Standard Time UT+8:00      古巴標准時間,Cuba Standard Time UT-4:00     在開發時我們需要注意不同國家的時區,並且UTC和GMT在計算機系統中使用並無明顯差別,可視為等同。   二、規范     在實際開發中,當時間用於顯示時,非特殊要求下一般使用系統默認的時區時間作為顯示時間。將時間做為數據存儲或傳遞給其他系統時(特別是跨平台調用),則最好使用標准的UTC/GMT時間(後面統稱GMT),除非事先約定或標識了時間的類型。   三、在Android中需要特別注意的事項     1、Android中表示日期時間的類型,有Date、Calendar,他們在沒有顯示設置其時區時,取到的當前時間均為系統默認時區的時間,即使給定一個時間,同樣是按系統默認時區來換算時間,所以說他們都是與時區相關的。     2、SimpleDateFormat對象本身也是跟時區相關。       當使用parse將一個字符串格式的日期轉換為Date對象,或者將一個Date對象轉換為字符串日期時,這個字符串日期的時區以SimpleDateFormat關聯的時區為准,如果通過setTimeZone修改了時區,則這個字符串日期以修改後的時區為准。例如:   // 2013-1-31 22:17:14 Date date = new Date(1359641834000L); System.out.println(date); String dateStr = "2013-1-31 22:17:14"; SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); try {     // 對於已經設定為GMT時間標准的dateFormat來說,一切需要他轉換的字符串日期都是GMT標准時間,轉換後返回的Date由於默認遵守系統默認時區,所以轉換給Date的日期需要+8(例如北京標准時區),也就是時區與標准不同導致的時差。     Date dateTmp = dateFormat.parse(dateStr);     System.out.println(dateTmp); }  catch (ParseException e)  {     e.printStackTrace();   }   // Date還是按系統默認時區,而format格式化處來的字符串是GMT,所以要-8。 String dateStrTmp = dateFormat.format(date);   System.out.println(dateStrTmp);     輸出結果為:image   3、Calendar在不手動設置時區時,是與系統默認時區相關的。在手動修改時區後,不能使用calendar.getTime方法來直接獲取Date日期,因為此時的日期與setTime時的值相同,想要正確獲取修改時區後的時間,應該通過calendar的get方法。例如:   Date date = new Date(1359641834000L); System.out.println(date); Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(TimeZone.getTimeZone("GMT"));   // 或者可以 Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));   calendar.setTime(date); System.out.println(calendar.get(Calendar.HOUR_OF_DAY) + ":" + calendar.get(Calendar.MINUTE));   Calendar calendar2 = Calendar.getInstance();   calendar2.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));   System.out.println(calendar.getTime());   System.out.println(calendar2.getTime());     輸入結果為:image     4、TimeZone       在開發中,我們可以通過TimeZone對象獲取關於系統默認時區及其相關的詳細信息。   四、Android關於日期的工具類   /**  * Copyright (C) 2011, BHJ  * All rights reserved.  *   * 文件名稱:  * 文件標識:  * 文件摘要:  *   * 當前版本:  * 作    者:  * 完成日期:2013-12-20  *   * 取代版本:  * 修改時間:  * 修 改 人:  * 修改摘要:  */   package com.bhj.timetest;   import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.TimeZone;   /**  * 日期工具類(未特別說明的均為系統默認時區下的時間)  * */ public class DateUtil {         /** 1s==1000ms */     private final static int TIME_MILLISECONDS = 1000;     /** 時間中的分、秒最大值均為60 */     private final static int TIME_NUMBERS = 60;     /** 時間中的小時最大值 */     private final static int TIME_HOURSES = 24;     /** 格式化日期的標准字符串 */     private final static String FORMAT = "yyyy-MM-dd HH:mm:ss";          /**      * 獲取時區信息      * */     public static TimeZone getTimeZone()     {         return TimeZone.getDefault();     }          /**      * 將日期字符串轉換為Date對象      * @param date 日期字符串,必須為"yyyy-MM-dd HH:mm:ss"      * @return 日期字符串的Date對象表達形式      * */     public static Date parseDate(String date)     {         return parseDate(date, FORMAT);     }          /**      * 將日期字符串轉換為Date對象      * @param date 日期字符串,必須為"yyyy-MM-dd HH:mm:ss"      * @param format 格式化字符串      * @return 日期字符串的Date對象表達形式      * */     public static Date parseDate(String date, String format)     {         Date dt = null;         SimpleDateFormat dateFormat = new SimpleDateFormat(format);         try         {             dt = dateFormat.parse(date);         }         catch(ParseException e)         {             e.printStackTrace();         }                  return dt;     }          /**      * 將Date對象轉換為指定格式的字符串      * @param date Date對象      * @return Date對象的字符串表達形式"yyyy-MM-dd HH:mm:ss"      * */     public static String formatDate(Date date)     {         return formatDate(date, FORMAT);       }          /**      * 將Date對象轉換為指定格式的字符串      * @param date Date對象      * @param String format 格式化字符串      * @return Date對象的字符串表達形式      * */     public static String formatDate(Date date, String format)     {         SimpleDateFormat dateFormat = new SimpleDateFormat(format);           return dateFormat.format(date);       }       /**      * 格式化日期      * @param long unixTime unix時間戳      * @return 日期字符串"yyyy-MM-dd HH:mm:ss"      * */     public static String formatUnixTime(long unixTime)     {           return formatUnixTime(unixTime, FORMAT);     }          /**      * 格式化日期      * @param long unixTime unix時間戳      * @param String format 格式化字符串      * @return 日期字符串      * */     public static String formatUnixTime(long unixTime, String format)     {         SimpleDateFormat dateFormat = new SimpleDateFormat(format);           return dateFormat.format(unixTime);       }          /**      * 將GMT日期格式化為系統默認時區的日期字符串表達形式      * @param gmtUnixTime GTM時間戳      * @return 日期字符串"yyyy-MM-dd HH:mm:ss"      * */     public static String formatGMTUnixTime(long gmtUnixTime)     {         return formatGMTUnixTime(gmtUnixTime, FORMAT);      }          /**      * 將GMT日期格式化為系統默認時區的日期字符串表達形式      * @param gmtUnixTime GTM時間戳      * @param format 格式化字符串      * @return 日期字符串"yyyy-MM-dd HH:mm:ss"      * */     public static String formatGMTUnixTime(long gmtUnixTime, String format)     {         SimpleDateFormat dateFormat = new SimpleDateFormat(format);         return dateFormat.format(gmtUnixTime + TimeZone.getDefault().getRawOffset());      }          /**      * 獲取時間戳的Date表示形式      * @param unixTime unix時間戳      * @return Date對象      * */     public static Date getDate(long unixTime)     {           return new Date(unixTime);       }          /**      * 獲取GMT時間戳的Date表示形式(轉換為Date表示形式後,為系統默認時區下的時間)      * @param gmtUnixTime GMT Unix時間戳      * @return Date對象      * */     public static Date getGMTDate(long gmtUnixTime)     {         return new Date(gmtUnixTime + TimeZone.getDefault().getRawOffset());      }       /**      * 將系統默認時區的Unix時間戳轉換為GMT Unix時間戳      * @param unixTime unix時間戳      * @return GMT Unix時間戳      * */     public static long getGMTUnixTime(long unixTime)     {         return unixTime - TimeZone.getDefault().getRawOffset();     }       /**      * 將GMT Unix時間戳轉換為系統默認時區的Unix時間戳      * @param gmtUnixTime GMT Unix時間戳      * @return 系統默認時區的Unix時間戳      * */     public static long getCurrentTimeZoneUnixTime(long gmtUnixTime)     {         return gmtUnixTime + TimeZone.getDefault().getRawOffset();     }          /**      * 獲取當前時間的GMT Unix時間戳      * @return 當前的GMT Unix時間戳      * */     public static long getGMTUnixTimeByCalendar()     {         Calendar calendar = Calendar.getInstance();         // 獲取當前時區下日期時間對應的時間戳         long unixTime = calendar.getTimeInMillis();         // 獲取標准格林尼治時間下日期時間對應的時間戳          long unixTimeGMT = unixTime - TimeZone.getDefault().getRawOffset();         return unixTimeGMT;     }          /**      * 獲取當前時間的Unix時間戳      * @return 當前的Unix時間戳      * */     public static long getUnixTimeByCalendar()     {         Calendar calendar = Calendar.getInstance();         // 獲取當前時區下日期時間對應的時間戳         long unixTime = calendar.getTimeInMillis();         return unixTime;     }          /**       * 獲取更改時區後的時間       * @param date 時間       * @param oldZone 舊時區       * @param newZone 新時區       * @return 時間      */       public static Date changeTimeZone(Date date, TimeZone oldZone, TimeZone newZone)      {           Date dateTmp = null;         if (date != null)         {             int timeOffset = oldZone.getRawOffset() - newZone.getRawOffset();             dateTmp = new Date(date.getTime() - timeOffset);         }         return dateTmp;     }          /**      * 將總秒數轉換為時分秒表達形式      * @param seconds 任意秒數      * @return %s小時%s分%s秒      */     public static String formatTime(long seconds)     {         long hh = seconds / TIME_NUMBERS / TIME_NUMBERS;         long mm = (seconds - hh * TIME_NUMBERS * TIME_NUMBERS) > 0 ? (seconds - hh * TIME_NUMBERS * TIME_NUMBERS) / TIME_NUMBERS : 0;         long ss = seconds < TIME_NUMBERS ? seconds : seconds % TIME_NUMBERS;         return     (hh == 0 ? "" : (hh < 10 ? "0" + hh : hh) + "小時")                  + (mm == 0 ? "" : (mm < 10 ? "0" + mm : mm) + "分")                  + (ss == 0 ? "" : (ss < 10 ? "0" + ss : ss) + "秒");     }          /**      * 獲取當前時間距離指定日期時差的大致表達形式      * @param long date 日期      * @return 時差的大致表達形式      * */     public static String getDiffTime(long date)     {         String strTime = "很久很久以前";         long time = Math.abs(new Date().getTime() - date);         // 一分鐘以內         if(time < TIME_NUMBERS * TIME_MILLISECONDS)         {             strTime = "剛剛";         }         else         {             int min = (int)(time / TIME_MILLISECONDS / TIME_NUMBERS);             if(min < TIME_NUMBERS)             {                 if(min < 15)                 {                     strTime = "一刻鐘前";                 }                 else if(min < 30)                 {                     strTime = "半小時前";                 }                 else                 {                     strTime = "1小時前";                 }             }             else             {                 int hh = min / TIME_NUMBERS;                 if(hh < TIME_HOURSES)                 {                     strTime = hh + "小時前";                 }                 else                 {                     int days = hh / TIME_HOURSES;                     if(days <= 6)                     {                         strTime = days + "天前";                     }                     else                     {                         int weeks = days / 7;                         if(weeks < 3)                         {                             strTime = weeks + "周前";                             }                     }                 }             }         }                  return strTime;     } }
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved