UTC时间转本地时间

更新时间:2018-07-20 14:06:08 点击次数:2095次

首先要先对UTC、GMT、CST等时间概念有所了解

1 UTC(世界标准时间)

协调世界时,又称世界标准时间或世界协调时间,简称UTC(从英文“Coordinated Universal Time”/法文“TempsUniversel Coordonné”而来),是主要的世界时间标准,其以原子时秒长为基础,在时刻上尽量接近于格
林尼治标准时间。

2 GMT(格林尼治平时)

格林尼治平时(又称格林尼治平均时间或格林尼治标准时间,旧译格林威治标准时间;英语:Greenwich MeanTime,GMT)是指位于英国伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义在通过那里的经线。
理论上来说,格林尼治标准时间的正午是指当太阳横穿格林尼治子午线时(也就是在格林尼治上空高点时)的时间。由于地球在它的椭圆轨道里的运动速度不均匀,这个时刻可能与实际的太阳时有误差,大误差达16分钟
。由于地球每天的自转是有些不规则的,而且正在缓慢减速,因此格林尼治时间已经不再被作为标准时间使用。现在的标准时间,是由原子钟报时的协调世界时(UTC)。

3 CST(北京时间)

北京时间,China Standard Time,中国标准时间。在时区划分上,属东八区,比协调世界时早8小时,记为UTC+8。不过这个CST这个缩写比较纠结的是它可以同时代表四个不同的时间: 
Central Standard Time (USA) UT-6:00 
Central Standard Time (Australia) UT+9:30 
China Standard Time UT+8:00 
Cuba Standard Time UT-4:00

基本概念:

GMT 和 UTC 可以互换,但是实际上,GMT 是一个时区,而 UTC 是一个时间标准。

ISO8601
国际标准化组织的国际标准ISO 8601是日期和时间的表示方法,全称为《数据存储和交换形式·信息交换·日期和时间的表示方法》。目前新为第三版ISO8601:2004,版为ISO8601:1988,第二版为ISO8601:2000。
日期和时间的组合表示法
日期和时间合并表示时,要在时间前面加一大写字母T,如要表示北京时间2004年5月3日下午5点30分8秒,可以写成2004-05-03T17:30:08+08:00或20040503T173008+08。

ISO8601与UTC的区别,其实两者完全是两个东西,通俗的说,iso8601是一种utc时间的表示方式而已。

本地时间 :UTC + (+0800) = 本地(北京)时间

时间戳 :时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数

时间字符串

我们先说复杂的时间字符串形式。它实际上支持两种格式:一种是 RFC-2822 的标准;另一种是 ISO 8601 的标准。我们主要介绍后一种。

RFC-2822标准格式大致是:Wed Mar 25 2015 09:56:24 GMT+0100

ISO 8601标准格式大致是:2018-05-23T16:05:52.123+08:00 

以下会用到三种时间字符串表示形式,时间格式:
2018-05-23T16:05:52.123+08:00    //"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
2018-05-24 00:05:52     //"yyyy-MM-dd HH:mm:ss"
Thu May 24 00:05:52 CST 2018   //"EEE MMM dd HH:mm:ss zzz yyyy"

ISO 8601
ISO 8601的标准格式是:YYYY-MM-DDTHH:mm:ss.sssZ,分别表示:

这里我们主要来说下 T、以及 Z。

T
T 也可以用空格表示,但是这两种表示有点不一样,T 其实表示 UTC,而空格会被认为是本地时区(前提是不通过 Z 指定时区)。比如下面的例子:(转换函数请拉倒底部)


  1. String utcTime = "2018-05-23 16:05:52";
  2. String utcTimePatten = "yyyy-MM-dd HH:mm:ss";
  3. String localTimePatten = "yyyy-MM-dd HH:mm:ss"
  4. 转换后:
  5. 2018-05-23 16:05:52    //"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
  6. 2018-05-24 00:05:52     //"yyyy-MM-dd HH:mm:ss"
  7. Thu May 24 00:05:52 CST 2018   //"EEE MMM dd HH:mm:ss zzz yyyy"

  1. String utcTime = "2018-05-23T16:05:52";
  2. String utcTimePatten = "yyyy-MM-dd'T'HH:mm:ss";
  3. String localTimePatten = "yyyy-MM-dd HH:mm:ss";
  4. 2018-05-23T16:05:52
  5. 2018-05-24 00:05:52
  6. Thu May 24 00:05:52 CST 2018

不加时区,不管日期与时间之间是空格还是T都会被认为是GMT时区,而本地时区为东八区,所以后转换的时间会在原基础上有8小时的偏移。2018-05-23T16:05:52和2018-05-23T16:05:52.000+00:00是等价的。

Z
Z 用来表示传入时间的时区(zone),不指定并且没有使用 T 分隔而是使用空格分隔时,就按GMT时区处理,比如下面的例子:


  1. String utcTime = "2018-05-23 16:05:52 ";
  2. String utcTimePatten = "yyyy-MM-dd HH:mm:ss";
  3. String localTimePatten = "yyyy-MM-dd HH:mm:ss";
  4. 2018-05-23 16:05:52
  5. 2018-05-24 00:05:52
  6. Thu May 24 00:05:52 CST 2018
  7. 没有指定时区,默认为GMT时区,显示的时间会加上本地时区的偏移(8 小时)

  1. String utcTime = "2018-05-23T16:05:52.000+00:00";
  2. String utcTimePatten = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
  3. String localTimePatten = "yyyy-MM-dd HH:mm:ss";
  4. 2018-05-23T16:05:52.000+00:00
  5. 2018-05-24 00:05:52
  6. Thu May 24 00:05:52 CST 2018
  7. 因为指定时区GMT时区(偏移为 0),显示的时间会加上本地时区的偏移(8 小时)

  1. String utcTime = "2018-05-23T16:05:52.000+08:00";
  2. String utcTimePatten = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
  3. String localTimePatten = "yyyy-MM-dd HH:mm:ss";
  4. 2018-05-23T16:05:52.000+08:00
  5. 2018-05-23 16:05:52
  6. Wed May 23 16:05:52 CST 2018
  7. 东八区时间,显示的时间和传入的时间一致(因为我本地时区是东八区)。

将ISO8061格式的中的毫秒去掉,yyyy-MM-dd'T'HH:mm:ss.SSSXXX格式中的.SSS就是表示毫秒的意思


  1. String utcTime = "2018-05-23T16:05:52+08:00";
  2. String utcTimePatten = "yyyy-MM-dd'T'HH:mm:ssXXX";
  3. String localTimePatten = "yyyy-MM-dd HH:mm:ss";
  4. 2018-05-23T16:05:52+08:00
  5. 2018-05-23 16:05:52
  6. Wed May 23 16:05:52 CST 2018

yyyy-MM-dd'T'HH:mm:ss.SSSXXX格式中的XXX表示时区,一个X表示+08,三个X表示+08:00


  1. String utcTime = "2018-05-23T16:05:52+08:30";
  2. String utcTimePatten = "yyyy-MM-dd'T'HH:mm:ssX";
  3. String localTimePatten = "yyyy-MM-dd HH:mm:ss";
  4. 2018-05-23T16:05:52+08:30
  5. 2018-05-23 16:05:52
  6. Wed May 23 16:05:52 CST 2018
  7. 一个X只读取了时区+08:30中的+08,而30却别忽略了
  8. String utcTime = "2018-05-23T16:05:52+08:30";
  9. String utcTimePatten = "yyyy-MM-dd'T'HH:mm:ssXXX";
  10. String localTimePatten = "yyyy-MM-dd HH:mm:ss";
  11. 2018-05-23T16:05:52+08:30
  12. 2018-05-23 15:35:52
  13. Wed May 23 15:35:52 CST 2018
  14. 三个X,时间在原有的基础上又多了30分钟,所以XXX表示的是+08:30,而X只表示+08

2018-05-23T16:05:52.123Z时间格式


  1. String utcTime = "2018-05-23T16:05:52.123Z";
  2. String utcTimePatten = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
  3. String localTimePatten = "yyyy-MM-dd HH:mm:ss";
  4. 2018-05-23T16:05:52.123Z
  5. 2018-05-24 00:05:52
  6. Thu May 24 00:05:52 CST 2018
  7. 默认为GMT时区,显示的时间会加上本地时区的偏移(8 小时)

完整代码


  1. import java.text.ParseException;
  2. import java.text.ParsePosition;
  3. import java.text.SimpleDateFormat;
  4. import java.util.Date;
  5. import java.util.TimeZone;
  6. public class Test {
  7. public static void main(String[] arg) {
  8. String utcTime = "2018-05-23T16:05:52.123+08:00";
  9. String utcTimePatten = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
  10. String localTimePatten = "yyyy-MM-dd HH:mm:ss.SSS";
  11. System.out.println(utcTime);
  12. System.out.println(utc2Local(utcTime,utcTimePatten, localTimePatten));
  13. System.out.println(str2DateLong(utc2Local(utcTime,utcTimePatten, localTimePatten)));
  14. }
  15. public static Date str2DateLong(String strDate) {
  16. SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  17. ParsePosition pos = new ParsePosition(0);
  18. Date strtodate = formatter.parse(strDate, pos);
  19. return strtodate;
  20. }
  21. /**
  22. * 函数功能描述:UTC时间转本地时间格式
  23. * @param utcTime UTC时间
  24. * @param utcTimePatten UTC时间格式
  25. * @param localTimePatten 本地时间格式
  26. * @return 本地时间格式的时间
  27. * eg:utc2Local("2017-06-14T09:37:50.788+08:00", "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", "yyyy-MM-dd HH:mm:ss.SSS")
  28. */
  29. public static String utc2Local(String utcTime, String utcTimePatten, String localTimePatten) {
  30. SimpleDateFormat utcFormater = new SimpleDateFormat(utcTimePatten);
  31. utcFormater.setTimeZone(TimeZone.getTimeZone("UTC"));//时区定义并进行时间获取
  32. Date gpsUTCDate = null;
  33. try {
  34. gpsUTCDate = utcFormater.parse(utcTime);
  35. } catch (ParseException e) {
  36. e.printStackTrace();
  37. return utcTime;
  38. }
  39. SimpleDateFormat localFormater = new SimpleDateFormat(localTimePatten);
  40. localFormater.setTimeZone(TimeZone.getDefault());
  41. String localTime = localFormater.format(gpsUTCDate.getTime());
  42. return localTime;
  43. }
  44. }

本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是一个个人学习交流的平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽,造成漏登,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

回到顶部
嘿,我来帮您!