Android中关于日期时间与时区的应用统计

By admin in 天文台 on 2019年1月24日

在开发Android的经过中,出现过两次出于日期时间导致的问题,而且根本是由于时区的来头导致,所以直接想统计一下,形成一个优良的支出规范。

 

一、Unix时间戳

 

  Unix时间戳(Unix timestamp),或称Unix时间(Unix time)、POSIX时间(POSIX
time),是一种时光代表方法,定义为从格林(Green)威治时间1970年0十月01日00时00分00秒起至现在的总秒数。Unix时间戳不仅被采纳在Unix系统、类Unix系统中,也在重重任何操作系统中被广大应用。

 

二、关于时间标准和时区

 

  1、原子时:International Atomic Time (IAT)

 

    又称国际原未时,是一种通过原子钟得到的小运标准,原子钟是世界上已知最纯粹的年月测量和成效标准,原子钟在
37 亿年的误差不超过 1 秒。

 

  2、世界时:Universal Time(UT)

 

    是一种以格林(Green)尼治子夜起算的平太阳时。世界时是以地球自转为基准拿到的时间尺度,其精度受到地球自转不均匀变化和极移的震慑,为明白决这种影响,1955年国际天文联合会概念了UT0、UT1和UT2三个连串,他们三者之间是推进的关系,后者都是发现前者的一些心地差异,通过校正得到更均匀的时标。

 

    在格林(格林(Green))尼治子午线上的平太阳时名叫世界时(UT0),又叫格林(Green)尼治经常(GMT)。格林(格林)尼治标准时间(旧译格林尼治平均时间或格林威治标准时间,克罗地亚语:Greenwich
Mean
提姆e,GMT)是指位于大英帝国London郊区的皇家格林(格林)尼治天文台的正规化时间,因为本初子午线被定义在经过那里的经线。自1924年5月5日始发,格林(格林(Green))尼治天文台每隔一时辰会向环球发放调时音信。

 

  2、协调世界时:Coordinated Universal 提姆e(UTC)

 

    又称世界标准时间、世界统一时间。是因此平分太阳时(以格林(格林)威治时间GMT为准)、地轴运动核对后的新时标以及以“秒”为单位的国际原兔时所综合计算而成的日子,总括进程相当严峻精密,因而若以“世界标准时间”的角度来说,UTC比GMT更精准。其误差值必须保持在0.9秒之内,若高于0.9秒则由位于法国巴黎的国际地球自转事务大旨局发表闰秒,使UTC与地球自转周期一致。

 

    基本上UTC的原形强调的是比GMT更可依赖的世界时间标准,UTC中多一个闰秒的调动,以保险协调世界时(UTC)与格林尼治日常(GMT)相差不会超过0.9秒,并在有需求的时候在协调世界时(UTC)内增加正或负闰秒。

 

    UTC被使用在多数的微机以及网络正式中。

 

  3、夏令时与冬令时:Daylight Saving 提姆(Tim)e(DST)

 

    又称“日光节约时制”和“夏令时间”,是一种为节约能源而人工规定地方时间的社会制度,在这一制度实践时期所选取的合并时间称为“夏令时间”。一般在天亮早的夏日人工将时刻提前一时辰,可以使人早起早睡,收缩照明量,以丰裕利用光照资源,从而省去照明用电。各样采取夏时制的国家实际规定不一致。近来海内外有近110个国家每年要实践夏令时。自二〇一一年六月27日开首俄联邦永久使用夏令时,把日子拨快一钟头,不再调回。

 

    不难的话,使用夏令时和冬令时即在春季将时刻拨快一个钟头,等到春季再将时间拨慢一个小时。

 

  4、CST

天文台, 

    CST同时意味着澳大海法、花旗国、中国、古巴八个国家的科班时间,时区分别为:

 

     非洲之中时间,Central Standard 提姆(Tim)e (Australia) UT+9:30

     中部标准时区(南美洲),Central Standard 提姆e (诺思 America)
UT-6:00

     上海时间,China Standard 提姆(Tim)e UT+8:00

     古巴标准时间,Cuba Standard 提姆e 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.get提姆e方法来直接获取Date日期,因为那时候的日子与set提姆(Tim)e时的值相同,想要正确获取修改时区后的光阴,应该经过calendar的get方法。例如:

 

Date date = new Date(1359641834000L);

System.out.println(date);

Calendar calendar = Calendar.getInstance();

calendar.setTimeZone(TimeZone.getTimeZone(“GMT”));  

// 或者可以 Calendar calendar =
Calendar.getInstance(提姆(Tim)eZone.get提姆eZone(“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

 

    在开发中,大家得以经过提姆eZone对象获得有关系统默许时区及其有关的详细新闻。

 

四、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 str提姆(Tim)e = “很久很久以前”;

        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)

                {

                    str提姆(Tim)e = “一时辰前”;

                }

                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;

    }

}

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 亚洲必赢手机官网 版权所有