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

來源:互聯網
上載者:User

標籤:android   http   os   io   使用   java   ar   for   檔案   

原文引自:http://www.2cto.com/kf/201312/266908.html

在開發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:14Date 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;    }}

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.