目录

一、概述

二、基础知识

2.1 时区

2.2 格林威治时间

2.3 时间戳

三、Date/Calendar/SimpleDateFormat

3.1 Date

3.2 Calendar

3.3 SimpleDateFormat 和 DateTimeFormatter


一、概述

Java提供了有关时间的类和API,可以很方便的处理日期时间。

JDK 1.8之前使用的是Date和Calendar,JDK 1.8之后使用DateTime,前者毛病较多,后者更加适用。

二、基础知识

2.1 时区

我们都知道,地球是圆的,并且在不停的自转与公转,自转一圈是为一天,公转一圈是为一年。

我们这里关注自转的部分。

圆形的地球总是存在面向太阳的半球与背向太阳的半球,面向太阳的半球为白天,背向太阳的半球为黑夜,边界区域为凌晨和傍晚。

那么在这些处于地球不同位置的地区的时间也怎么分配的呢?

如果我们规定一个统一的时间,让全球共用。这样的话,0点时分,全球将拥有各种不同的景象,有的在凌晨,有的在早晨,有的在中午,有的在下午,有的在晚上等等,这也无关大雅。

但是当一个人从一个地方到另外一个地方后,他自认为的时间与光景将不再对应,这就是时差。

举个例子,比如规定中国晚上0点为统一的0点时间,而中国和美国都是在白天工作,晚上休息,但是中国是白天的时候,美国正好是晚上,一个人从中国到达美国之后,看到的就是人们在0点上班,12点休息,这与人的行为习惯相悖!

所以有了时区的概念,将全球以经线均分为24个时区,相邻时区的时间相差一个小时,当你跨越时区时,只要将你的手表调快或调慢一个小时即可,还是满足你的0点休息,12点上班的行为习惯。

实际上我们并没有绝对的使用标准的时区来划分时间,比如中国,横跨5个时区,为了国内的时间统一,我们规定统一使用北京时间为中国的时间。

2.2 格林威治时间

有了时区的概念,那么就有一个标准时间的问题了,以哪个地方为标准来定义时间呢?

那就是格林威治时间了,即GMT(Greenwich Mean Time)。

GMT表示的是格林威治平时,是指位于英国伦敦郊区的皇家格林尼治天文台当地的平太阳时,因为本初子午线被定义为通过那里的经线。

自1924年2月5日开始,格林尼治天文台负责每隔一小时向全世界发放调时信息。国际天文学联合会于1928年决定,将由格林威治平子夜起算的平太阳时作为世界时,也就是通常所说的格林威治时间。

比如中国北京位于东八区,所以北京时间即为GMT+8,即北京时间比格林威治平时快8个小时。

2.3 时间戳

时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。

这个值是全球固定值,全球通用,虽然各地的时间不同,但是时间戳是一致的。

有了时间戳,我们就是实现不同地区时间的转换。

三、Date/Calendar/SimpleDateFormat

3.1 Date

关于Date,​​ 请查看java基础系列二十(Date类)

3.2 Calendar

关于Calendar,请查看java基础系列十四(Calendar类、时间调用)

3.3 SimpleDateFormat 和 DateTimeFormatter

SimpleDateFormat是JDK提供的用于实现Date与String之间相互转换的工具类,成为时间格式化工具。

我们来看一下简单的格式化方式:

public class SimpleDateFormatTest {public static void main(String[] args) throws ParseException {test();}public static void test() throws ParseException {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 格式化-将Date格式化输出Date date = new Date();System.out.println(sdf.format(date));// 解析-将String解析为DateString dateStr = "2019-01-01 12:12:12";System.out.println(sdf.parse(dateStr));}
}

执行结果为:

2019-02-20 18:01:30
Tue Jan 01 12:12:12 CST 2019

最后输出了“Tue Jan 01 12:12:12 CST 2019”格式的字符串是因为使用System.out.println()方式输出自动调用了Date的toString方法。

上面的东西就是基础,重点关注的是下面的内容。

SimpleDateFormat是非线程安全的类,如果将其作为共享变量使用,在多线程环境中将会发生线程安全问题。

下面是推荐的处理办法:

  1. 作为局部变量使用
  2. 加锁
  3. 使用ThreadLocal,这也是阿里巴巴java手册中推荐的方式。
public static ThreadLocal<SimpleDateFormat> sdfThreadLocal = new ThreadLocal<SimpleDateFormat>(){@Overrideprotected SimpleDateFormat initialValue() {return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");}
};
  1. 更彻底的方式是使用DateTimeFormatter来替换。

                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 格式化-将Date格式化输出Date date = new Date();System.out.println("SimpleDateFormat date 转为 String  :" + sdf.format(date));Instant instant = date.toInstant();ZoneId zone = ZoneId.systemDefault();DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);System.out.println("DateTimeFormatter date 转为 String :" + formatter.format(localDateTime));// 解析-将String解析为DateString dateStr = "2019-01-01 12:12:12";System.out.println("SimpleDateFormat String 转为 date :" + sdf.parse(dateStr));LocalDateTime localDateTime1 = LocalDateTime.parse("2021-10-18 17:44:49", formatter);System.out.println("DateTimeFormatter String 转为 LocalDateTime :" + localDateTime1);
    

    输出:SimpleDateFormat date 转为 String  :2021-10-18 17:46:16
    DateTimeFormatter date 转为 String :2021-10-18 17:46:16
    SimpleDateFormat String 转为 date :Tue Jan 01 12:12:12 CST 2019
    DateTimeFormatter String 转为 LocalDateTime :2021-10-18T17:44:49

这里只补充一点关于时区的内容:

Date其实保存的就是时间戳,我们可以通过设定时区来获取不同地点的当前时间。

public class DateTest {public static void main(String[] args) {Date date1 = new Date(0);// 格林威治1970年1月1日0点0分0秒System.out.println("格林威治0时的时间戳:" + date1.getTime());System.out.println("格林威治0时的中国时区时间:" + date1);Date date2 = new Date();// 当前时间戳System.out.println("date2的时间戳:" + date2.getTime());System.out.println("date2表示的中国时区时间:" + date2);TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));// 设置时区为美国洛杉矶时区System.out.println("date2表示的美国洛杉矶时区时间:" + date2);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));// 设置为美国纽约时区System.out.println("date2表示的美国纽约时区时间:" + sdf.format(date2));}
}

执行结果为:

格林威治0时的时间戳:0
格林威治0时的中国时区时间:Thu Jan 01 08:00:00 CST 1970
date2的时间戳:1550656106538
date2表示的中国时区时间:Wed Feb 20 17:48:26 CST 2019
date2表示的美国洛杉矶时区时间:Wed Feb 20 01:48:26 PST 2019
date2表示的美国纽约时区时间:2019-02-20 04:48:26

可见中国时区的时间确实是比格林威治时间快8个小时,而美国洛杉矶时区的时间则是比格林威治时间慢8个小时,美国纽约时区的时间又比洛杉矶快3个小时。

如果不指定时区,则自动获取操作系统的默认时区。

java基础系列十七(时间日期转换)相关推荐

  1. java hh24miss_时间日期转换工具类,获取当前时间YYYYMMDD24HHMISS、YYYYMMDDHHMISS

    packagecom.ztesoft.iotcmp.util;importcom.ztesoft.zsmart.core.log.ZSmartLogger;importjava.sql.Timesta ...

  2. Java基础系列【导读】

    Java基础系列导读 Java基础 JaveWEB Java基础 基础系列[一]-- Java语言介绍 基础系列[二]-- 环境搭建 基础系列[三]-- Java基础语法 基础系列[四]-- 面向对象 ...

  3. Java 8新的时间日期库,这二十个案例看完你还学不会算我的!!!

    Java对日期,日历及时间的处理一直以来都饱受诟病,尤其是它决定将java.util.Date定义为可修改的以及将SimpleDateFormat实现成非线程安全的.看来Java已经意识到需要为时间及 ...

  4. 夯实Java基础系列3:一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

  5. 夯实Java基础系列19:一文搞懂Java集合类框架,以及常见面试题

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

  6. 夯实Java基础系列17:一文搞懂Java多线程使用方式、实现原理以及常见面试题

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

  7. 基础的java增删改查,Java基础系列(基础):Java使用Cookie增删改查操作!

    什么是Cookie? Cookie是由W3C组织提出,最早由NetScape社区发展的一种机制. Cookie是存储于访问者的计算机中的变量.每当同一台计算机通过浏览器请求某个页面时,就会发送这个co ...

  8. 知其然,知其所以然之Java基础系列(一)

    相信大家在最初接触Java基础学习的时候,也只是跟着课本上的描述学习,知其然,不知所以然,要想成为一个Java老鸟,不仅要学会怎么用,也要知道为何这么用.在Java基础系列的博客中,我会列举一系列大家 ...

  9. 夯实Java基础系列9:深入理解Class类和Object类

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

最新文章

  1. 常见的块状和内联元素
  2. 《12个球问题》分析
  3. U3D physics总结
  4. Django框架(1.Django框架的简介)
  5. 杠上了,Linus 再次怒喷 Intel 直言“去死”
  6. 由浅到浅入门批量渲染(一)
  7. 考研心路历程2021北京交通大学计算机学院软件工程
  8. Spring Security 学习-环境搭建(一)
  9. deep learning 以及deep learning 常用模型和方法
  10. css中利用margin来隐藏元素
  11. send tcp char far_wemos D1 arduino项目实战1-TCP协议连接Tlink平台③
  12. 关于 Ubuntu Server 18.04 的网络(dchp/dns/route/PPPoE)
  13. 深入学习GridBagLayout
  14. BOS物流项目注册流程图
  15. 《动态壁纸 : 手机壁纸大全》EULA条款协议
  16. 事件委托(事件代理)是什么?有什么用?
  17. Pandas快速合并多张excel表格
  18. 关于取地址运算符以及指针10要点
  19. java cpu分配_容器中的Java:资源分配准则
  20. YOLO V2得到的启发

热门文章

  1. Linux 小程序开发日记(终章)(pyqt+yolov5)
  2. wx2540h配置教程_H3C wx3000系列配置
  3. 【JAVA】文件储存——File
  4. 柯尼卡美能达C364e安装步骤(全)-柯美复印机如何装机-柯美C364e驱动安装-柯美复印机安装扫描
  5. PS 2019 cc衣服换色+去白边
  6. Electron 远程控制
  7. hexo网页相册页面的制作
  8. 综合案例 跳转到主页面
  9. 城市地铁站点接驳公交多目标优化方法
  10. 12月19日科技资讯|富士康员工涉嫌盗卖 iPhone 零件遭调查;IntelliJ IDEA 2019.3.1 发布