总结工作中遇到的日期UTC与GMT转换问题!
1:在不同系统中,对于数据的存储方式是不同的,但是不管用的哪个sql数据库,里面都支持日期类型的存储!
我见过日期字段存储string的,见过存储lang类型的,最多的还是常规的日期类型的,因为简单易懂,不用再代码里进行频繁处理或者解码!
2:我用的语言是Java,Java对日期类的操作有封装好的操作类,各大网站上也都用数不清的源码提供参考,这对我们开发速度有很大的提升,我以前没遇到过这种类似时区的转换问题,这次遇到了就总结一下!
首先说一下我遇到的这个问题:
我们用的是mongodb数据库(Nosql类),我需要做的是上一篇文章提到的那个根据日期区间检索成功订单,接口接收到的日期是string类型的数据格式如下:
String StartDateTime="2018-05-20T00:00:00"; String EndDateTime="2018-05-24T23:59:59";
由于开发前第三方并未对日期进行说明(我做的接口是提供给给第三方调用的),所以当时就简单做了转:date,做好测试时第三方说功能没问题,就是日期显示有问题,由于是订单的对账接口(目前国内的涉及到第三方的很少有提供这个接口的,一般是第三方给本方提供对方保存的订单信息),所以会有争议,日期在这里显得极其的重要!
现在说一下数据库保存的日期类型,我当时到服务器查看mongo保存的订单信息,日期字段保存的是:IOSDate(); 当时看了有点蒙,就想这是个什么类型,其实就是GMT,格林时间。
这个日期类型和Java中的date有什么区别呢,就是两个时间相差8小时(毫秒忽略),那就好弄了,开始想办法处理String日期:我用到了Java中日期的格式化类:
SimpleDateFormat
源码:
SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
这个类引用的是:
import java.text.SimpleDateFormat;
这个类包!
由于我数据库操作都写好了,所以就没有在改传值问题,直接在controller中对数据进行操作的。向数据库操作接口传的就是string,第三方传过来的都是UTC转成的字符串,回传信息时也要回传UTC的字符串格式,这个两个问题简单,都是通过
SimpleDateFormat
来操作;这个类里除了能按照需求定义显示格式,还可以完成date和string之间的转换。
直接上源码及截图:(使用这个类的方法,需要捕获异常,或者抛出异常)
public static void main(String[] args) throws ParseException {
SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
String StartDateTime="2018-05-20T00:00:00";
String EndDateTime="2018-05-24T23:59:59";
Date startDate = simple.parse(StartDateTime);
Date endDate = simple.parse(EndDateTime);
System.out.println(startDate);
System.out.println("-------------------");
System.out.println(endDate);
}
结果:
接下来是date转成string:
String startTime = simple.format(startDate);
String endTime = simple.format(endDate);
System.out.println(startTime);
System.out.println("-------------------");
System.out.println(endTime);
结果:
这样string和date的转换就搞定了,接下来就是UTC与GMT的转换了,这个我也是百度了资料,自己也测试过几个办法,simpleDateFormat这个方法可以设置时区,我当时就想通过这个类完成所有的操作,然后反复测试了达不到效果,决定放弃,找个新的方法,后来查到了个方法,绝对比设置时区这个操作有效,并且可扩展性强。
直接上源码:
Calendar calle = Calendar.getInstance();
calle.setTime(date);
calle.add(Calendar.HOUR_OF_DAY, +8);
这个可以根据自己的需要对日期进行加减时间,我项目里回传时也要回传UTC格式化后的string,所以我就自己封装了个方法,如下:
private static Date modifyTime(Date date, String operation){
if ("plus".equals(operation)){
Calendar calle = Calendar.getInstance();
calle.setTime(date);
calle.add(Calendar.HOUR_OF_DAY, +8);
return calle.getTime();
}
if ("reduce".equals(operation)){
Calendar calle = Calendar.getInstance();
calle.setTime(date);
calle.add(Calendar.HOUR_OF_DAY, -8);
return calle.getTime();
}
return date;
}
进行测试:
public static void main(String[] args) throws ParseException {
SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
String StartDateTime="2018-05-20T00:00:00";
String EndDateTime="2018-05-24T23:59:59";
Date start = simple.parse(StartDateTime);
Date end = simple.parse(EndDateTime);
System.out.println(start);
System.out.println("-------------------");
System.out.println(end);
System.out.println("=================================");
Date startDate = modifyTime(start,"plus");
Date endDate = modifyTime(end,"plus");
System.out.println(startDate);
System.out.println("-------------------");
System.out.println(endDate);
}
结果:
以上测试我调用的是加8小时,可以根据需求调用不同的处理。这样所有的问题就解决啦,可以码代码完成模块了!