摘要:System.currentTimeMillis()获取的时间戳与时区无关。

综述

  System.currentTimeMillis()经常被用来获取当前时间戳,单位是毫秒,可以用来计算当前年月日或者星期几等,可以方便地与Date进行转换,可以计算某个方法的耗时:

long curTime = System.currentTimeMillis();
doSth();
System.out.println("耗时 = " + (System.currentTimeMillis()-curTime));

  正因为该方法是当前时间节点与0时区(1970-01-01 00:00:00 +0:00)相差的毫秒数,所以在这个时间节点,无论在哪个时区获取时间戳,其值丝毫不差。

测试用例

  如何验证它不会因为时区不同而返回不同的数值呢?测试用例很简单:调用函数TimeZone.setDefault(TimeZone zone)初始化操作系统时区为上海,打印一次时间戳的计算结果,接着切换操作系统的时区到东京,再运行一次,得到时间戳2。时间戳2和时间戳1的差值,等于切换时区的耗时,看看此耗时是否非常地小;为了使得实验效果更理想,每次切换时区都打印时分秒格式的当前时间,而且加了一组巴黎时区的数据。

    public static void main(String[] args) throws InterruptedException {
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
long timestamp1 = System.currentTimeMillis();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(df.format(new Date())); System.out.println("时间戳: " + timestamp1 + ",OS time zone: " + ZoneId.systemDefault());
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Tokyo"));
long timestamp2 = System.currentTimeMillis();
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(df.format(new Date()));
System.out.println("时间戳: " + timestamp2 + ",OS time zone: " + ZoneId.systemDefault());
System.out.println("timestamp2 - timestamp1 = " + (timestamp2 - timestamp1)); TimeZone.setDefault(TimeZone.getTimeZone("Europe/Paris"));
long timestamp3 = System.currentTimeMillis();
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(df.format(new Date()));
System.out.println("时间戳: " + timestamp3 + ",OS time zone: " + ZoneId.systemDefault());
System.out.println("timestamp3 - timestamp1 = " + (timestamp3 - timestamp1));
}

实验结果如下:

2023-08-05 12:20:59
时间戳: 1691209259885,OS time zone: Asia/Shanghai
2023-08-05 13:21:00
时间戳: 1691209260033,OS time zone: Asia/Tokyo
timestamp2 - timestamp1 = 148
2023-08-05 06:21:00
时间戳: 1691209260035,OS time zone: Europe/Paris
timestamp3 - timestamp1 = 150

  分析实验结果可知:

  1. 函数System.currentTimeMillis()与时区毫无瓜葛。
  2. df.format(new Date()) 的执行结果和时区休戚相关。其实,SimpleDateFormat的对象df可以调用函数df.setTimeZone(TimeZone.getTimeZone("UTC"))设置时区。

  关于时间的存储和显示问题,基于数据的存储和显示相分离是非常基础的设计原则,在数据库存储时间的时候,只保存表示绝对时间的Long型时间戳,不用顾虑应用服务器和数据库服务器的时区设置问题,在显示给用户的时候,根据用户设置的时区转换为字符串。

小结

  函数System.currentTimeMillis()获取的时间戳与时区无关。基于时间戳的时间存储不存在时区的问题,时区只与页面显示绑定。也就是说,在进行时间戳和日期之间的转换时,需要根据不同的时区进行计算,以防止出现时间偏差。

System.currentTimeMillis()与时区无关的更多相关文章

  1. System.nanoTime与System.currentTimeMillis的理解与区别

    System类代表系统,系统级的很多属性和控制方法都放置在该类的内部.该类位于java.lang包. 平时产生随机数时我们经常拿时间做种子,比如用System.currentTimeMillis的结果 ...

  2. System.nanoTime与System.currentTimeMillis的区别

    平时产生随机数时我们经常拿时间做种子,比如用 System.currentTimeMillis的结果,但是在执行一些循环中使用了System.currentTimeMillis,那么每次的结 果将会差 ...

  3. JAVA获取当前系统时间System.currentTimeMillis()

    System.currentTimeMillis()产生一个当前的毫秒,这个毫秒其实就是自1970年1月1日0时起的毫秒数,Date()其实就是相当于Date(System.currentTimeMi ...

  4. System.nanoTime与System.currentTimeMillis的区别(转)

    原文地址:http://blog.csdn.net/dliyuedong/article/details/8806868 平时产生随机数时我们经常拿时间做种子,比如用System.currentTim ...

  5. new Date().getTime()和System.currentTimeMillis()对比

    我在工作中,看项目组的代码时,在代码中会发现一个有趣的现象,有使用new Date().getTime()来获取时间戳的, 也有使用System.currentTimeMillis()来获取时间戳的, ...

  6. 我的Java开发学习之旅------>System.nanoTime与System.currentTimeMillis的区别

    首先来看一道题:下面代码的输出结果是什么? import java.util.HashMap; import java.util.Map; public class HashMapTest { pub ...

  7. JAVA获取当前系统时间System.currentTimeMillis()以及获取运行时间

    System.currentTimeMillis()产生一个当前的毫秒,这个毫秒其实就是自1970年1月1日0时起的毫秒数,Date()其实就是相当于Date(System.currentTimeMi ...

  8. java的System.currentTimeMillis()如何转换成C#的DateTime.Now.Ticks?

    考虑到我们是东八时区的话,应做如下转换: long milli = System.currentTimeMillis() + 8*3600*1000; long ticks = (milli*1000 ...

  9. 由system.currentTimeMillis() 获得当前的时间

    System类代表系统,系统级的很多属性和控制方法都放置在该类的内部.该类位于java.lang包. currentTimeMillis方法 public static long currentTim ...

  10. c# 实现 java 的 System.currentTimeMillis() 值

    本文地址:http://www.cnblogs.com/jying/p/3875331.html 以下一句即可实现 java 中的 System.currentTimeMillis() 值 , , , ...

随机推荐

  1. 豆包:php如何模拟多客户端访问服务器

    在 PHP 中模拟多客户端访问服务器可以通过以下几种方式实现,具体方法根据需求选择: 方法 1:使用 cURL 多请求(Multi Handle) 通过  curl_multi_*  系列函数实现并发 ...

  2. 探秘Transformer系列之(12)--- 多头自注意力

    探秘Transformer系列之(12)--- 多头自注意力 目录 探秘Transformer系列之(12)--- 多头自注意力 0x00 概述 0x01 研究背景 1.1 问题 1.2 根源 1.3 ...

  3. 使用PySide6/PyQt6实现Python跨平台通用列表页面的基类设计

    我在随笔<使用PySide6/PyQt6实现Python跨平台GUI框架的开发>中介绍过PySide6/PyQt6 框架架构的整体设计,本篇随笔继续深入探讨框架的设计开发工作,主要针对通用 ...

  4. Golang入门:Linux上的go语言安装与配置

    Tips:本文以本文撰写时的 Go 语言最新版本,也就是 go.1.19.2 版本为例. Linux 发行版本使用 Ubuntu 22.04.1 LTS 为例来做演示. 安装 C 工具 Go 的工具链 ...

  5. vue 保留两位小数

    前言 有时候我们需要对各种数值进行保留位数,以便于更好的展示. Html部分 template中这样使用,需要处理的字段名,再加上过滤器方法 <div class="text prim ...

  6. Mqtt集成与设计

    Mqtt集成 集成mqtt,我们首先得明白什么是mqtt: MQTT(Message Queuing Telemetry Transport)是一种轻量级.基于发布-订阅模式的消息传输协议,适用于资源 ...

  7. Windows 10右键添加 "在此处打开命令窗口" 菜单

    1.添加右键菜单的两种效果: 第一种是在 桌面/文件夹窗口中/选中文件夹上直接点击右键,显示"在此处打开命令窗口"选项,如图: 第二种是在 桌面/文件夹窗口中/选中文件夹上按住Sh ...

  8. 使用UNRAID系统,搭建ALL IN ONE全过程

    NAS最强攻略:使用UNRAID系统,搭建ALL IN ONE全过程!超万字教程,绝对干货! 2020-06-01 11:24:27 1690点赞 11149收藏 717评论 创作立场声明:熬了几个通 ...

  9. 05 过拟合(over-fitting)与正则化(regularization)

    1. 什么是Overfitting 我们希望神经网络模型能够找到数据集中的一般规律,从而帮助我们预测未知数据.这个过程是通过不断地迭代优化损失函数(也就是预测值和实际值的误差)而实现的.然而随着误差进 ...

  10. MYSQL架构介绍

    专栏持续更新中- 本专栏针对的是掌握MySQL基本操作后想要对其有深入了解并且有高性能追求的读者. 第一篇文章主要是对MySQL架构的主要概括,让读者脑海中有个对MySQL大体轮廓,很多地方没有展开细 ...