也就是我执行上述代码的时刻:2017年8月24日10点15分29秒。是不是Date对象里存了年月日时分秒呢?不是的,Date对象里存的只是一个long型的变量,其值为自1970年1月1日0点至Date对象所记录时刻经过的毫秒数,调用Date对象getTime()方法就可以返回这个毫秒数,如下代码:
Date date = new Date();
System.out.println(date + ", " + date.getTime());
输出如下:
Thu Aug 24 10:48:05 CST 2017, 1503542885955
即上述程序执行的时刻是2017年8月24日10点48分05秒,该时刻距离1970年1月1日0点经过了1503542885955毫秒。反过来说,输出的年月日时分秒其实是根据这个毫秒数来反算出来的。
那这三个date对象里存的毫秒数是相同的吗?还是北京的比东京的小3600000(北京时间比东京时间晚1小时,1小时为3600秒即3600000毫秒)?答案是,这3个Date里的毫秒数是完全一样的。确切的说,Date对象里存的是自格林威治时间(
GMT
)1970年1月1日0点至Date对象所表示时刻所经过的毫秒数。所以,如果某一时刻遍布于世界各地的程序员同时执行new Date语句,这些Date对象所存的毫秒数是完全一样的。也就是说,Date里存放的毫秒数是与时区无关的。
那么北京的程序员将会打印出2017年8月24日11:17:10,而东京的程序员会打印出2017年8月24日12:17:10,伦敦的程序员会打印出2017年8月24日4:17:10。既然Date对象只存了一个毫秒数,为什么这3个毫秒数完全相同的Date对象,可以打印出不同的时间呢?这是因为Sysytem.out.println函数在打印时间时,会取操作系统当前所设置的时区,然后根据这个时区将同毫秒数解释成该时区的时间。当然我们也可以手动设置时区,以将同一个Date对象按不同的时区输出。可以做如下实验验证:
Date date = new Date(1503544630000L); // 对应的北京时间是2017-08-24 11:17:10
SimpleDateFormat bjSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 北京
bjSdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); // 设置北京时区
SimpleDateFormat tokyoSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 东京
tokyoSdf.setTimeZone(TimeZone.getTimeZone("Asia/Tokyo")); // 设置东京时区
SimpleDateFormat londonSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 伦敦
londonSdf.setTimeZone(TimeZone.getTimeZone("Europe/London")); // 设置伦敦时区
System.out.println("毫秒数:" + date.getTime() + ", 北京时间:" + bjSdf.format(date));
System.out.println("毫秒数:" + date.getTime() + ", 东京时间:" + tokyoSdf.format(date));
System.out.println("毫秒数:" + date.getTime() + ", 伦敦时间:" + londonSdf.format(date));
毫秒数:1503544630000, 北京时间:2017-08-24 11:17:10
毫秒数:1503544630000, 东京时间:2017-08-24 12:17:10
毫秒数:1503544630000, 伦敦时间:2017-08-24 04:17:10
有时我们会遇到从一个字符串中读取时间的要求,即从字符串中解析时间并得到一个Date对象,比如将
"
2017-8-24 11:17:10"
解析为一个Date对象。现在问题来了,这个时间到底指的是北京时间的2017年8月24日11:17:10,还是东京时间的2017年8月24日11:17:10?如果指的是北京时间,那么这个时间对应的东京时间2017年8月24日12:17:10;如果指的是东京时间,那么这个时间对应的北京时间就是2017年8月24日10:17:10。因此,只说年月日时分秒而不说是哪个时区的,是有歧义的,没有歧义的做法是,给出一个时间字符串,同时指明这是哪个时区的时间。
从字符串中解析时间的正确作法是:指定时区来解析。示例如下:
String timeStr = "2017-8-24 11:17:10"; // 字面时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); // 设置北京时区
Date d = sdf.parse(timeStr);
System.out.println(sdf.format(d) + ", " + d.getTime());
String timeStr = "2017-8-24 11:17:10"; // 字面时间
SimpleDateFormat bjSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
bjSdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
Date bjDate = bjSdf.parse(timeStr); // 解析
System.out.println("字面时间: " + timeStr +",按北京时间来解释:" + bjSdf.format(bjDate) + ", " + bjDate.getTime());
SimpleDateFormat tokyoSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 东京
tokyoSdf.setTimeZone(TimeZone.getTimeZone("Asia/Tokyo")); // 设置东京时区
Date tokyoDate = tokyoSdf.parse(timeStr); // 解析
System.out.println("字面时间: " + timeStr +",按东京时间来解释:" + tokyoSdf.format(tokyoDate) + ", " + tokyoDate.getTime());
字面时间: 2017-8-24 11:17:10,按北京时间来解释:2017-08-24 11:17:10, 1503544630000
字面时间: 2017-8-24 11:17:10,按东京时间来解释:2017-08-24 11:17:10, 1503541030000
可以看出,对于"2017-8-24 11:17:10"这个字符串,按北京时间来解释得到Date对象的毫秒数是
1503544630000;而按东京时间来解释得到的毫秒数是1503541030000,前者正好比后者大于3600000毫秒即1个小时,正好是北京时间和东京时间的时差。这很好理解,北京时间2017-08-24 11:17:10对应的毫秒数是1503544630000,而东京时间2017-08-24 11:17:10对应的北京时间其实是2017-08-24 10:17:10(因为北京时间比东京时间晚1个小时),北京时间2017-08-24 10:17:10自然比北京时间2017-08-24 11:17:10少3600000毫秒。
String timeStr = "2017-8-24 11:17:10"; // 字面时间
SimpleDateFormat bjSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
bjSdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
Date date = bjSdf.parse(timeStr); // 将字符串时间按北京时间解析成Date对象
SimpleDateFormat tokyoSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 东京
tokyoSdf.setTimeZone(TimeZone.getTimeZone("Asia/Tokyo")); // 设置东京时区
System.out.println("北京时间: " + timeStr +"对应的东京时间为:" + tokyoSdf.format(date));
北京时间:2017-8-24 11:17:10对应的东京时间为:2017-08-24 12:17:10
1.Date中保存的是什么在java中,只要我们执行Date date = new Date();就可以得到当前时间。如:Date date = new Date();System.out.println(date);输出结果是:Thu Aug 24 10:15:29 CST 2017也就是我执行上述代码的时刻:2017年8月24日10点15分29秒。是不是Date对象里存了年月日时分秒呢?不是...
Date
date
= new
Date
();
System.out.println(
date
);
System.out.println(
date
.getTime());
// 输出
Tue Dec 10 18:44:24 CST 2019
1575974664352
Date
中
保存的是什么?
查看源码可以知道...
近段时间,由于某种原因我一直在研究js不同地区不同
时区
之间的时间换算。北京时间早上9点,在其他地区可能已经是夜晚了。
我们都知道,国内统一使用的都是北京时间,但在国外,不仅因
时区
不同而有时间差异,同一地区还存在夏令时冬令时的时间差异,如果程序上涉及时间上的计算,要千万小心了。
一、将当前所在地区时间
转换
为UTC时间
二、将某一固定时间
转换
为UTC时间
三、将UTC时间
转换
为当前所在地区时间
四、两...
Local
Date
Time now = Local
Date
Time.now();
//规定
时区
ZoneId zone = ZoneId.of("Asia/Shanghai");
//
转换
user.setCreateTime(now.atZone(zone).toLocal
Date
Time());
两个
时区
转换
ZoneId newZone = ZoneId.of(" Ameri...
CST和GMT时间的区别
问题由来:
学习
java
.util.
Date
&
java
.sql.
Date
时,发现输出结果
中
:Sun Nov 22 13:27:45 CST 2020,于是查阅资料研学。
Main:
关于时间格式:GMT 、 UTC 、 CST 、ISO 。下文主要就CST和GMT进行整理总结。
时间格式:
GMT:(GreenwichMeanTime,GMT),格林尼治所在地的标准时间
格林尼治是英国伦敦南郊原格林威治天文台的所在地,它又是世界上地理经度的起始点。对
平时工作
中
遇到时间如何处理?用
Date
还是JDK 8之后的日期时间API?如何解决跨
时区
转换
等等头大问题。A哥向来管生管养,管杀管埋,因此本文就带你领略一下,
Java
是如何实现GMT和UTC的?
众所周知,JDK以版本8为界,有两套处理日期/时间的API:
虽然我一直鼓励弃用
Date
而支持在项目
中
只使用JSR 310日期时间类型,但是呢,由于
Date
依旧有庞大的存量用户,所以本文也不落单,对二者的实现均进行阐述。
Date
类型实现
java
.util.
Date
在JDK 1.0就已存在,用于表
根据字符串和时间格式,目标
时区
Id和源
时区
Id来
转换
public static
Date
convertZoneTimeByString(String source
Date
, String sourceZoneId, String targetZoneId,String pattern) throws ParseException {
Simple...
当在不同的
时区
使用相同程序,时间的值只会为当地时间,这样就会造成时间混乱,为了避免这个问题,可以将不同
时区
的时间先
转换
为同一
时区
时间后保存。
转换
为UTC时间
Date
now = new
Date
();
Simple
Date
Format sdf = new Simple
Date
Format("yyyy-MM-dd HH-mm-ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC");
String
date
= sdf.format(now);
这样便能将现在的
Date
date
= new
Date
();
Instant instant =
date
.toInstant();
Local
Date
Time local
Date
Time = Local
Date
Time.ofInstant(instant, ZoneId.systemDefault());
将Local
Date
Time
转换
为
Date
:
```
java
Local
Date
Time local
Date
Time = Local
Date
Time.now();
Instant instant = local
Date
Time.atZone(ZoneId.systemDefault()).toInstant();
Date
date
=
Date
.from(instant);
需要注意的是,Local
Date
Time不包含
时区
信息,而
Date
是有
时区
信息的。所以在
转换
时需要指定
时区
信息。上述示例
中
使用的是系统默认
时区
。如果需要使用其他
时区
,可以替换`ZoneId.systemDefault()`为其他
时区
的`ZoneId`实例。