Shell 贴士: Unix 时间到字面

小编的行事索要时刻跟报表数量打交道,在调换的文本中,一般时间的字段内容都是Unix 时间。为了检查数据的科学,不可幸免地必要退换 Unix
时间到人类可读的字面时间。

在开发Android的进度中,出现过三遍出于日期时间导致的题目,並且注重是出于时区的由来产生,所以直接想总计一下,产生一个可观的开拓标准。

下边想分享的是三个在 Shell 下转移 Unix 时间到字面包车型客车小方法。这几个小 shell
函数能够放在 ~/.bashrc 中方便飞快使用。

 

# 转换 Unix 时间到本地时间字符串
function ctime()
{
    date -d "UTC 1970-01-01 $1 secs"
}

一、Unix时间戳

动用办法很简短:

 

$ ctime 1234567890
Sat Feb 14 07:31:30 CST 2009

  Unix时间戳(Unix timestamp),或称Unix时间(Unix time)、POSIX时间(POSIX
time),是一种时光表示方法,定义为从Green威治时间一九六七年0四月01日00时00分00秒起至现在的总秒数。Unix时间戳不独有被采纳在Unix系统、类Unix系统中,也在众多任何操作系统中被广大应用。

对 date 命令熟识的同学会说,date 不是现已有一直转 Unix 时间的参数了吗?

 

$ date -d @1234567890
Sat Feb 14 07:31:30     2009

二、关于时间标准和时区

但是腼腆的是,表哥偶然候用的 date 程序好老,不援救 @ 符号。

 

$ date --version
date (coreutils) 5.2.1
Written by David MacKenzie.

Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

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

PS: 写完那篇博文,笔者又想开了叁个风趣的作业,既然相当多 Linux 64 位版本的
time_t 已经是 long long 格式了,那么 date 命令有未有 year 2038 难点啊?

 

上面是 date (coreutils) 5.2.1 在 64 位服务器上的尝尝结果:

    又称国际原申时,是一种通过机械电子钟获得的时光标准,石英表是世界3月知最确切的年华度量和功能标准,电子手表在
37 亿年的标称误差不超过 1 秒。

$ date +%s -d "Tue Jan 19 11:14:07 CST 2038"
2147483647
$ date +%s -d "Tue Jan 19 11:14:08 CST 2038"
2147483648
$ date +%s -d "Tue Jan 19 11:14:09 CST 2999"
32473710849
$ ctime 2147483647
Tue Jan 19 11:14:07 CST 2038
$ ctime 2147483648
Sat Dec 14 04:51:44 LMT 1901
$ ctime 32473710849
Mon Mar 28 07:33:53 LMT 1910

 

看来字面时间和 Unix 时间之间互转存在着主题材料呀!不过用
Ubuntu 11.04 的 date
(GNU coreutils) 8.5 尝试就一纸空文这么些标题了。

  2、世界时:Universal Time(UT)

图片 1

 

    是一种以格林尼治子夜起算的平太阳时。世界时是以地球自转为基准获得的时间尺度,其精度受到地球自转不均匀变化和极移的熏陶,为了化解这种影响,一九五三年国际天文学艺术家联合会晤会概念了UT0、UT1和UT2几个系统,他们三者之间是带动的关联,后者都是开掘前面五个的一对心胸差距,通过校对获得更均匀的时标。

 

    在Green尼治子午线上的平太阳时名叫世界时(UT0),又叫Green尼治日常(红霉素T)。Green尼治标准时间(旧译格林尼治平均时间或Green威治标准时间,保加布兰太尔语:Greenwich
Mean
Time,氯洁霉素T)是指位于大不列颠及北爱尔兰联合王国London镜湖区的皇家Green尼治天文台的科班时间,因为本初子午线被定义在通过这里的经线。自一九二一年三月5日初阶,Green尼治天文台每隔一钟头会向中外发放调时新闻。

 

  2、和谐世界时:Coordinated Universal 提姆e(UTC)

 

    又称世界规范时间、世界统不时常间。是透过平分太阳时(以Green威治时间金霉素T为准)、地轴运动改良后的新时标以及以“秒”为单位的国际原龙时所综合计算而成的光阴,总结进程优异严酷精密,因而若以“世界规范时间”的角度来讲,UTC比GMT更加精准。其抽样误差值必须保持在0.9秒之内,若高于0.9秒则由位于法国首都的国际地球自转事务中心局发表闰秒,使UTC与地球自转周期一致。

 

    基本上UTC的实质重申的是比GMT更标准的社会风气时间标准,UTC中多一个闰秒的调动,以保险协调世界时(UTC)与Green尼治平时(克林霉素T)相差不会抢先0.9秒,并在有要求的时候在和谐世界时(UTC)内加多正或负闰秒。

 

    UTC被利用在大部的管理器以及网络正式中。

 

  3、夏令时与冬令时:Daylight Saving Time(DST)

 

    又称“日光节约时制”和“夏令时间”,是一种为节能而人工规定地点时间的制度,在这一制度试行时期所运用的联结时间称为“夏令时间”。一般在天亮早的三夏人工将时刻提前一钟头,能够使人早起早睡,减少照明量,以丰盛利用光照能源,进而省去照明用电。各种选取夏时制的国度实际规定分裂。这段时间满世界有近1十个国家每年要施行夏令时。自二〇一二年四月十日开始俄罗斯永世使用夏令时,把日子拨快一钟头,不再调回。

 

    简单的说,使用夏令时和冬令时即在三夏将时间拨快七个小时,等到冬天再将时刻拨慢二个钟头。

 

  4、CST

 

    CST同一时候表示澳洲、U.S.A.、中中原人民共和国、古巴三个国家的标准时间,时区分别为:

 

     澳国中央时间,Central Standard 提姆e (Australia) UT+9:30

     中部规范时区(南美洲),Central Standard 提姆e (North America)
UT-6:00

     新加坡时间,China Standard Time UT+8:00

     古巴正式时间,Cuba Standard Time UT-4:00

 

  在开采时我们须求小心分化国家的时区,并且UTC和青霉素T在管理器种类中选取并无分明差别,可便是等同。

 

二、规范

 

  在实际付出中,当时间用于展现时,非特殊供给下一般选拔系统暗中认可的时区时间作为展现时间。将时间做为数据存款和储蓄或传递给别的系统时(极其是跨平台调用),则最佳使用标准的UTC/土霉素T时间(前面统称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

{

    //
对于曾经设定为金霉素T时间规范的dateFormat来讲,一切供给他转移的字符串日期都以欧霉素T规范时间,调换后再次回到的Date由于暗中认可遵守系统默许时区,所以调换给Date的日期供给+8(譬喻东京标准时区),也正是时区与正统区别变成的时差。

    Date dateTmp = dateFormat.parse(dateStr);

    System.out.println(dateTmp);

catch (ParseException e) 

{

    e.printStackTrace();  

}  

// Date依旧按系统暗中认可时区,而format格式化处来的字符串是欧霉素T,所以要-8。

String dateStrTmp = dateFormat.format(date);  

System.out.println(dateStrTmp);

    输出结果为:image

  3、Calendar在不手动设置时区时,是与系统默许时区相关的。在手动修改时区后,不可能利用calendar.get提姆e方法来平昔拿走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(“核糖霉素T”));  

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.

 * 

 * 文件名称:

 * 文件标志:

 * 文件摘要:

 * 

 * 当前版本:

 * 作    者:

 * 完成日期:二零一二-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);  

    }

    

    /**

     *
获取克林霉素T时间戳的Date表示方式(调换为Date表示格局后,为系统暗中同意时区下的时辰)

     * @param gmtUnixTime GMT Unix时间戳

     * @return Date对象

     * */

    public static Date getGMTDate(long gmtUnixTime)

    {

        return new Date(gmtUnixTime +
TimeZone.getDefault().getRawOffset()); 

    }

 

    /**

     * 将系统暗许时区的Unix时间戳调换为土霉素T Unix时间戳

     * @param unixTime unix时间戳

     * @return GMT Unix时间戳

     * */

    public static long getGMTUnixTime(long unixTime)

    {

        return unixTime – TimeZone.getDefault().getRawOffset();

    }

 

    /**

     * 将威他霉素T Unix时间戳转变为系统暗许时区的Unix时间戳

     * @param gmtUnixTime GMT Unix时间戳

     * @return 系统默许时区的Unix时间戳

     * */

    public static long getCurrentTimeZoneUnixTime(long gmtUnixTime)

    {

        return gmtUnixTime + TimeZone.getDefault().getRawOffset();

    }

    

    /**

     * 获取当后天子的博来霉素T Unix时间戳

     * @return 当前的GMT Unix时间戳

     * */

    public static long getGMTUnixTimeByCalendar()

    {

        Calendar calendar = Calendar.getInstance();

        // 获取当前时区下日期时间对应的时日戳

        long unixTime = calendar.getTimeInMillis();

        // 获取标准Green尼治时间下日期时间对应的时光戳 

        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;

    }

}

相关文章