Date, TimeZone, MongoDB, java中date的时区问题

打印new Date(),Fri Aug 12 13:37:51 CST 2016. 显示Asia/Shanghai的时区,但是date toString 的时区简写却是CST。更坑爹的是,Google CST结果出来是Central Standard Time. 表示North American Central Standard Time. 还以为jdk的date类有问题,debug date toString发现确实是将Asia/Shanghai的name 简写成CST. 接着google,终于看到另一个:cst-china, 即China Standard Time。中国的标准时区当然是北京时间,不过在时间上就是+8,就是Asia/Shanghai.

Asia/Shanghai  -- CST  -- China Standard Time

时区的说法只是对时间的一种翻译,时间是唯一的,确定的。虽然我们北京时间会比UTC时间多8h,但这只是说法的不同,在表示时间的含义上是等价的。也就是说UTC时间0点就等价于北京时间8点。这个Date类中是通过记录UTC时间以及偏移量来表示的,不同时区只是显示的结果不同,但可以相互转换。

之所以迷惑是因为时间使用上会分两个阶段。一个是翻译阶段,一个是比较阶段。比如我传入参数2016-08-12 10:31:20,这个时间并没有指定时区,如果我想要表达的是北京时间,那么对应的就是UTC 2:31:20. 就在这里出问题。 MongoDB的时间都是UTC时间,我想要查询10点31之前的数据,然后我使用new Date来指定时间,看上去我是想要获取这个时间之前的数据,实际上却是UTC 2:31:20之前的数据。也就是说,我查出的结果并不是UTC时间上10:31之前的数据,而是北京时间10:31之前的数据。即,我查询的 数据,日期标准是按照北京时间来查询的。

因此,如果确定java的driver会自动转换date中的时区。也就是说,加入我传入参数2016-08-12 10:31:20, 并且本机器的默认时区是北京时间,MongoDB的driver在查询的时候把Date时区转换成UTC来对待,即相当于查询2016-08-12 2:31:20Z之前的数据。那么,我的结果就是北京时间31的。如果没有转化时区,MongoDB会将10:31当做UTC时间传入,那么查询的结果就是UTC时间的。所以,关键是driver是否会进行时区转换。

date设置时区

  1. 设置TimeZone default
  2. 直接设置TimeZone

1.

        Date date = new Date();
        System.out.println("default:  "+date.toString());

        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
        System.out.println("utc:  "+date);

        TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
        System.out.println("Asia/Shanghai:  "+date);

        TimeZone.setDefault(TimeZone.getTimeZone("CST"));
        System.out.println("CST:  "+date);    
default:  Fri Aug 12 10:22:51 CST 2016
utc:  Fri Aug 12 02:22:51 UTC 2016
Asia/Shanghai:  Fri Aug 12 10:22:51 CST 2016
CST:  Thu Aug 11 21:22:51 CDT 2016

2.

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
        Date parse = sdf.parse("2016-08-12 10:31:20");
        System.out.println("default: "+parse);
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
        System.out.println("UTC:  "+parse);
default: Fri Aug 12 18:31:20 CST 2016
UTC:  Fri Aug 12 10:31:20 UTC 2016

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏racaljk

Boost Coroutine2 - stackful coroutine简介

协程可以很轻量的在子例程中进行切换,它由程序员进行子例程的调度(即切换)而不像线程那样需要内核参与,同时也省去了内核线程切换的开销,因为一个协程切换保留的就是函...

823
来自专栏一个会写诗的程序员的博客

计算机中的数学【水仙花数】求解自然数中所有的水仙花数

在数论中,水仙花数(Narcissistic number),也被称为超完全数字不变数(pluperfect digital invariant, PPDI)、...

752
来自专栏运维技术迷

Python时间获取及转换

datetime是date与time的结合体,包括date与time的所有信息。 函数原型是: datetime. datetime (year, mont...

3706
来自专栏QQ空间开发团队的专栏

关于 Block 中捕获 self 的分析

最近遇到一个已经使用了 weak-strong dance 的 block 依旧强引用了self 的情况,,但这里的关键是用了weak_self的 blcok ...

1771
来自专栏文渊之博

Python中获取当前日期的格式

在Python里如何获取当前的日期和时间呢?在Python语言里,我们可以通过调用什么模块或者类函数来得到当前的时间或日期呢? 当然你可以使用时间模块(tim...

1747
来自专栏烂笔头

Python标准库笔记(3) — datetime模块

目录[-] datetime模块提供了简单和复杂的方式用于操纵日期和时间的类。虽然支持日期和时间运算,但实现的重点是为了输出格式化和操作高效地提取属性。 ...

3526
来自专栏V站

PHP日期时间函数 :time(),date(),mktime()区别

语法: int checkdate(int month, int day, int year);

1093
来自专栏技术/开源

TypeScript设计模式之装饰、代理

看看用TypeScript怎样实现常见的设计模式,顺便复习一下。 学模式最重要的不是记UML,而是知道什么模式可以解决什么样的问题,在做项目时碰到问题可以想到...

1948
来自专栏抠抠空间

python常见模块之time模块

一、模块简介 在Python中,通常有这几种方式来表示时间: 时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按...

3207
来自专栏腾讯云API

求两个自然数的最大公约数和最小公倍数

812

扫描关注云+社区