时区、时间戳、时间点三者的关系

news2025/1/21 2:59:49

时区、时间戳、时间点这三个概念与Java的Date类和Calendar类紧密联系。分别说说区别。然后说一下Java的Date类和Calendar

1. 时间戳

时间戳指的就是Unix时间戳(Unix timestamp)。它也被称为Unix时间(Unix time)、POSIX时间(POSIX time),是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。时间戳是没有时区的概念的,在不同的时区下,System.currentTimeMillis() 获得的值是一样的,即使在中国和美国都一样。也可以理解为UTC此刻的时间到格林威治时间的总秒数。测试如下:

public class Main {
    public static void main(String[] args) {
        System.out.println("===========TimeStamp at different TimeZone=============\n");
        System.out.println("Local timeStamp is: " + getTimeZoneTimeNow(TimeZone.getDefault().getID()));
        System.out.println("timeStamp at UTC-05:00 is: " + getTimeZoneTimeNow("UTC-05:00"));
    }

    // 获取某个时区当前的时间戳
    public static long getTimeZoneTimeNow(String timeZoneId) {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(timeZoneId));
        return calendar.getTimeInMillis();
    }
}

===========TimeStamp at different TimeZone=============

Local timeStamp is: 1700098745560
timeStamp at UTC-05:00 is: 1700098745579

可以看到不同时区下时间戳是一致的

2. 时区

虽然全世界都规定了统一的时间戳,但是由于太阳的东升西落,每个地方早上和晚上的时间点不一样,如果都采用UTC-00:00时间那么全世界统一是一个问题。人类为了适配太阳的升落引入了时区的概念,按照经度划分将地球分为24个时区,每个时区15度。相邻时区间相差一小时。本初子午线(格林尼治子午线,是位于英国格林尼治天文台的一条经线(亦称子午线)为UTC-00:00)标准时间,向东依次为UTC+01:00, UTC+02:00等时区,向西为UTC-01:00, UTC-02:00等时区。全世界通过UTC来协调各地时间。查看世界所有时区网站
在这里插入图片描述

3. 时间点

既然有了时区和时间戳的概念,那么两者结合起来就可以得到一个时间戳在不同时区下对应的时间点了。因此我们平时说的时间其实北京时间18:00整。翻译过来就是某一个时间戳在UTC+08:00下对应的时间点为18:00。如果单说18:00整而不说时区那就是有歧义的。这个时刻在不同的时区下时间点是不一样的。

4. Date类

Java中的Date类查看源码可以知道表示的是某一个时刻的的时间戳。没有时区的概念。值为自1997-01-01 00:00:00(GMT)至Date对象记录时刻所经过的毫秒数可以通过getTime()方法,获取这个变量值,且这个变量值和时区没有关系全球任意地点同时执行new Date().getTime()获取到的值相同。

    public Date() {
        this(System.currentTimeMillis());
    }

4.1 Date类格式化涉及时区

查看 Date类的toString方法,可以得到其是根据本地时区进行转化的。因此得到的是本地时间。不管是调用Date对象的toString方法, 还是使用SimpleDateFormatformat方法去格式化Date对象,或者使用parse解析字符串成Date对象都会涉及到时区, 也就是说Date对象没有时区概念, 但是格式化Date对象, 或者解析字符串成Date对象时, 是有时区概念的。

public class TestDate {
    public static void main(String[] args) {
        System.out.println(new Date().toString());
    }
}

Thu Nov 16 10:11:51 CST 2023
public class TestDate {
    public static void main(String[] args) {
        Date date = new Date();
        System.out.println(date);
        // modify default timezone
        TimeZone.setDefault(TimeZone.getTimeZone("GMT-08:00"));
        System.out.println(date);
    }
}

Thu Nov 16 10:41:19 CST 2023
Wed Nov 15 18:41:19 GMT-08:00 2023
public class TestDate {
    public static void main(String[] args) {
        Date date = new Date();
       
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(dateFormat.format(date));

        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT+1:00"));
        System.out.println(dateFormat.format(date));
        
        //2023-11-16 10:43:51
        //2023-11-16 03:43:51
    }
}

解析字符串成Date对象, 涉及时区将同一个时间字符串按照不同的时区来解析, 得到的Date对象值不一样很好理解: 东八区8点当然和0时区8点不一样。

public class TestDate {
    public static void main(String[] args) throws ParseException {
        String dateStr = "2019-12-10 08:00:00";

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date1 = dateFormat.parse(dateStr);
        System.out.println(date1.getTime());


        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT+1:00"));
        Date date2 = dateFormat.parse(dateStr);
        System.out.println(date2.getTime());

 // 输出
//        1575936000000
//        1575961200000

    }
}
  1. Calendar
    Calendar 类是一个抽象类,它为特定瞬间与 YEAR、MONTH、DAY_OF—MONTH、HOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段(如获得下星期的日期) 提供了一些方法。

Calendar类只能通过静态方法获取实例

    /**
     * Gets a calendar using the default time zone and locale. The
     * {@code Calendar} returned is based on the current time
     * in the default time zone with the default
     * {@link Locale.Category#FORMAT FORMAT} locale.
     * <p>
     * If the locale contains the time zone with "tz"
     * <a href="Locale.html#def_locale_extension">Unicode extension</a>,
     * that time zone is used instead.
     *
     * @return a Calendar.
     */
    public static Calendar getInstance()
    {
        Locale aLocale = Locale.getDefault(Locale.Category.FORMAT);
        return createCalendar(defaultTimeZone(aLocale), aLocale);
    }

    /**
     * Gets a calendar using the specified time zone and default locale.
     * The {@code Calendar} returned is based on the current time
     * in the given time zone with the default
     * {@link Locale.Category#FORMAT FORMAT} locale.
     *
     * @param zone the time zone to use
     * @return a Calendar.
     */
    public static Calendar getInstance(TimeZone zone)
    {
        return createCalendar(zone, Locale.getDefault(Locale.Category.FORMAT));
    }

    /**
     * Gets a calendar using the default time zone and specified locale.
     * The {@code Calendar} returned is based on the current time
     * in the default time zone with the given locale.
     * <p>
     * If the locale contains the time zone with "tz"
     * <a href="Locale.html#def_locale_extension">Unicode extension</a>,
     * that time zone is used instead.
     *
     * @param aLocale the locale for the week data
     * @return a Calendar.
     */
    public static Calendar getInstance(Locale aLocale)
    {
        return createCalendar(defaultTimeZone(aLocale), aLocale);
    }

    /**
     * Gets a calendar with the specified time zone and locale.
     * The {@code Calendar} returned is based on the current time
     * in the given time zone with the given locale.
     *
     * @param zone the time zone to use
     * @param aLocale the locale for the week data
     * @return a Calendar.
     */
    public static Calendar getInstance(TimeZone zone,
                                       Locale aLocale)
    {
        return createCalendar(zone, aLocale);
    }

Calendar对象可以调用set方法定位到任何一个时间。调用get方法获得时间点的所有信息。简单使用如下:

public class Main {
    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();// get default time zone time
        printTimeInfo(calendar);

        // add on year. All Field can be added. amount can be minus
        calendar.add(Calendar.YEAR, 1);
        printTimeInfo(calendar);

        // UTC-08:00
        Calendar calendar1 = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));
        printTimeInfo(calendar1);
    }


    public static void printTimeInfo(Calendar calendar) {
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int min = calendar.get(Calendar.MINUTE);
        int sec = calendar.get(Calendar.SECOND);
        String format = "TimeZone: %s, %d-%d-%d, %d:%d:%d";
        System.out.println(String.format(format, calendar.getTimeZone().getID(), year, month + 1, day, hour, min, sec));
    }
}

TimeZone: Asia/Shanghai, 2023-11-16, 11:15:4
TimeZone: Asia/Shanghai, 2024-11-16, 11:15:4
TimeZone: America/Los_Angeles, 2023-11-15, 19:15:4

5.1 计算同一时间戳在不同时区下的时间点

    public static void main(String[] args) {
        long timeStamp = 1700104961;
        // UTC+08:00
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Asia/Shanghai"));
        calendar.setTimeInMillis(timeStamp * 1000);
        printTimeInfo(calendar);
        // UTC-08:00
        Calendar calendar1 = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));
        calendar1.setTimeInMillis(timeStamp * 1000);
        printTimeInfo(calendar1);
    }
TimeZone: Asia/Shanghai, 2023-11-16, 11:22:41
TimeZone: America/Los_Angeles, 2023-11-15, 19:22:41

5.2 计算同一时间点在不同时区下对应的时间戳

如2023-10-18 9:25:30在不同时区下对应的时间戳。

    public static void main(String[] args) throws ParseException {
        String dateStr = "2023-10-18 9:25:30";

        // get the timeStamp at Asia/Shanghai
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        Date date1 = dateFormat.parse(dateStr);
        System.out.println(date1.getTime());


        //get the timeStamp at America/Los_Angeles
        dateFormat.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
        Date date2 = dateFormat.parse(dateStr);
        System.out.println(date2.getTime());
    }
1697592330000
1697646330000

5.3 知道一个时区某个时间点的时间戳,计算另一时区该时间点的时间戳

如:知道1697592330000是"2023-10-18 9:25:30"在Asia/Shanghai下的时间戳,计算在America/Los_Angeles下"2023-10-18 9:25:30"对应的时间戳。

第一种方法:使用5.1计算,第二种方法使用相对国际标准时间的偏移量计算。假设时区A相对国际标准时间的偏移量为offsetA, 时区B偏移量为offsetB。那么B时区"2023-10-18 9:25:30"对应的时间戳为timeStampA + offsetA - offsetB - MILLSAHOURS

    public static void main(String[] args) throws ParseException {
        String dateStr = "2023-10-18 9:25:30";
        long MILLS_ONE_HOUR = 60 * 60 * 1000;

        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Asia/Shanghai"));
        calendar.set(2023, Calendar.OCTOBER, 18, 9, 25, 30);
        System.out.println(calendar.getTimeInMillis());
        printTimeInfo(calendar);

        System.out.println(
                calendar.getTimeInMillis()
                        + TimeZone.getTimeZone("Asia/Shanghai").getRawOffset()
                        - TimeZone.getTimeZone("America/Los_Angeles").getRawOffset() - MILLS_ONE_HOUR
        );
        calendar.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
        calendar.set(2023, Calendar.OCTOBER, 18, 9, 25, 30);
        System.out.println(calendar.getTimeInMillis());
        printTimeInfo(calendar);
    }
1697592330668
TimeZone: Asia/Shanghai, 2023-10-18, 9:25:30
1697646330668
1697646330668
TimeZone: America/Los_Angeles, 2023-10-18, 9:25:30

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

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

相关文章

单词故事嵌入:通过自然语言处理解开叙事

一、介绍 在自然语言处理和文本分析领域&#xff0c;寻求理解和表示人类叙事丰富而复杂的结构是一个持续的挑战。在研究人员和数据科学家可以使用的众多工具和技术中&#xff0c;“Word Story Embeddings”作为一种创新且有前景的方法脱颖而出。这些嵌入建立在词嵌入的基础上&a…

深度学习OCR中文识别 - opencv python 计算机竞赛

文章目录 0 前言1 课题背景2 实现效果3 文本区域检测网络-CTPN4 文本识别网络-CRNN5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习OCR中文识别系统 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;…

Jmeter- Beanshell语法和常用内置对象(网络整理)

在利用jmeter进行接口测试或者性能测试的时候&#xff0c;我们需要处理一些复杂的请求&#xff0c;此时就需要利用beanshell脚本了&#xff0c;BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法&#xff0c;所以它和java是可以无缝衔接的。beans…

入职算法工程师后敲的非常有趣使用的小工具

NOTE&#xff1a;代码仅用来参考&#xff0c;没时间解释啦&#xff01; &#x1f349;一、自动从数据库从抽取数据。 在某台服务器中&#xff0c;从存放数据集的数据库自动抽取标注好的数据标签&#xff0c;这一步操作有什么用呢&#xff1f;当我们发现我们数据不均衡的时候&a…

OpenSign:安全可靠的电子签名解决方案 | 开源日报 No.76

microsoft/Web-Dev-For-Beginners Stars: 71.5k License: MIT 这个开源项目是一个为期 12 周的全面课程&#xff0c;由微软云倡导者团队提供。它旨在帮助初学者掌握 JavaScript、CSS 和 HTML 的基础知识。每一节都包括预习和复习测验、详细的书面指南、解决方案、作业等内容。…

中小企业如何最大程度地利用CRM系统的潜力?

在当今竞争激烈的商业世界中&#xff0c;客户关系管理&#xff08;CRM&#xff09;数字化转型已经成为大企业成功的重要秘诀。大型跨国公司如亚马逊、苹果和微软等已经在CRM数字化方面走在了前列&#xff0c;实现了高度个性化的客户体验&#xff0c;加强了客户忠诚度。 然而&a…

UI自动化测试框架的搭建(详解)

前言 今天给大家分享一个seleniumtestngmavenant的UI自动化&#xff0c;可以用于功能测试&#xff0c;也可按复杂的业务流程编写测试用例&#xff0c;今天此篇文章不过多讲解如何实现CI/CD&#xff0c;只讲解自己能独立搭建UI框架&#xff0c;需要阅读者有一定的java语言基础&…

FPGA实现Avalon-MM接口通信

在Avalon总线协议&#xff08;一&#xff09;和Avalon总线协议&#xff08;二&#xff09;中大概了解Avalon总线的几种类型&#xff0c;目前比较常用到的就是Avalon-MM接口了&#xff0c;虽然在概念中有那么多的属性&#xff0c;但是具体使用起来还是非常简单的。 一、Avalon-…

《QT从基础到进阶·三十二》Q指针和D指针用法

二进制兼容&#xff1a; 如果程序从一个以前版本的库动态链接到新版本的库之后&#xff0c;能够继续正常运行&#xff0c;而不需要重新编译&#xff0c;那么我们就说这个库是二进制兼容的。&#xff08;通常只要dll的头文件总字节数不变基本满足二进制兼容&#xff0c;pimpl设计…

前端js面试题 (四)

文章目录 ES6新增的proxy手写&#xff0c;proxy访问某对象输出别的数字深度拷贝&#xff0c;为啥无法使用JSON.parse(JSON.stringify(obj))异步编程有哪些&#xff0c;async await来由&#xff0c;本质原理是什么事件队列输出题第一题第二题第三题 粘性布局的原理&#xff0c;以…

2023 年 数维杯(D题)国际大学生数学建模挑战赛 |数学建模完整代码+建模过程全解全析

大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 让我们来看看数维杯D题&#xff01; 问题一&#xff1a;最佳清…

软件外包开发设计文档的编写

编写软件设计文档是软件开发过程中至关重要的一步&#xff0c;下面是一些在编写软件设计文档时需要注意的问题&#xff0c;通过注意这些问题&#xff0c;可以确保软件设计文档是清晰、完整且易于理解的&#xff0c;为整个开发团队提供有力的指导。北京木奇移动技术有限公司&…

candence出现no connect property onpin,,,,错误,该怎么办?

原因是上面有引脚添加了 属性no connect&#xff0c;但依然连接了网络&#xff0c;这个时候需要把线剪切&#xff0c;然后看到引脚上有个X, 解决方法&#xff1a; 工具栏&#xff02;place >no connect "X 再连上线&#xff0c;再生成网标的时候&#xff0c; 就不报错了…

【实施】Sentry-self-hosted部署

Sentry-self-hosted部署 介绍 Sentry 是一个开源的错误追踪&#xff08;error tracking&#xff09;平台。它主要用于监控和追踪应用程序中的错误、异常和崩溃。Sentry允许开发人员实时地收集和分析错误&#xff0c;并提供了强大的工具来排查和修复问题&#xff0c;研发最近是…

MCTS蒙特卡洛树搜索(The Monte Carlo Tree Search)

1、简介 蒙特卡罗树搜索是一类树搜索算法的统称&#xff0c;简称MCTS。它是一种用于某些决策过程的启发式搜索算法&#xff0c;且在搜索空间巨大的游戏中会比较有效。从全局来看&#xff0c;蒙特卡洛树搜索的主要目标是&#xff1a;给定一个游戏状态来选择最佳的下一步。等常见…

AD教程 (十六)常用PCB封装的直接调用

AD教程 &#xff08;十六&#xff09;常用PCB封装的直接调用 打开已经做好的PCB文件 点击设计&#xff0c;生成PCB库&#xff0c;会自动把PCB里所用到的所有封装&#xff0c;全部自动生成 CtrlA 将所有元器件的封装全部选中&#xff08;或者只选中所需要的&#xff09;&#x…

Java相关编程思想

少用继承多用“组合”——在现有类的基础上组织一个新类。 2.继承要用“is”来检验&#xff0c;如果继承者is被继承者&#xff0c;说明这是一个比较好的继承。 3.向上造型&#xff0c;把实现方法留给继承者去实现。&#xff08;动态绑定&#xff09; 4.把接口理解为抽象类的进一…

windows安装gdal库

提示&#xff1a;在windows上使用pip在cmd终端安装gdal 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 原因是由于丹丹安装使用pip安装gdal时报错Microsoft visual C 1…

编码器脉冲信号测量2路DI高速计数器PNP/NPN转RS-485数据采集模块 解码转换成标准Modbus RTU协议 YL150-485

特点&#xff1a; ● 编码器解码转换成标准Modbus RTU协议 ● 可用作编码器计数器或者转速测量 ● 支持编码器计数&#xff0c;可识别正反转 ● 也可以设置作为2路独立DI高速计数器 ● 计数值支持断电自动保存 ● DI输入支持PNP和NPN输入 ● 继电器和机械开关输入时可以…

几个测试接口的好工具,效率加倍~

作为一名后端程序员&#xff0c;一定要对自己写的接口负责&#xff0c;保证接口的正确和稳定性。因此&#xff0c;接口测试也是后端开发中的关键环节。 但我相信&#xff0c;很多朋友是懒得测试接口的&#xff0c;觉得这很麻烦。一般自己写的接口自己都不调用&#xff0c;而是…