也就是我执行上述代码的时刻: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`实例。