Java获取当前时区时间LocalDateTime与System.currentTimeMillis

article/2025/10/30 10:40:20

Java获取当前时区时间

    • System.currentTimeMillis
    • LocalDateTime
    • 最终结果

全球根据纬度不同,划分不同的时区。对于此时此刻,大家同处同一个时间点,但是,每个时区的时间表示是不同的。Java可以使用 System.currentTimeMillisLocalDateTime相关代码获取当前时区时间。
注:之前文章有表达不清楚之处,看到评论后,重新修改了下

System.currentTimeMillis

  • System.currentTimeMillis获取当前毫秒数,与时区无关。这个Java静态方法,同一时刻在不同时区的机器上执行,结果是一致的。
  • Javanew Date()方法,也是通过System.currentTimeMillis创建当前时间对象。使用new Date()时,已经默认取当前系统时区了,所以显示的当前时区正确数字的时间。
  • java.util.Date类的部分源码如下:
	/*** Allocates a <code>Date</code> object and initializes it so that* it represents the time at which it was allocated, measured to the* nearest millisecond.** @see     java.lang.System#currentTimeMillis()*/public Date() {this(System.currentTimeMillis());}/*** Allocates a <code>Date</code> object and initializes it to* represent the specified number of milliseconds since the* standard base time known as "the epoch", namely January 1,* 1970, 00:00:00 GMT.** @param   date   the milliseconds since January 1, 1970, 00:00:00 GMT.* @see     java.lang.System#currentTimeMillis()*/public Date(long date) {fastTime = date;}
  • 再看一下java.lang.System类的具体源码
	/*** Returns the current time in milliseconds.  Note that* while the unit of time of the return value is a millisecond,* the granularity of the value depends on the underlying* operating system and may be larger.  For example, many* operating systems measure time in units of tens of* milliseconds.** <p> See the description of the class <code>Date</code> for* a discussion of slight discrepancies that may arise between* "computer time" and coordinated universal time (UTC).** @return  the difference, measured in milliseconds, between*          the current time and midnight, January 1, 1970 UTC.* @see     java.util.Date*/public static native long currentTimeMillis();
  • 可以看到currentTimeMillis取的是 between "computer time" and coordinated universal time (UTC),取的是机器时间(computer time)与那个时刻(midnight, January 1, 1970 UTC)的差值
  • 针对不同的时区(UTC+N),当前机器时间(computer time)是不同的,但是都是同一时刻(只是时间显示不同),而我们规定的那个时刻(midnight, January 1, 1970 UTC)是不变的,所以两个时刻的差值是不变的,即获取的系统毫秒数一致
  • 换个思路,System.currentTimeMillis获得的是自1970-01-01 00:00:00.000到当前时刻的类型为long的时间毫秒数。但是我们要想到,对于那个时刻(midnight, January 1, 1970 UTC)显示的时间也是不同的,例如东八区就是 1970-01-01 08:00:00.000。现在东八区与UTC差8小时,在1970年也是差8小时
  • 获取的毫秒数是系统当前时区的1970-01-01 00:00:00.000以来的毫秒数,如果使用的是linux系统默认时区(0),则对于我国的+8时区刚好差8小时毫秒数
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.TimeZone;public class TimeTest {/*System.currentTimeMillis() 获取的当前时间与 格林尼治标准时间1970年零点 相差的毫秒数东八区比UTC快8小时,东八区时间当做UTC时间去计算毫秒数,就会比实际多8 * 60 * 60 * 1000LocalDateTime.now()获取的是当前时区的时间,但它的结果值不带时区属性,把它按照UTC时区计算毫秒数,发现刚好相差8小时*/public static void main(String[] args) {String os = System.getProperty("os.name");TimeZone zone = TimeZone.getDefault();System.out.println("zone = " + zone.getID() + ", os = " + os);long time1 = System.currentTimeMillis();LocalDateTime local = LocalDateTime.now();long time2 = local.toInstant(ZoneOffset.UTC).toEpochMilli();long time3 = time2 - 8 * 60 * 60 * 1000;System.out.println("local = " + local);System.out.println("time1 = " + time1);System.out.println("time2 = " + time2);System.out.println("time3 = " + time3);}
}

运行结果

zone = Asia/Shanghai, os = Windows 10
local = 2023-06-15T00:45:24.420
time1 = 1686761124378
time2 = 1686789924420
time3 = 1686761124420
  • 换了台Linux系统机器,也设置为东八区,可以看到获取的毫秒数(对应截图时间)也和Windows机器没差别
    在这里插入图片描述
  • 将此机器切换成UTC时区,执行Java程序,再切回东八区执行,可以明细看到毫秒数一致(对应截图里的时间)
    在这里插入图片描述

LocalDateTime

  • LocalDateTime 本身不包含时区信息,它存储了年、月、日、小时、分钟、秒和纳秒等数字。
  • LocalDateTime 默认只是存储当前系统所在时区当前时刻的年月日时分秒的数字
  • LocalDateTime.now 可以在传递参数时指定时区
  • toInstant()可以指定时区生成毫秒数(这里指定国际时间 UTC 0,实际上就是 System.currentTimeMillis() + 时区偏移毫秒数)
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Calendar;
import java.util.TimeZone;public class Test3 {public static void main(String[] args) {String os = System.getProperty("os.name");TimeZone zone = TimeZone.getDefault();System.out.println("zone = " + zone.getID() + ", os = " + os);long time1 = System.currentTimeMillis();// LocalDateTime itself does not contain time zone information, it stores numbers such as year, month, day, hour, minute, second, and nanosecond.LocalDateTime local = LocalDateTime.now();System.out.println("local = " + local);long time2 = local.toInstant(ZoneOffset.UTC).toEpochMilli();// LocalDateTime.now can specify the time zone when passing the parameterLocalDateTime dtUtc = LocalDateTime.now(ZoneOffset.UTC);	System.out.println("dtUtc = " + dtUtc);long time3 = dtUtc.toInstant(ZoneOffset.UTC).toEpochMilli();Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));long time4 = calendar.getTime().getTime() ;//+ 8 * 60 * 60 * 1000;	System.out.println("time1 = " + time1);System.out.println("time2 = " + time2);System.out.println("time3 = " + time3);System.out.println("time4 = " + time3);}
}

运行结果

zone = Asia/Shanghai, os = Windows 10
local = 2022-09-04T16:25:27.030469500
dtUtc = 2022-09-04T08:25:27.031493500
time1 = 1662279926996
time2 = 1662308727030
time3 = 1662279927031
time4 = 1662279927031

最终结果

  • 其实只要服务器设置的时区是正确的,无论LocalDateTime.now()还是System.currentTimeMillis()都是正确的,都没有问题
  • 如果时区不正确,例如写代码时没考虑时区写的平台与部署的平台时区不一致(仅考虑系统时区为UTCCST),就要考虑针对时区处理下8小时毫秒数差距
  • 在不确定代码部署的平台的时区的情况下,又在最终结果里需要北京时间毫秒数(例如平台给前端雷达等设备校时,需要东八区),该怎么办?
  • 可以使用LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli()获取当前时间点的时区时间(年月日时分秒)相对于0时区(UTC)的毫秒数。再获取系统时区,判断是否为Asia/Shanghai,若不是(即时区为linux默认UTC时区),则加8小时毫秒数(8 * 60 * 60 * 1000)获得的毫秒数就是对的了
   // LocalDateTime 本身不包含时区信息(只是当前系统所在时区当前时刻的年月日时分秒)// toInstant可以指定时区生成毫秒数(这里指定国际时间 UTC 0,实际上就是 System.currentTimeMillis() + 时区偏移毫秒数)long time = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli();TimeZone zone = TimeZone.getDefault();// 东八区为北京/上海时间,国内一般使用 UTC +8(但是linux服务器、docker初始都是 UTC 0,差8小时)if (!"Asia/Shanghai".equals(zone.getID())) {time += 8 * 60 * 60 * 1000;}System.out.println("当前zone为:" + zone + ", 当前时间为:" + time);

http://chatgpt.dhexx.cn/article/R54ee91g.shtml

相关文章

关于Java currentTimeMillis方法简述

刚刚接触JAVA时&#xff0c;为了便于记录某个方法块的执行时间&#xff0c;通常都会在代码块的执行前和执行后各标记一个时间&#xff0c;取两个时间差。 但是初学者一般只会选择用LocalDateTime来标记&#xff0c;然后用Duration.between来做差值。当然&#xff0c;Duration可…

System.currentTimeMillis()计算方式与时间的单位转换

一、时间的单位转换 1秒1000毫秒(ms) 1毫秒1&#xff0f;1,000秒(s) 1秒1,000,000 微秒(μs) 1微秒1&#xff0f;1,000,000秒(s) 1秒1,000,000,000 纳秒(ns) 1纳秒1&#xff0f;1,000,000,000秒(s) 1秒1,000,000,000,000 皮秒(ps) 1皮秒1&#xff0f;1,000,000,000,000秒(s) …

Java currentTimeMillis()方法介绍

一、官方文档 参考自Java SE 8官方文档&#xff1a; 方法功能&#xff1a;返回从1970年1月1日午夜&#xff08;UTC&#xff09;开始到当前时间的毫秒值. 其中&#xff0c;需要特别说明的地方 1.午夜(midnight)指的时间是 0时0分0秒&#xff0c;UTC表示该时间是0时区的时间…

Android中Intent和IntentFilter进行通信

文章目录 Intent启动不同组件的方法ActivityServiceBroadcastReceiver Data&#xff0c;Type属性与intent-filter配置指定Action调用系统的Activity启动Activity的标准Action常量以及对应的字符串标准的Category常量以及对应的字符串 实例一查看并获取联系人电话MainActivity代…

三、Intent 和 Intent过滤器(IntentFilter)

Intent&#xff08;意图&#xff09;&#xff1a; Intent 是一个消息传递对象&#xff0c;是我们要执行操作的一个抽象描述。我们可以使用它在相应的组件中传递消息和请求。下面是它的主要使用场景&#xff1a; 1. 启动Activity 通过 startActivity() 或者 startActivityForRes…

【Android】Intent 和 Intent Filter

一. Intent 简介 Intent 是一个消息传递对象&#xff0c;您可以用来从其他应用组件请求操作。可以用于&#xff1a;启动 Activity、启动服务、传递广播。 https://developer.android.com/guide/components/intents-filtershttps://developer.android.com/guide/components/i…

Android开发——IntentFilter的匹配规则

1. IntentFilter中的过滤信息 启动Activity分为显式调用和隐式调用&#xff0c;前者没什么好讲的&#xff0c;后者需要Intent能够匹配目标组件的IntentFilter中所设置的过滤信息。包括action、category、data。 一个Activity中可以有多个IntentFilter&#xff0c;一个Intent…

Android中的Intent和Intent-filter总结

一&#xff0e;相关概念 &#xff08;一&#xff09;基本概念 Intent中文意思指”意图”,按照Android的设计理念,Android使用Intent来封装程序的”调用意图”,不管启动Activity、Service、BroadcastReceiver,Android都使用统一的Intent对象来封装这一”启动意图”。此外,Inten…

【intent-filter】AndroidManifest中<intent-filter>标签的 部分作用

这里写自定义目录标题 AndroidManifest.xmlIntent-filter 标签Intent-filter 标签中的常用元素Intent-filter 标签的作用Intent对象Intent显式启动活动窗口Intent隐式启动&#xff08;重要&#xff09; AndroidManifest.xml AndroidManifest.xml是安卓开发中主配置文件&#x…

IntentFilter功能简介

1.什么是IntentFilter &#xff1f; IntentFilter翻译成中文就是“意图过滤器”&#xff0c;主要用来过滤隐式意图。当用户进行一项操作的时候&#xff0c;Android系统会根据配置的 “意图过滤器” 来寻找可以响应该操作的组件&#xff0c;服务。 例如&#xff1a;当用户点击…

简述 IntentFilter(意图过滤器)

转载自&#xff1a;http://www.cnblogs.com/ywtk/p/4158103.html 侵删 1.什么是IntentFilter &#xff1f; IntentFilter翻译成中文就是“意图过滤器”&#xff0c;主要用来过滤隐式意图。当用户进行一项操作的时候&#xff0c;Android系统会根据配置的 “意图过滤器” 来寻找可…

IntentFilter详解

IntentFilter的意思就是意图过滤器&#xff0c;当我们隐式的启动系统组件的时候&#xff0c;就会根据IntentFilter来筛选出合适的进行启动。 如果组件的 IntentFilter 与 Intent 中的 IntentFilter 正好匹配&#xff0c;系统就会启动该组件&#xff0c;并把 Intent 传递给它。如…

WPF MessageBox简单用法

1、弹出小框 用法&#xff1a; if (MessageBox.Show("内容", "标题", MessageBoxButton.YesNo, MessageBoxImage.Information) MessageBoxResult.Yes){label1.Content "yes";}else{label1.Content "no";} 2、例子 if (MessageBo…

C# winform 中MessageBox用法大全(附效果图)

我们在程序中经常会用到MessageBox。 MessageBox.Show()共有21中重载方法。现将其常见用法总结如下&#xff1a; 1.MessageBox.Show(“Hello~~~~”); 最简单的&#xff0c;只显示提示信息。 2.MessageBox.Show(“There are something wrong!”,“ERROR”); 可以给消息框加上…

MessageBox使用详解

Messagebox是我们编写程序时都会用到的东西&#xff0c;我每次使用的时候都能让它显示出来&#xff0c;但是我并不了解它的结构&#xff0c;或者说语法&#xff0c;下面简单总结一下。 语法 Messagebox(<字符串>text,<字符串>title&#xff0c;messageboxbuttons&a…

C#中Messagebox的简单使用

MessageBox的使用方法比较多&#xff0c;下面对常用的几种做了简单的说明&#xff0c;详细的资料可参考微软官方文档。 Messagebox.Show(String) 显示具有指定文本的消息框。 private void button1_Click(object sender, EventArgs e){//Show(String).显示具有指定文本的消息…

MessageBoxA 和MessageBoxW

文章目录 第一个参数&#xff1a;第二个参数&#xff1a;第三个参数&#xff1a;第四个参数&#xff1a;补充代码实现 MessageBoxA(NULL, text, title, MB_OK) 第一个参数&#xff1a; HWND hWnd 传入一个句柄&#xff0c;这个窗口句柄代表的窗口就是这个消息窗口的所有者&…

C#中MessageBox()用法详解

简介&#xff1a; MessageBox&#xff08;&#xff09;功能是显示一个消息对话框&#xff0c;其中包含一个系统图标、 一组按钮和一个简短的特定于应用程序消息&#xff0c;如状态或错误的信息。 格式&#xff1a; MessageBox.Show&#xff08;string Text, string Caption,…

C/C++ MessageBox() 弹窗的用法

C/C MessageBox 的用法 目录 一、语法 二、头文件 三、常量 图标常量&#xff0c;按钮常量&#xff0c;返回值 四、示范 五、成品 六、通过返回值判断点击的按钮是什么 七、通过输入的文字来改变弹窗上的文字 一、语法 MessageBox(NULL,("对话框内容"),("对话…

MessageBox()函数用法及参数详解

MessageBox函数 显示模式对话框&#xff0c;其中包含系统图标&#xff0c;一组按钮和简要的特定于应用程序的消息&#xff0c;例如状态或错误信息。消息框返回一个整数值&#xff0c;指示用户单击的按钮。 语法 int MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCapti…