Java中的时间与时区__java

news/2025/2/6 7:04:05/

     转:https://yq.aliyun.com/ziliao/245667

     摘要: 本文讲的是Java中的时间与时区__java, 0. 前言: 时间格式: //世界标准时间,其中T表示时分秒的开始(或者日期与时间的间隔),Z表示这是一个世界标准时间 2017-12-13T01:47:07.081Z //本地时间,也叫不含时区信息的时间。

时间格式:

//世界标准时间,其中T表示时分秒的开始(或者日期与时间的间隔),Z表示这是一个世界标准时间 
2017-12-13T01:47:07.081Z 
//本地时间,也叫不含时区信息的时间,末尾没有Z 
2017-12-13T09:47:07.153 
//含有时区信息的时间,+08:00表示该时间是由世界标准时间加了8个小时得到的,[Asia/Shanghai]表示时区 
2017-12-13T09:47:07.153+08:00[Asia/Shanghai]

      其中最难理解的是本地时间,2017-12-13T09:47:07.153时间本身是不含有时区信息的,但是“本地”这两个字含有时间信息。所以我认为这个翻译并不好,不应该叫做“本地时间”,应该直接翻译为“不含时区信息的时间”。

     协调世界时,又称世界统一时间、世界标准时间、国际协调时间。由于英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。 
世界时UT即格林尼治平太阳时间,是指格林尼治所在地的标准时间,也是表示地球自转速率的一种形式。以地球自转为基础的时间计量系统。 

1. 先来看Java8:

      表示时间的主要有4类String、Instant、LocalDateTime、ZonedDateTime

      String是格式化的时间,Instant是时间戳,LocalDateTime是不含时区信息的时间,ZonedDateTime是含有时区信息的时间。 

1.1 它们之间的关系

1.1.1 String与LocalDateTime是等价的

       符合格式的String可以直接解析为LocalDateTime,如下:

System.out.println(LocalDateTime.parse("2017-12-13 10:10:10",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); 
输出: 2017-12-13T10:10:10

       辨析LocalDateTime最好的办法就是不要把它当成“本地时间”,它就是“不含时区信息的时间”。它只是存储了年月日时分秒,没有存储任何时区信息,具体表示哪里的时间全靠输入和输出时进行解释。与String完全等价,本质上是对String的解析,只是年月日时分秒格式化的存储到了对象当中,方便取用。

 1.1.2 Instant与ZonedDateTime是等价的

     Instant是时间戳,是指世界标准时格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数,Instant本身实际上就指明时区了,0时区。 
     ZonedDateTime是含有时区信息的时间,本质上是根据时区对Instant的格式化显示。

ZonedDateTime ztime1=ZonedDateTime.ofInstant(Instant.now(),ZoneId.systemDefault()); 
System.out.println(ztime1); System.out.println(ztime1.toInstant()); 
System.out.println(ztime1.toLocalDateTime()); 
ZonedDateTime ztime2=ZonedDateTime.ofInstant(Instant.now(),ZoneId.of("Australia/Darwin")); 
System.out.println(ztime2); 
System.out.println(ztime2.toInstant()); 
System.out.println(ztime2.toLocalDateTime()); 输出: 
2017-12-13T13:24:55.932+08:00[Asia/Shanghai] 
2017-12-13T05:24:55.932Z 
2017-12-13T13:24:55.932 
2017-12-13T14:54:55.933+09:30[Australia/Darwin] 
2017-12-13T05:24:55.933Z 
​​​​​​​2017-12-13T14:54:55.933

注释1、2输出相同,说明ZonedDateTime的存储本质是Instant; 
注释3、4输出不同,说明ZonedDateTime会根据创建ZonedDateTime对象时传入的时区,进行格式化显示。

相同的Instant,在不同的时区有不同的展示时间,所以在用Instant构造ZonedDateTime的时候需要传入时区;ZonedDateTime可以直接转化为Instant,并且不同的ZonedDateTime可能会生成同样的Instant。 

1.2 如何构造时间对象:1.2.1 直接定义

System.out.println(Instant.ofEpochMilli(System.currentTimeMillis())); System.out.println(LocalDateTime.of(2017,12,13,10,0,0,0)); System.out.println(ZonedDateTime.of(2017,12,13,10,0,0,0,ZoneId.systemDefault())); 
输出: 2017-12-13T06:22:06.581Z 2017-12-13T10:00 2017-12-13T10:00+08:00[Asia/Shanghai]

1.2.2 获取系统当前时间now()

System.out.println(Instant.now()); //世界标准时间 
System.out.println(LocalDateTime.now()); //会把世界标准时间转换为本时区的时间,但是时区信息会被丢弃 System.out.println(ZonedDateTime.now()); //会把世界标准时间转换为本时区的时间,但是时区信息会被保留 System.out.println(LocalDateTime.now(ZoneId.of("+00:00"))); //0时区的现在时间 System.out.println(ZonedDateTime.now(ZoneId.of("+00:00"))); //0时区的现在时间 
输出: 2017-12-14T02:53:05.830Z 
2017-12-14T10:53:05.904 
2017-12-14T10:53:05.906+08:00[Asia/Shanghai] 
2017-12-14T02:53:05.906 2017-12-14T02:53:05.906Z

1.2.3 解析String

System.out.println(Instant.parse("2007-12-03T10:15:30Z")); //只能解析这种格式,不能自己指定 System.out.println(LocalDateTime.parse("2017-12-13 11:51:12.083", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))); 
System.out.println(ZonedDateTime.parse("2017-12-13 11:51:12.083 +04:30", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS ZZZZZ"))); 
输出: 
2007-12-03T10:15:30Z 
2017-12-13T11:51:12.083 
2017-12-13T11:51:12.083+04:30

1.3 时间对象之间的转换: 1.3.1 Instant与LocalDateTime、ZonedDateTime之间的转换

Instant instant=Instant.now(); 
LocalDateTime localDateTime=LocalDateTime.ofInstant(instant,ZoneId.systemDefault()); 
ZonedDateTime zonedDateTime=ZonedDateTime.ofInstant(instant,ZoneId.systemDefault()); 
System.out.println(instant); 
System.out.println(localDateTime); 
System.out.println(zonedDateTime); 
System.out.println(ZoneOffset.systemDefault()); 
System.out.println(ZoneOffset.UTC); 
System.out.println(ZoneOffset.MIN); 
System.out.println(ZoneOffset.of("+08:00")); 
System.out.println(localDateTime.toInstant(ZoneOffset.UTC)); 
//在把LocalDateTime转换为Instant时,需要明确指定当前这个时间指的是那个时区的时间 System.out.println(localDateTime.toInstant(ZoneOffset.of("+08:00"))); System.out.println(zonedDateTime.toInstant()); 
输出: 
2017-12-14T01:50:26.098Z
2017-12-14T09:50:26.098 
2017-12-14T09:50:26.098+08:00[Asia/Shanghai] 
Asia/Shanghai Z -18:00 +08:00 
2017-12-14T09:50:26.098Z 
2017-12-14T01:50:26.098Z 
2017-12-14T01:50:26.098Z

1.3.2 LocalDateTime、ZonedDateTime之间的转换

Instant instant=Instant.now(); 
LocalDateTime localDateTime=LocalDateTime.ofInstant(instant,ZoneId.systemDefault()); 
ZonedDateTime zonedDateTime=ZonedDateTime.ofInstant(instant,ZoneId.systemDefault()); 
System.out.println(instant); 
System.out.println(localDateTime); 
System.out.println(zonedDateTime); 
System.out.println(ZonedDateTime.of(localDateTime,ZoneId.systemDefault())); //LocalDateTime转ZonedDateTime System.out.println(zonedDateTime.toLocalDateTime()); //ZonedDateTime转LocalDateTime 
输出: 
2017-12-14T02:01:45.145Z 
2017-12-14T10:01:45.145 
2017-12-14T10:01:45.145+08:00[Asia/Shanghai] 
2017-12-14T10:01:45.145+08:00[Asia/Shanghai] 
2017-12-14T10:01:45.145

1.4 时区之间的转换

    时区转换时要特别注意的是:用户输入的String类型的时间是没有时区信息的,需要人为指定解析。 
解析的步骤分2步: 先结合语境,分析用户时区,把用户输入的时间转化为世界标准时间; 再把世界标准时间转为需要的时区。 

1.5 关于时间的陷阱 1.5.1 问题

    因为存在时区的概念,所以会造成2个问题: 不同时区的用户,对时间的理解不同,不同时区的同一个时间String不是同一个时间戳; 不同时区的服务器,对时间的理解也不同,比如,同一份程序运行在不同时区的服务器上,当这些程序同时调用LocalDateTime.now()时,返回的结果并不同,如果操作不当很容易出现问题; 如果前台和后台程序分别部署在不同时区的服务器上,情况会更加复杂。如果用户、前台和后台程序都不在相同时区,……。 

1.5.2 解决办法 建议在系统当中统一使用时间戳,包括前后台传输和数据库存储,只有在展示的时候再转化为字符串; 如果为了处理方便建议把所有的时间都转化到0时区进行处理。

 2. Java8以前的时间API

JAVA API系列—-日期和时间相关的类 
时区转换:java new Date() 变成GMT&& GMT时间与CST时间转换 

3. 新旧时间API的转换

新旧时间API连接的桥梁是Date类和Instant类,这两个都是世界标准时间,但是Date打印的时候会转化为本地时间。

Date date=Date.from(Instant.now()); 
Instant instant=date.toInstant(); 
System.out.println(date); 
System.out.println(date.getTime()); //1 
System.out.println(instant); 
System.out.println(instant.toEpochMilli()); //2 
输出: Thu Dec 14 11:45:58 CST 2017 
1513223158588 
2017-12-14T03:45:58.588Z 
1513223158588

注释1、2输出相同,说明Date类和Instant类是等价的;

     以上是Java中的时间与时区__java的全部内容,在云栖社区的博客、问答、云栖号、人物、课程等栏目也有Java中的时间与时区__java的相关内容,欢迎继续使用右上角搜索按钮进行搜索java , java8 , 日期 时间 ,以便于您获取更多的相关知识。


http://www.ppmy.cn/news/775271.html

相关文章

UTC时间转本地时间

首先要先对UTC、GMT、CST等时间概念有所了解 1 UTC(世界标准时间) 协调世界时,又称世界标准时间或世界协调时间,简称UTC(从英文“Coordinated Universal Time”/法文“TempsUniversel Coordonn”而来),是…

utc时间 单位换算_c++ 时间类型详解 time_t

Unix时间戳(Unix timestamp),或称Unix时间(Unix time)、POSIX时间(POSIX time),是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。Unix时间戳不仅被使用在Unix 系统、类Unix系统中,也在许多其他操作系统中被广告采用。 目前相当一部分…

linux锁定系统时间设置,设置linux系统时间的方法

尝试了好多,都是因为权限问题失败,但是总结出了几种思路: 1 通过linux指令进行设置: date -s "20091112 18:30:50" &&hwclock --systohc 执行该指令时,需要先切换到root,在一般用户下用sudo也不行。我做成一个脚本文件,但是不能在一般用户下执行成功。…

嵌入式Linux系统时间和RTC时间

1 概念 1.1 “系统时间”与“硬件时间” Linux时钟分为系统时钟(System Clock)和硬件(Real Time Clock,简称RTC)时钟。系统时钟是指当前Linux Kernel中的时钟,而硬件时钟则是主板上由电池供电的时钟&…

Node.js中怎么获取北京时间?

基于Node.js开发开发的时候,调用new Date()出来的时间是这样的: 2017-01-18T09:30:38.405Z 而当前时间北京时间是17:30,为了不让自己总有穿越感,于是需要转换一下。 过程可以是这样的(在Node.js的命令行下&#xff0…

Java时间类型转换详细代码示例

Java时间类型转换详细代码示例 一、时间类型转换代码示例二、时间标准简介1、UTC(世界标准时间)2、GMT(格林尼治平时)3、CST(北京时间) 三、SimpleDateFormat 参数对照表 一、时间类型转换代码示例 示例代码如下: package com.lyp;import java.text.ParseExceptio…

7、添加billboard小旗子

本节演示添加billboard小旗子,使用第四节click的例子,通过鼠标点击地图添加billboard添加小旗子。 1、修改鼠标点击事件mouseUp,在函数中创建BillboardCollection对象并添加到地图中。鼠标点击时获取鼠标位置,转换成经纬度然后添…

互联网生活中的隐私保护:用隐私换便利还是花钱护隐私?

近日,某高校毕业生在校期间窃取学校内网数据,收集全校学生个人隐私信息的新闻引发了人们对互联网生活中个人信息安全问题的再度关注。在大数据时代,算法分发带来了隐私侵犯,在享受消费生活等便捷权利的同时,似乎又有不…