岁月戳 时区 java mysql天文台

By admin in 天文台 on 2019年1月13日
  • 当一个时间
    比如2016年七月6日,生成时间戳。这一个运算是与时区有关的。首先得肯定这么些刻钟是哪些时区的,然后转换成utc时区的时刻。再减去1970,得到的秒数,就是时刻戳。
  • 光阴戳是个肯定的值,他与时区没关。
  • 当想把时光戳还原成时间,必须指定时区,才能肯定什么时间。
  • 总计:时间与时区有关。时间戳与时区无关,它是utc,也就是gmt时区的时刻与1970年的差。在时间轴的某一点整日,不管位于哪个时区(如法国巴黎市
    +8钟头,或者格林威治 +0时辰),它转换成的光阴戳是相等的。
      • 首先澄清一个定义:

 

富有的linux系统文件系统底层存储的都是UTC时间,也就是说都是自1970年0时0分0秒以来的UTC标准时间的秒数。

不论是系统布局是哪些时区,呈现怎么不同,底层存储都是相同的。

 

  • 何以得到UTC系统时间?

 

在shell环境下 >date ‘+%s’ 即可取得

在mysql环境下>select unix_timestamp();即可得到

 

  • timestamp是什么?

timestamp是mysql数据库中的一种字段类型,

不要说太多,

  • 个中存储是4个字节
  • 精度达到微妙
  • 回转换成UTC时间存储
  • 读取的时候再依照时区转换回来

mysql> select now()+0;
+———————–+
| now()+0               |
+———————–+
| 20130722184134.000000 |
+———————–+
1 row in set (0.00 sec)

mysql> select now();  
+———————+
| now()               |
+———————+
| 2013-07-22 18:41:37 |
+———————+
1 row in set (0.00 sec)

可以看看,我们看到的timestamp实际是一度按照当前时区转换过格式的字符形式

 

  • 哪些在mysql中依据timestamp得到UTC系统时间戳呢吧?

很简单,mysql> select unix_timestamp( 20130722183356.000000);
+—————————————-+
| unix_timestamp( 20130722183356.000000) |
+—————————————-+
|                             1374489236 |
+—————————————-+

             

  • 怎么在mysql中依据UTC 系统时间戳得到当前时区的timestamp呢?

mysql> select from_unixtime(1374489236);
+—————————+
| from_unixtime(1374489236) |
+—————————+
| 2013-07-22 18:33:56       |
+—————————+
1 row in set (0.00 sec)

 

  •  咋样在mysql中依据近年来时区的时区得到任哪天区的timestamp呢?

mysql> SELECT CONVERT_TZ(‘2013-07-22 18:41:37′,’+08:00′,’+00:00’) as
UTC;         
+———————+
| UTC                 |
+———————+
| 2013-07-22 10:41:37 |
+———————+
1 row in set (0.00 sec)

 

 

  • 一个偶发的问题

 

数据库使用Amazon RDS 是无力回天修改时区的,统一拔取UTC时区

应用程序使用Amazon 服务器 是UTC -7 美西时光

数据库部分时光字段使用了current_timestamp,使用了UTC时区

有的字段使用了unix_time,由应用程序插入,理论上也是UTC时间

一对字段使用了unix_time并基于app服务器的时区转成了岁月的string格式,导致出现UTC-7的岁月

以致了同一IDC的数额有了二种时光

===========================================

结论:

咱俩不需要被timestamp和时区弄糊涂,其实很粗略,timestamp存储的光阴是带时区偏移的。

富有的数据库的年华应当联合操作,要么采取DB的current_timestamp,要么采用应用程序插入。

在有多IDC且不同时区的图景下,

如果急需标准UNIX时间戳:我指出只需要每一遍取出UTC的时日戳举行拍卖

虽然需要正式的timestamp,我提出任何统一convert到一个时区去处理

 


0

 

(摘自http://www.cnblogs.com/flying5/archive/2011/12/05/2276578.html)

目前在编程中相遇了岁月与时区相关的题材,整理在那边

  我的次第是一个在Hadoop上运行的分布式程序,从MySQL数据库中取数据,经过处理未来输出

一. 基本概念

  时区 :time zone
1884年国际经线会议规定,全球按经度分为24个时区,每区各占经度15°。

     
以本初子午线为中心经线的时区为零时区,由零时区向东、西各分12区,东、西12区都是半时区,共同利用180°经线的地点时。

  CST :China Standard 提姆e UTC+8:00 中国专业时间(迪拜时间),在东八区

  UTC :Universal 提姆e
Coordinated,世界和谐时间,又称世界标准时间、世界统一时间。UTC
提供了一种与时区无关(或非特定于时区)的年月。

      世界上的拥有时区都可以表示为 UTC 加上或减去一个偏移量。

      由此,UTC是0时区的日子,如时尚之都为清晨八点(东八区),UTC时间就为零点,时间比迪拜时晚八刻钟

  GMT :格林wich Mean
提姆(Tim)e格林威治标准时间,指位于大英帝国London郊区的皇家格林(Green)尼治天文台的正儿八经时间,因为本初子午线被定义在通过这里的经线。

  Unix timestamp :Unix时间戳,或称Unix时间(Unix
time)、POSIX时间(POSIX time),是一种时光代表方法,

      定义为从格林(Green)威治时间(UTC/GMT的晌午)1970年0七月01日00时00分00秒起至现在的总秒数。

  可以如此说:

  UTC和GMT几乎是如出一辙概念,两者的分别是GMT是一个天文上的概念,UTC是基于原子钟。

  GMT=UTC

  GMT + 8 = UTC + 8 = CST

  UTC+时间差=本地时间 (时间差东为正,西为负,东八区记为 +0800)

 

二. 从数据库取多少的历程

?

  mysql>select auction_id,startsfrom auctions where auction_id=88888;
+-------------+---------------------+
| auction_id  | starts |
+-------------+---------------------+
| 88888       | 2011-10-24 20:32:58 |
+-------------+---------------------+
1 rowin set (0.00 sec)
 
mysql> show columnsfrom auctions;
+--------------------------------+---------------+------+-----+---------+-------+
| Field | Type |Null KeyDefault | Extra |
+--------------------------------+---------------+------+-----+---------+-------+
|starts | datetime | YES | MUL |NULL | |

  可见:数据库的小运字段starts存的是datetime类型,它是一个和时区相关的string(显明:string都是和时区相关的)

  而且数据库是遵从CST时区存的时间

     程序中从数据库取数据用的sql语句:

?

mysql>select auction_id,DATE_FORMAT(starts,'%Y%m%d%H%i%S')from auctions where auction_id=88888;
+-------------+------------------------------------+
| auction_id  | DATE_FORMAT(starts,'%Y%m%d%H%i%S') |
+-------------+------------------------------------+
| 88888       | 20111024203258 |
+-------------+------------------------------------+
1 rowin set (0.00 sec)

  那里只是简短的用DATE_FORMAT函数把datetime类型的starts字段转换为大家需要的格式
%Y%m%d%H%i%S 而已

 

三、Java代码

  看这样一段转换时间的java代码:

?

// 将字符串时间转化为秒数(yyyyMMddHHmmss)
staticpublic long getUnixTimestamp(String srcTime)
{        
          SimpleDateFormat sdf =new SimpleDateFormat("yyyyMMddHHmmss");
          Date result_date;
          longresult_time = 0;
          try
                   result_date = sdf.parse(srcTime);
                   //返回的是毫秒数故除以1000
                   result_time = result_date.getTime()/1000;
          }catch (Exception e) { 
                   //出现异常时间赋值为20000101000000
                   result_time =946684800;
          }
          returnresult_time;
 }

  总括结果:

?

getUnixTimestamp("20111204212224") =1323004944

  表明:java.util.Date中的getTime函数定义如下:

     java.util.Date代表一个时间点,其值为距公元1970年3月1日
00:00:00的皮秒数。所以它是未曾时区和Locale概念的。

     public long get提姆e() 重返自 1970 年 1 月 1 日 00:00:00 GMT
以来此 Date 对象表示的飞秒数

  java中经过如下情势拿到当明天子点: 

?

Date now =new Date(); //这个时间点与本地系统的时区无关

  而正因为其与时区的无关性,才使得咱们的储存数据(时间)是均等的(时区一致性)。
  一般的我们将now存储于数据库中,当我们需要表现数据时,将now格式化成想要的格式,如:2011-12-04
21:22:24
  而这么些功能相似交由java.text.DateFormat来贯彻。例如:

?

SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String snow = sdf.format(now);

  我们发现snow是带时间(如2011-12-04 21:22:24)的字符串,那么
2011-12-04 21:22:24 这多少个时间是哪位时区的年华呢?

  默认情形下,SimpleDateFormat
取得当地系统的时区(我的时区为GMT+8京城),然后遵照 pattern(”yyyy-MM-dd
HH:mm:ss”)格式化now,
  此时出口的就是 GMT+8
区的日子了。假诺想协助国际化时间,则先指定时区,然后再格式化date数据。例如:

?

SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
String snow = sdf.format(now);// snow = 2011-12-04 21:22:24
sdf.setTimeZone(TimeZone.getTimeZone("GMT+7"));
String snow2 = sdf.format(now);// snow2 = 2011-12-04 20:22:24 (可见:东八区比东七区早一个小时)

  此外,你可以经过如下代码修改本地时区新闻:

?

TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));

  在windows操作系统中,是通过桌面右下角,也得以指定操作系统的时区。

  在linux系统中,通过如下命令可以博得当前时区

?

[admin@localhost]$ date -R
Sun,04 Dec 201122:49:00+0800

 

四、结论:

  get提姆(Tim)e()再次来到的早已是一个UTC的unix
timestamp秒数了,与时区无关;而更换为字符串后,就和时区相关了
  对于那一个秒数,不同时区的人,依照自己所在的时区去分析,就足以博得不错的时辰了

?

[admin@localhost]$ date -d@1323004944
201112月 04日 星期日21:22:24CST
[admin@localhost]$ date -d@1323004944 -u
201112月 04日 星期日13:22:24UTC

  对于涉嫌到时刻更换的次序来说,假如代码里面没有强行指定时区,这就会凭借于操作系统的时区。

  特别是对于分布式程序,即使不同机器上系统时区不一致,这就会油然则生不等同的数量了!

 

五、对unix timestamp和时区概念的篡改和误用

  由于历史原因,发现先后中有如此一段代码:

?

// 将字符串时间转化为秒数(yyyyMMddHHmmss),有8个小时的时差
  staticpublic long getLongTime(String srcTime)
  {        
            SimpleDateFormat sdf =new SimpleDateFormat("yyyyMMddHHmmss");
            Date result_date;
            longresult_time = 0;
            try
                     result_date = sdf.parse(srcTime);
                     //返回的是毫秒数故除以1000
                     result_time = result_date.getTime()/10008 3600;  // 这里加了八个小时
            }catch (Exception e) { 
                     //出现异常时间赋值为20000101000000
                     result_time =946684800;
            }
             
            returnresult_time;
   }

  总括结果:

?

getUnixTimestamp("20111204212224") =1323033744

  显著,那些时间比上边通过 getUnix提姆(Tim)estamp(“20111204212224”) =
1323004944 拿到的年华多了8个时辰

       1323033744 – 1323004944 = 28800 = 8 * 3600 = 8h

  假若用户将取得的 1323033744 按照自己所在的时区解析后拿到的结果是:

?

[admin@localhost]$ date -d@1323033744
201112月 05日 星期一05:22:24CST

  拿到了一个通通错误的结果!

  但即使用户将以此 1323033744 遵照UTC时区来分析后取得的结果是:

?

[admin@localhost]$ date -d@1323033744 -u
201112月 04日 星期日21:22:24UTC

  为了便利比较,把 1323004944 的辨析结果也拿来对待

?

[admin@localhost]$ date -d@1323004944
201112月 04日 星期日21:22:24CST
[admin@localhost]$ date -d@1323004944 -u
201112月 04日 星期日13:22:24UTC

  可以看出,这些代码中赢得的秒数时间是比UTC的unix
timestamp秒数多了四个钟头

    这一个时间 1323033744 可以了然为京城时区拿到的秒数,可是不是unix
timstamp时间!

    unix timestamp秒数是与时区无关的,不管是在哪些时区拿到的unix
timestamp都是如出一辙的

  我们可以作证一下,用新加坡时间“20111204212224”减去“19700000000000”得到的秒数,就是
1323033744

?

SimpleDateFormat df =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
java.util.Date end = df.parse("2011-12-04 21:22:24");
java.util.Date start = df.parse("1970-01-01 00:00:00");
longdelta = (end.getTime() - start.getTime())/1000;
System.out.println("delta="+ delta); // delta=1323033744

  或者用shell命令来求时间差

?

[admin@localhost]$ date -d"2011-12-04 21:22:24" +%s
1323004944
[admin@localhost]$ date -d"1970-01-01 0:0:0" +%s
-28800
[admin@localhost]$ date -d"2011-12-04 21:22:24" +%s -u
1323033744
[admin@localhost]$ date -d"1970-01-01 0:0:0" +%s -u
0

    1323004944 + 28800 = 1323033744

  对于东八区的人的话,1323033744 这多少个刻钟依照UTC时间足以分析正确。不可能遵照自己所在的时区去分析,不然就是错的

  不过假使是东七区的人吗?需要按照UTC时间分析后,自己去减1个时辰的时差,so
ugly!

  所以,用户在解析1323033744 那么些数额的时候:

    (1)
依照UTC时间来分析得到新加坡时间,然后依照时间差换算成自己处处时区的日子

    
   (当然,一般都是在香港时区了,所以不用换算,按UTC时间来分析就能取得正确的时间)

    (2) 将以此时刻减去8钟头得到unix
timestamp,然后遵照自己所在的时区去分析就足以了

  总括:这段代码是对unix timestamp和时区的篡改和误用。

 

六、从数据库获取unix timestamp时间

    其实从数据库是足以直接获取到unix timestamp时间的

?

mysql> select auction_id,unix_timestamp(starts)  from auctions where auction_id=88888;                                                   
 +-------------+------------------------+
 | auction_id  | unix_timestamp(starts) |
 +-------------+------------------------+
 |88888       |            1319459578 |
 +-------------+------------------------+
 1row in set (0.02 sec)

 

七、参考

  java.util.Date
 http://www.jar114.com/jdk6/zh_CN/api/java/util/Date.html

  关于java Date和时区的题材
 http://blog.163.com/haizai219@126/blog/static/444125552009101924912981/

八、unix时间戳转换工具

http://code.aosoo.com/unixtime

 

 

发表评论

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

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