三句话理解时区与时间戳

第一句话:时间戳

时间不分东西南北、在地球的每一个角落都是相同的。他们都有一个相同的名字,叫时间戳时间戳 指的就是Unix时间戳(Unix timestamp)。它也被称为Unix时间(Unix time)、POSIX时间(POSIX time),是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。

关于 时间戳, 你可以看在线时间戳 http://tool.chinaz.com/Tools/unixtime.aspx

第二句话:时区

时间戳 在地球的每一个角落都是相同的,但是在相同的时间点会有不同的表达方式,所以有了另外一个时间概念,叫时区。这里的时区地区不是同一个概念,例如我们所在的时区东八区 。 在设备中,可以自己手动的切换当前的系统时区:

http://static.cyblogs.com/1198135-c33bb659a21ae7d7.jpg

你会发现:当你选在不同的时区,你的当前时间是不一样的。

第三句话:时间戳与时区在Code中应用

格林威治标准时间GMT

十七世纪,格林威治皇家天文台为了海上霸权的扩张计画而进行天体观测。1675年旧皇家观测所(Old Royal Observatory) 正式成立,到了1884年决定以通过格林威治的子午线作为划分地球东西两半球的经度零度。观测所门口墙上有一个标志24小时的时钟,显示当下的时间,对全球而言,这里所设定的时间是世界时间参考点,全球都以格林威治的时间作为标准来设定时间,这就是我们耳熟能详的「格林威治标准时间(Greenwich Mean Time,简称G.M.T.)的由来,标示在手表上,则代表此表具有两地时间功能,也就是同时可以显示原居地和另一个国度的时间。

世界协调时间UTC

多数的两地时间表都以GMT来表示,但也有些两地时间表上看不到GMT字样,出现的反而是UTC这3个英文字母,究竟何谓UTC?事实上,UTC指的是Coordinated Universal Time-世界协调时间(又称世界标准时间、世界统一时间),是经过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以「秒」为单位的国际原子时所综合精算而成的时间,计算过程相当严谨精密,因此若以「世界标准时间」的角度来说,UTC比GMT来得更加精准。其误差值必须保持在0.9秒以内,若大于0.9秒则由位于巴黎的国际地球自转事务中央局发布闰秒,使UTC与地球自转周期一致。所以基本上UTC的本质强调的是比GMT更为精确的世界时间标准,不过对于现行表款来说,GMT与UTC的功能与精确度是没有差别的。

代码展示
package com.vernon.test.time;

import java.text.DateFormat;  
import java.text.ParseException;  
import java.text.SimpleDateFormat;  
import java.util.Calendar;  
import java.util.TimeZone;

public class UTCTimecase {

    private static DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");

    /**
     * 得到UTC时间,类型为字符串,格式为"yyyy-MM-dd HH:mm"<br />
     * 如果获取失败,返回null
     *
     * @return
     */
    public static String getUTCTimeStr() {
        StringBuffer UTCTimeBuffer = new StringBuffer();
        // 1、取得本地时间:
        Calendar cal = Calendar.getInstance();
        // 2、取得时间偏移量:
        int zoneOffset = cal.get(java.util.Calendar.ZONE_OFFSET);
        // 3、取得夏令时差:
        int dstOffset = cal.get(java.util.Calendar.DST_OFFSET);
        // 4、从本地时间里扣除这些差量,即可以取得UTC时间:
        cal.add(java.util.Calendar.MILLISECOND, -(zoneOffset + dstOffset));
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        int day = cal.get(Calendar.DAY_OF_MONTH);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int minute = cal.get(Calendar.MINUTE);
        UTCTimeBuffer.append(year).append("-").append(month).append("-").append(day);
        UTCTimeBuffer.append(" ").append(hour).append(":").append(minute);
        try {
            format.parse(UTCTimeBuffer.toString());
            return UTCTimeBuffer.toString();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将UTC时间转换为东八区时间
     *
     * @param UTCTime
     * @return
     */
    public static String getLocalTimeFromUTC(String UTCTime) {
        java.util.Date UTCDate = null;
        String localTimeStr = null;
        try {
            UTCDate = format.parse(UTCTime);
            format.setTimeZone(TimeZone.getTimeZone("GMT-8"));
            localTimeStr = format.format(UTCDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return localTimeStr;
    }

    public static void main(String[] args) {
        String UTCTimeStr = getUTCTimeStr();
        System.out.println(UTCTimeStr);
        System.out.println(getLocalTimeFromUTC(UTCTimeStr));
    }

}
package com.vernon.test.time;

import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;  
import java.util.Calendar;  
import java.util.Date;  
import java.util.TimeZone;

@Slf4j
public class DateTimeCase {

    public static final String FORMAT_DATETIME = "yyyy-MM-dd HH:mm:ss";

    public static String getOffsetTime(int offset, Date date) {
        TimeZone timeZone = TimeZone.getTimeZone("GMT-" + offset + ":00");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        simpleDateFormat.setTimeZone(timeZone);
        return simpleDateFormat.format(date);
    }

    public static void main(String[] args) {
        // 取得本地时间:
        Calendar cal1 = Calendar.getInstance();
        log.info("cal1={}", new SimpleDateFormat(FORMAT_DATETIME).format(cal1.getTime()));
        log.info("cal1={}", cal1.getTime().getTime());

        log.info("cal2={}", getOffsetTime(9, cal1.getTime()));
    }
}

总结

如果想实现国际化,数据库可以采用存放时间戳的方式,因为没有时区的影响,都是从1970年01月01日00时00分00秒计算的时间。然后根据当前的地区来显示。

参考地址

如果大家喜欢我的文章,可以关注个人订阅号。欢迎随时留言、交流。如果想加入微信群的话一起讨论的话,请加管理员简栈文化-小助手(lastpass4u),他会拉你们进群。

简栈文化服务订阅号