Java获取当前的UTC时间

2023-05-16

Java获取当前的UTC时间

  • Java获取当前的UTC时间
    • Calendar与TimeZone
      • 结论:因此想要获取UTC时间可以修改系统默认时区或转换时区
        • 修改系统默认时区
        • SimpleDateFormat 转换时区
    • Instant

Java获取当前的UTC时间

java中如何获取utc时间,并转为Date对象,这是一个常见的问题。可能会找到如下代码的回答:

public static void main(String[] args) {
	Date current = Calendar.getInstance(TimeZone.getTimeZone("UTC")).getTime();
	System.out.println(current);
}

但是运行过后发现不能获取带UTC时间

Tue Mar 20 13:05:22 CST 2023

那么为什么不能获取,如何正确获取utc时间呢?

Calendar与TimeZone

分析一下上述代码为什么不能获取正确的UTC时间
看一下Calendar.getTime()方法

    /**
     * Returns a <code>Date</code> object representing this
     * <code>Calendar</code>'s time value (millisecond offset from the <a
     * href="#Epoch">Epoch</a>").
     *
     * @return a <code>Date</code> representing the time value.
     * @see #setTime(Date)
     * @see #getTimeInMillis()
     */
    public final Date getTime() {
        return new Date(getTimeInMillis());
    }

本质上是通过getTimeInMillis()获取了UTC的毫秒时间,然后new一个Date对象。
Date对象保存的是毫秒数,本身不带时区信息。但是如果想要把Date展现出来(比如System.out.println(new Date())实际上是生成了当前时间并调用了Date.toString()方法)时就会存在时区的概念转换,因为不是所有人都只想要UTC时间。所以当调用Date.toString()Date.parse()等方法时,就会存在时区信息。

    public String toString() {
        // "EEE MMM dd HH:mm:ss zzz yyyy";
        BaseCalendar.Date date = normalize();  // 调用此方法获取带时区信息的BaseCalendar
        StringBuilder sb = new StringBuilder(28);
        int index = date.getDayOfWeek();
        if (index == BaseCalendar.SUNDAY) {
            index = 8;
        }
        convertToAbbr(sb, wtb[index]).append(' ');                        // EEE
        convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' ');  // MMM
        CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd

        CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':');   // HH
        CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
        CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
        TimeZone zi = date.getZone();
        if (zi != null) {
            sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz
        } else {
            sb.append("GMT");
        }
        sb.append(' ').append(date.getYear());  // yyyy
        return sb.toString();
    }

    private final BaseCalendar.Date normalize() {
        if (cdate == null) {
            BaseCalendar cal = getCalendarSystem(fastTime);
            cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
                                                            TimeZone.getDefaultRef()); // 此处取的默认时区
            return cdate;
        }
        // ...
    }

可以发现toString()方法使用了normalize()初始化了一个带时区信息的BaseCalendar,而会默认使用TimeZone.getDefaultRef(),即JVM的系统默认时区。所以这里可以解释System.out.println(new Date())时打印的是带时区的时间,而非UTC时间。

结论:因此想要获取UTC时间可以修改系统默认时区或转换时区

修改系统默认时区

    public static void main(String[] args) {
        Date current = Calendar.getInstance().getTime();
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
        System.out.println(current);
    }

但是此修改可能是全局性的,建议在代码启动之初设定全部使用同一时区时间,后面就不再频繁更改,避免产生时间错乱问题。

SimpleDateFormat 转换时区


    public static void main(String[] args) {
        Date current = Calendar.getInstance(TimeZone.getTimeZone("UTC")).getTime();
        System.out.println(current);

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
        format.setTimeZone(TimeZone.getTimeZone("UTC"));
        System.out.println(format.format(current));
    };

输出

Wed Mar 22 00:29:11 CST 2023
2023-03-21 16:29:11

Instant

jdk8提供了Instant对象,Instant获取的是格林威治标准时间(UTC时间)。因为Instant是表示时间戳的对象,它不依赖于时区信息。但是在显示Instant对象时,需要将其转换为特定时区的本地时间。

    public static void main(String[] args) {
        Date current=  Date.from(Instant.now());
        System.out.println(current);
        
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  // 东京
        format.setTimeZone(TimeZone.getTimeZone("UTC"));
        System.out.println(format.format(current));
    }

输出

Wed Mar 22 00:29:11 CST 2023
2023-03-21 16:29:11
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java获取当前的UTC时间 的相关文章

  • 使用 objectGUID 进行查询 - Spring LDAP 模板

    我正在尝试获取 存储并依次使用 objectGUID 来查询 Active Directory 为了获取用户属性我正在使用以下 public static class MyDnKeyValueAttMapper implements Att
  • java替代Thread.stop()来中断特定调用

    我正在寻找一种方法来告诉这个调用 大约需要 20 120 秒 final Area image final AffineTransform transform new AffineTransform transform scale imag
  • Java,将 null 分配给对象和仅声明之间有什么区别

    之间有什么区别 Object o null and Object o 仅声明 有人可以回答我吗 这取决于您声明变量的范围 例如 局部变量没有default values在这种情况下你将不得不分配null手动 在这种情况下实例变量分配 nul
  • Eclipse 自动完成更改变量名称

    只是一个愚蠢的问题 但很难搜索 因为有很多关于 Eclipse 自动完成的主题 而且很难找到与我的问题匹配的内容 所以问题是 如果我写 MyClass MyVarName 然后按空格键 添加 new MyClass Eclipse 自动添加
  • DateTimeFormatter.parseLocalDate 抛出 UnsupportedOperationException

    该API用于解析本地日期 http joda time sourceforge net apidocs org joda time format DateTimeFormatter html parseLocalDate 28java la
  • ASM之前看一下maxStack指令吗?

    我正在尝试使用 ASM 库将字节代码转换为不同的格式 这可以使用 MethodVisitor 来完成 就像这个简单的测试代码一样 return new MethodVisitor ASM7 Override public void visi
  • 将 EditText 聚焦在设备上运行的 PopupWindow 中时出现异常

    我正在为 Android 开发一个弹出窗口 它正在工作 我在上面添加了一个 EditText 和一个按钮 当在 ADV 上运行时 它可以正常工作 而在设备上运行时 当我专注于 EditText 时 这会抛出一个奇怪的异常 android v
  • Java中的OR运算(BitSet.class)

    如何编写一个程序 该程序需要001010101110000100100 011100010001000011000 000000000010000000000100 作为输入 位 输出将是OR其中 3 个 OR 0 0 0 0 1 1 1
  • Java中无参数的for循环

    我在看别人的代码 发现了这段代码 for 我不是 Java 专家 这行代码在做什么 起初 我认为这会创建一个无限循环 但在该程序员使用的同一个类中 while true 其中 如果我错了 请纠正我 是一个无限循环 这两个相同吗 为什么有人会
  • 使用 Java 通过 HTTP 下载未知长度的文件

    我想用java下载一个HTTP查询 但是我下载的文件在下载时有一个未确定的长度 我认为这将是相当标准的 所以我搜索并找到了它的代码片段 http snipplr com view 33805 http snipplr com view 33
  • 多对多不检索映射数据

    Spring boot 2 5 6 我无法安装版本 概要文件 java Getter Setter NoArgsConstructor AllArgsConstructor EqualsAndHashCode FieldDefaults l
  • 在Spring-Boot中,我们如何在同一个项目中连接两个数据库(Mysql数据库和MongoDB)?

    我正在尝试创建一个 Spring Boot 项目 其中我有一个要求 我想连接到不同的数据库 MySql 和 MongoDB 我是否需要做一些特殊的事情来连接到这两个数据库 或者 spring boot 会自动计算出自己连接到这两个数据库 我
  • 处理照片上传的最佳方式是什么?

    我正在为一个家庭成员的婚礼制作一个网站 他们要求的一个功能是一个照片部分 所有客人都可以在婚礼结束后前往并上传他们的照片 我说这是一个很棒的想法 然后我就去实现它 那么只有一个问题 物流 上传速度很慢 现代相机拍摄的照片很大 2 5 兆 我
  • 链表中的虚拟节点

    问 什么时候使用它们 作业问题 列表中的第一个和最后一个节点 有时用作列表中的第一个和最后一个节点 从未用作列表中的第一个和最后一个节点 维基百科说 哨兵节点是与链接一起使用的专门指定的节点 列表和树作为遍历路径终止符 哨兵节点的作用是 不
  • Apache HttpClient TCP Keep-Alive(套接字保持活动)

    我的 http 请求需要太多时间才能被服务器处理 大约 5 分钟 由于连接闲置 5 分钟 代理服务器将关闭连接 我正在尝试在 Apache DefaultHttpClient 中使用 TCP Keep Alive 来使连接长时间处于活动状态
  • Microsoft JDBC 中的 JTDS 属性相当于什么?

    我正在将 JTDS 连接更改为 Microsoft JDBC 并且我看到存在于http jtds sourceforge net faq html http jtds sourceforge net faq htmlMicrosoft JD
  • 如何配置嵌入式 MongoDB 以在 Spring Boot 应用程序中进行集成测试?

    我有一个相当简单的 Spring Boot 应用程序 它公开一个小型 REST API 并从 MongoDB 实例检索数据 对 MongoDB 实例的查询通过基于 Spring Data 的存储库 下面的一些关键代码 Main applic
  • Java 相当于 Python 的 urllib.urlencode(基于 HashMap 的 UrlEncode)

    From https stackoverflow com questions 2018026 should i use urllib or urllib2 2018103 2018103 Java 中 Python 的 urllib url
  • 线程“main”中出现异常 java.lang.UnsatisfiedLinkError: ... \jzmq.dll: 找不到依赖库

    我有一个使用 ZMQ 的 java 应用程序 我已经能够在我的 Win7 PC 上运行它 我将 jzmq dll 放在 jar 可执行文件所在的同一文件夹中 然后通过命令 java jar myapp jar 运行它 我的下一步是将其移至服
  • 安卓框架?

    是否有任何框架比构建 Android 应用程序更容易 您会对其中一个感兴趣吗 很快就会有 我正在开发 DroidFu 一个 Android 共享库 它将为您提供 活动 和服务 中直接提供大量实用功能 例如生成列表和错误对话框 检查 Inte

随机推荐