一文读透时区和时间戳以及基于Java的操作

news2024/11/15 15:53:16

重要概念

1. UTC 和 UTC+8

UTC 是世界标准时间, UTC+8 是东八区标准时间,中国就属于东八区, 也就是北京时间。
+8 就是加8个小时。 时区的划分图示如下:

也就是说:
假如现在是UTC时间是 2023-08-08 01:00:00 (2023年8月8号凌晨1点),那么北京时间现在就是 2023-08-08 09:00:00 (上午9点)。

2. 时间戳

时间戳是一个数字,以UTC 的1970年1月1日作为开始时间, 也就是0开始, 后面的时间减去这个时间得到的秒数。
比如 UTC的 1970-01-01 00:00:00 的时间戳是 0 。 一分钟后 1970-01-01 00:01:00 的时间戳是 60。

为什么以这个时间作为开始呢?
因为这是 UNIX操作系统的约定, 约定 1970年1月1日作为时间纪元的开始, 后面很多计算机相关的语言,系统等都遵循了这个约定。

获取某个时间的时间戳

	@Test
	public void Timestamp(){
		LocalDateTime dateTime = LocalDateTime.of(1970, 1, 1, 0, 0, 0);// 获取时间戳(秒数)
		long timestamp = dateTime.toEpochSecond(ZoneOffset.UTC);//设置时区后获取时间戳
		System.out.println("Timestamp: " + timestamp); //0, 时间戳开始
	}
  • LocalDateTime 是一个不带时区信息的时间
  • ZoneOffset.UTC 则代表UTC 的时区

Java还提供了一个简便的方式获取当前时间的时间戳。

System.currentTimeMillis()

获取某个时区的时间

ZonedDateTime 是一个需要指定时区的时间, 比如北京时间的1970年1月1日的上午8点,可以如下表示:

ZonedDateTime utc8DateTime= ZonedDateTime.of(1970, 1, 1, 8, 0, 0,0, ZoneId.of("UTC+8"));

因为东八区的时间比UTC标准时间快8个小时,所以上面的时间也就是时间戳的开始时间。

	@Test
	public void zoneTimeStamp(){
		ZonedDateTime utc8DateTime= ZonedDateTime.of(1970, 1, 1, 8, 0, 0,0, ZoneId.of("UTC+8"));
		long timestamp =utc8DateTime.toEpochSecond();
		System.out.println("Timestamp1: " + timestamp);  //0
	}

当然,时区时间也可以从 LocalDateTime 转换而来,比如:

		LocalDateTime lcoalDateTime = LocalDateTime.of(1970, 1, 1, 8, 0, 0);
		ZonedDateTime zonedDateTime = ZonedDateTime.of(lcoalDateTime, ZoneId.of("UTC+8"));
		timestamp =zonedDateTime.toEpochSecond();
		Assert.assertEquals(0, timestamp);

时间的格式化显示

使用 DateTimeFormatter 可以将时间显示为不同格式的字符串, 示例代码如下:

	
	@Test
	public void dateTimeformatter() {
		LocalDateTime lcoalDateTime = LocalDateTime.of(1970, 1, 1, 8, 0, 0);
		ZonedDateTime zonedDateTime = ZonedDateTime.of(lcoalDateTime, ZoneId.of("UTC+8"));
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); 
		String lcoalDateTimeStr = formatter.format(lcoalDateTime);
		Assert.assertEquals("1970-01-01 08:00:00", lcoalDateTimeStr);
		
		String zonedDateTimeStr =  formatter.format(zonedDateTime);
		Assert.assertEquals("1970-01-01 08:00:00", zonedDateTimeStr);
	}

获取当前的北京时间

通过 ZonedDateTime.now() 可以获取当前的时间:

	@Test
	public void getCurrentUtc8Time() {
        // 获取UTC+8时区
        ZoneId utc8ZoneId = ZoneId.of("UTC+8");
        // 获取当前时间
        ZonedDateTime now = ZonedDateTime.now(utc8ZoneId);
        // 格式化为字符串
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");     
        String currentTime = now.format(formatter);
        // 输出时间
        System.out.println("Current time in UTC+8: " + currentTime);
	}

如果要获取的是 UTC标准时间,则需要修改上面获取的时区即可:

ZoneId.of("UTC");

时间戳转换为时间

通过Instant 可以将一个时间戳转换为时间。

	@Test
	public void timeMillisToUtc() {
		long timeMillis = 0L;
		Instant instant = Instant.ofEpochMilli(timeMillis);
		LocalDateTime utcDateTime = LocalDateTime.ofInstant(instant, ZoneId.of("UTC"));
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		String utcTime = utcDateTime.format(formatter);
		Assert.assertEquals("1970-01-01 00:00:00", utcTime);
	}

注意: 时间戳和时间无关

在实际的开发中, 遇到这样一种场景: 某些应用的授权 Token的有效截止时间是时间戳的格式,也就是一个长整型的数字, 有人会问: “这个是已经+8处理的时间吗?”,显然,这句话问的就很外行了。

一个时间戳对应的就是一个时间,也就是基于 UTC的开始时间的一个时间, 这个时间戳可以转换为不同时区的时间,但是时间戳本身并没有时区的差异。也就是说, 时间戳是0 , 对应的就是UTC时间的1970年1月1日的零点, 也就是1970年1月1日的上午8点。

总结

  • LocalDateTime 是一个和时区无关的时间处理类
  • ZonedDateTime 是一个和时区有关的时间处理类
  • 时间戳的开始时间是1970年1月1日的零点,也就是北京时间的上午8点。
  • 时间戳和时区无关

在线示例

  • https://github.com/osxm/java-ency/blob/master/src/main/java/com/osxm/je/topic/date/DateDemo.java


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/832551.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构—哈夫曼树及其应用

5.6哈夫曼树及其应用 5.6.1哈夫曼树的基本概念 路径:从树中一个结点到另一个结点之间的分支构成这两个结点间的路径。 结点的路径长度:两结点间路径上的分支数。 树的路径长度:从树根到每一个结点的路径长度之和。记作 TL 结点数目相同的…

【MySQL】MySQL数据类型

文章目录 一、数据类型的分类二、tinyint类型2.1 创建有符号数值2.2 创建无符号数值 三、bit类型三、浮点类型3.1 float3.2 decimal类型 四、字符串类型4.1 char类型4.2 varchar类型 五、日期和时间类型六、枚举和集合类型6.1 enum的枚举值和set的位图结构6.2 查询集合find_in_…

带头单链表,附带完整测试程序

🍔链表基础知识 1.概念:链表是由多个节点链接构成的,节点包含数据域和指针域,指针域上存放的指针指向下一个节点 2.链表的种类:按单向或双向、带头或不带头、循环或不循环分为多个种类 3.特点:无法直接找到…

信号源功率输出是什么意思(功率信号源)

信号源功率输出是指信号源能够输出的最大功率。在无线电通信和电子工程领域中,信号源功率输出是一项非常重要的参数,它对信号传输距离、接收灵敏度、噪声抑制等方面都有着重要的影响。 信号源功率输出与信号传输距离密切相关。在无线电通信中&#xff0c…

二叉搜索树与双向链表(牛客网 和 剑指 Offer同类型题)

文章目录 JZ36 二叉搜索树与双向链表(牛客网)剑指 Offer 36. 二叉搜索树与双向链表 JZ36 二叉搜索树与双向链表(牛客网) 题目链接 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示 注意: 1…

亚马逊品牌推荐金计划:通过亚马逊外营销活动赚取奖金!

亚马逊美国站发布公告称新推出的品牌推荐金计划可以让卖家在通过亚马逊外营销活动的销售中获得奖金,当卖家将非亚马逊营销流量引导至亚马逊时,您将获得促销产品以及客户在接下来的两周内购买的任何品牌产品平均销售额的10%的奖金,以下是公告内…

【C语言初阶】使用指针求字符串长度(五个版本盘点总结)

在代码的题目中,我们经常会遇到需要自己手写函数,求字符串长度的情况,那么今天博主就带大家一起盘点五种求字符串长度的写法 版本一:判断累加法 逻辑:由于字符串的末位是\0,且\0不计入字符串长度&#xf…

docker logs 使用说明

docker logs 可以查看某个容器内的日志情况。 前置参数说明 c_name容器名称 / 容器ID logs 获取容器的日志 , 命令如下: docker logs [options] c_name option参数: -n 查看最近多少条记录:docker logs -n 5 c_name--tail与-n 一样 &#…

C高级 作业 day2 8/3

1.脑图 2.递归实现&#xff0c;输入一个数&#xff0c;输出这个数的每一位 #include <myhead.h>void solute(int a) {if(a<10&&a>0) //如果是一位数{printf("%2d\t",a);return;}else //两位及以上{ solute(a/10);printf("%d\t",a%10…

1345:香甜的黄油(Dijkstra)---信息学奥赛一本通

【题目描述】 农夫John发现做出全威斯康辛州最甜的黄油的方法&#xff1a;糖。把糖放在一片牧场上&#xff0c;他知道N&#xff08;1≤N≤500&#xff09;只奶牛会过来舔它&#xff0c;这样就能做出能卖好价钱的超甜黄油。当然&#xff0c;他将付出额外的费用在奶牛上。 农夫Jo…

Electron 开发,报handshake failed; returned -1, SSL error code 1,错误

代码说明 在preload.js代码中&#xff0c;暴露参数给渲染线程renderer.js访问&#xff0c; renderer.js 报&#xff1a;ERROR:ssl_client_socket_impl.cc(978)] failed; returned -1, SSL error code 1,错误 问题原因 如题所说&#xff0c;跨进程传递消息&#xff0c;这意味…

Matlab对TMS320F28335编程--SVPWM配置互补PWM输出

前言 F28335中断 目的&#xff1a;FOC的核心算法及SVPWM输出&#xff0c;SVPWM的载波频率10kHz&#xff0c;SVPWM的每个周期都会触发ADC中断采集相电流&#xff0c;SVPWM为芯片ePWM4、5、6通道&#xff0c;配置死区 1、配置中断SVPWM进ADC中断&#xff0c;查上表知CPU1,PIE1 …

一个计算机专业的学生数据结构这门课学到什么程度才能算学的还不错?

数据结构之所以重要是因为它处于算法中的基础地位&#xff0c;与解决实际问题关系密切&#xff1b;而之所以不重要是因为课本上能学到的所有实现都已经有人造过轮子了&#xff0c;甚至已经作为很多语言的标准API存在了。 换句话来说&#xff0c;在以后的编码生涯中&#xff0c…

Qt tabwidget中插入widget

一、简单介绍 QT->tabWidget&#xff1a;标签页面。 在ui中通过工具栏自定义拉取控件&#xff0c;其中tabwidget可以可以创建多个标签页面&#xff0c;默认生成两个tab_widget(tab_1/tab_2)。并且可以在ui中右键自由添加控制删除等标签页&#xff0c;切换标签页就是切换widg…

TensorRT学习笔记--基于TensorRT部署YoloV3, YoloV5和YoloV8

目录 1--完整项目 2--模型转换 3--编译项目 4--序列化模型 5--推理测试 1--完整项目 以下以 YoloV8 为例进行图片和视频的推理&#xff0c;完整项目地址如下&#xff1a;https://github.com/liujf69/TensorRT-Demo git clone https://github.com/liujf69/TensorRT-Demo.…

Kubernetes高可用集群二进制部署(六)Kubernetes集群节点添加

Kubernetes概述 使用kubeadm快速部署一个k8s集群 Kubernetes高可用集群二进制部署&#xff08;一&#xff09;主机准备和负载均衡器安装 Kubernetes高可用集群二进制部署&#xff08;二&#xff09;ETCD集群部署 Kubernetes高可用集群二进制部署&#xff08;三&#xff09;部署…

8.3 C高级 Shell脚本

写一个脚本&#xff0c;包含以下内容&#xff1a; 显示/etc/group文件中第五行的内容创建目录/home/ubuntu/copy切换工作路径到此目录赋值/etc/shadow到此目录&#xff0c;并重命名为test将当前目录中test的所属用户改为root将test中其他用户的权限改为没有任何权限 #!/bin/b…

1016. 子串能表示从 1 到 N 数字的二进制串;2601. 质数减法运算;1824. 最少侧跳次数

1016. 子串能表示从 1 到 N 数字的二进制串 核心思想&#xff1a;第一种方法&#xff0c;直接将1-n转化为二进制数看它是否是在s中&#xff0c;第二种方法&#xff0c;将s的二进制字串转换为数字存在哈希表中&#xff0c;看它是否满足长度为n,然后具体的方法就是枚举字符串的左…

uC-OS2 V2.93 STM32L476 移植:串口打印篇

前言 前几篇已经 通过 STM32CubeMX 搭建了 NUCLEO-L476RG 的 STM32L476RG 的 裸机工程&#xff0c;下载了 uC-OS2 V2.93 的源码&#xff0c;并把 uC-OS2 的源文件加入 Keil MDK5 工程&#xff0c;通过适配 Systick 系统定时器与 PendSV 实现任务调度&#xff0c;初步让 uC-OS2 …

以技术驱动反欺诈,Riskified 为企业出海保驾护航

如今&#xff0c;全球对于线上消费的需求日益增长&#xff0c;各类新型支付方式也层出不穷。在国内&#xff0c;线上支付有着较为完善的法律及监管条例&#xff0c;格局基本已定型。但对于出海商家而言&#xff0c;由于不同国家和地区的支付规则和监管机制不同&#xff0c;跨境…