为啥在编程的世界里,日期时间处理这么难?

这篇具有很好参考价值的文章主要介绍了为啥在编程的世界里,日期时间处理这么难?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

做过开发的同学都有体会,日期时间的处理很麻烦,稍不注意就会出现日期格式不一样,或者时间差8小时。

那为何日期时间这么难处理呢?今天我们就来梳理一下在编程的世界里,为啥日期时间这么难处理。

我们先来熟悉几个概念
1、时区(Timezone)

由于各地的日出日落时间不同,所以把全球所有地区共分为24个时区,每个时区跨越360/24=15个经度,比如伦敦位于北京的西面,那么当北京的太阳已经升起的时候,伦敦还要再过 8 小时才能迎来黎明。也就是说,伦敦比北京晚 8 小时。而东京位于北京的东面,所以东京的日出比北京早 1 小时。

一定有人听过中国的时区是东八区,那这个东八区到底是啥意思呢?

以本初子午线(即0度经线,也称格林尼治子午线)为基准,向东每跨越15度经度就增加一个时区,向西则相应减去一个时区

中国位于东经约73度至135度之间,理论上跨越了五个时区,即东五区至东九区。然而,为了便于全国范围内的行政管理、交通调度、通信交流以及社会生活的统一协调,中国选择了东经120度所在的东八区作为全国统一的标准时间,即“北京时间”

如果我们想知道当北京是中午 12:00 的时候,东京是什么时间,可以先用 12:00 减去当前时区 +08:00,换算成伦敦时间 04:00,再加上目标时区 +09:00,就得到了东京时间 13:00

2、格林威治时间(Greenwich Mean Time, GMT)

GMT是基于英国伦敦格林尼治天文台所在经线(本初子午线)的地方时。作为曾经的世界标准时间,它不考虑夏令时(DST)调整。现在通常用作UTC(协调世界时)的同义词,尽管在实际应用中可能仍有细微差别

3、协调世界时(Coordinated Universal Time, UTC)

UTC又称世界统一时间、世界标准时间、国际协调时间。是当前国际通用的时间标准,它基于原子钟的测量结果,与GMT基本相同,但在需要插入闰秒以保持与地球自转的长期同步时,两者会有所区别。UTC时间通常以“UTC”后跟时分秒表示,如“2024-04-26T12:30:00Z”

4、夏令时(Daylight Saving Time, DST)

一到夏天,白天就变得很长,特别是高纬度地区会更明显,到了北极或南极,太阳整天都不会落下去,这就是极昼。为了充分利用大自然的馈赠,有些地方会实行夏令时,也就是说到了夏天,就人为把表拨快一个小时,让人们早点起床、早点睡觉,这样可以节省一些照明的电费。中国曾经短暂实行过几年夏令时,不过后来认为它带来的负面影响超过收益,就取消了。但是世界上仍然有很多地方实施夏令时,当设计全球化应用的时候,必须得考虑它

5、CST

CST这个缩写它可以同时代表四个不同的时间:

  • China Standard Time ── 中国标准时间(UTC+8)
  • Central Standard Time (USA) ── 美国中央时区(UTC-6)
  • Central Standard Time (Australia) ── 澳大利亚中央时区 (UTC+9)
  • Cuba Standard Time UTC-4:00 ── 古巴标准时区(UTC-4)

因此,使用CST时需注意其具体指代哪个时区,以免产生混淆

6、ISO 8601

这是一个国际标准化组织(International Organization for Standardization, ISO)制定的日期和时间表示法。ISO 8601提供了一种清晰、无歧义的日期和时间格式,如“YYYY-MM-DD”表示日期,“HH:MM:SS”表示时间,两者结合为“YYYY-MM-DDTHH:MM:SS”(如“2024-04-26T12:30:00”)。该标准还支持时区表示,如“2024-04-26T12:30:00+01:00”表示在UTC基础上加1小时的时区时间

7、时间戳(Timestamp)

时间戳是一种精确记录某一事件发生时刻的方法,通常是一个从特定起点(如Unix时间戳的起点是1970年1月1日0时0分0秒(UTC))开始计数的整数或浮点数,单位通常是秒或毫秒。例如,Unix时间戳“1678882200”表示距离该起点的秒数。时间戳常用于计算机系统中记录事件发生的精确时间点,便于比较和排序

8、网络时间协议(Network Time Protocol,NTP)

NTP是一种网络协议,用于在分布式系统中同步各个设备的时钟,以确保所有参与通信的节点拥有高度一致的时间。NTP通过在客户端与NTP服务器之间交换时间戳信息,通过复杂的算法计算时钟偏差和网络延迟,从而调整客户端系统的时钟以接近服务器提供的准确时间。NTP对于确保网络应用中的事务完整性、日志记录准确性、分布式系统协作等具有重要意义

9、本地时间

本地时间是指某个特定地点当前所采用的时间,包括了时区偏移和可能的夏令时调整。例如,“北京时间”对应东八区时间,表示为“UTC+08:00”。本地时间通常用于日常生活和商业活动,如“2024年4月26日 10:30 AM(北京)”

怎么样?是不是看了上面的梳理,感觉有些头大,这还没有算上中国的农历、还有比如康熙、乾隆多少年,都可以表示日期和时间。

那这么多时间格式,你在做项目的时候不可能全部会用到,一般如果不涉及到国际业务,可以使用本地时间来简单化处理。

可以只用存储时间戳,不存储时区信息,这样可以依赖系统自带的时区来简单处理日期时间

Java中是如何处理日期时间的

在Java 8以前,日期和时间的处理主要依赖于java.util.Datejava.util.Calendar这两个类

java.util.Date 类

java.util.Date类实际上包含了日期和时间,但它的toString()方法默认输出的是带有当前时区的时间,而getYear(), getMonth(), getDate()等方法已经过时,并且月份是从0开始计数的(1表示二月,依此类推)

import java.util.Date;

public class OldDateExample {
    public static void main(String[] args) {
        // 获取当前日期和时间
        Date currentDate = new Date();

        // 打印当前日期和时间
        System.out.println("Current date and time (in default format): " + currentDate);

        // 转换为自定义格式,需要用到SimpleDateFormat类
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = sdf.format(currentDate);
        System.out.println("Current date and time (formatted): " + formattedDate);
        
        // 设置一个新的日期(此方式已过时,但仍可用于演示)
        Calendar cal = Calendar.getInstance();
        cal.set(2000, Calendar.JANUARY, 1, 0, 0, 0); // 注意月份是Calendar.JANUARY而不是1
        Date specificDate = cal.getTime();
        System.out.println("Specific date (old style): " + sdf.format(specificDate));
    }
}

java.util.Calendar 类

java.util.Calendar 类是用来处理日期和时间字段以及完成日期时间字段运算的抽象类,它为特定的日历系统提供了方法,如获取和设置日期字段,计算与日期相关的值等。但它不是线程安全的,并且API使用繁琐

import java.util.Calendar;
import java.text.SimpleDateFormat;

public class OldCalendarExample {
    public static void main(String[] args) {
        // 创建一个Calendar实例
        Calendar calendar = Calendar.getInstance();

        // 设置日期为2000年1月1日
        calendar.set(Calendar.YEAR, 2000);
        calendar.set(Calendar.MONTH, Calendar.JANUARY); // 注意月份需要减1,因为它是从0开始计数的
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        // 获取Date对象
        Date specificDate = calendar.getTime();

        // 将Date对象格式化为字符串
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = sdf.format(specificDate);

        System.out.println("Specific date using Calendar: " + formattedDate);
    }
}

这些类在设计和使用上存在一些不足,比如构造函数隐含了当前时区,日期时间的表示不够直观,而且API使用起来相对复杂

在实际开发中,强烈建议使用Java 8及以上版本的日期时间API,因为它们更简洁、直观且避免了许多老API中存在的陷阱

Java8新版日期时间处理方法

Java 8及以后版本中推荐使用的java.time包下的类来进行日期和时间的操作

  1. 基础日期时间类

    • LocalDate:表示日期,不包含任何时间信息,只关注年、月、日。
    • LocalTime:表示时间,不包含日期,只关注小时、分钟、秒和纳秒。
    • LocalDateTime:结合了日期和时间,依然不包含时区信息,用于表示具体的日期和时间点。
  2. 时区相关类

    • ZonedDateTime:包含日期、时间及时区信息,用于表示具体某一地点的日期和时间。
    • ZoneId:表示时区,替代了旧版的TimeZone类。
  3. 瞬时时间类

    • Instant:表示时间线上某一特定的瞬间,通常对应 Unix 时间戳,内部以 epoch 秒和纳秒表示。
  4. 日期时间格式化与解析

    • DateTimeFormatter:用于日期和时间的格式化和解析,可自定义日期时间字符串的样式

示例代码:

// 创建 LocalDate 和 LocalTime
LocalDate today = LocalDate.now();
LocalTime currentTime = LocalTime.now();

// 创建 LocalDateTime
LocalDateTime now = LocalDateTime.now();

// 创建 ZonedDateTime
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));

// 创建 Instant
Instant currentInstant = Instant.now();

// 格式化和解析日期时间
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedNow = now.format(formatter);
LocalDateTime parsedDateTime = LocalDateTime.parse("2024-04-27 14:30:00", formatter);

// 日期时间操作
LocalDate tomorrow = today.plusDays(1);
LocalTime nextHour = currentTime.plusHours(1);

// 与时区相关的转换
ZonedDateTime utcTime = zdt.withZoneSameInstant(ZoneId.of("Etc/UTC"));

MySQL中日期时间的处理

我们实际开发当中,大部分时候都需要将日期时间写入MySQL数据库中进行持久化,那Java与MySQL之间是如何进行日期时间处理的呢?

在MySQL中处理日期时间,主要通过几种预定义的数据类型来存储和操作日期和时间值

  • DATE:仅存储日期,格式为 'YYYY-MM-DD',范围从'1000-01-01'到'9999-12-31'
  • TIME:仅存储时间,格式为 'HH:MM:SS'
  • DATETIME:存储日期和时间,格式为 'YYYY-MM-DD HH:MM:SS',范围从'1000-01-01 00:00:00.000000'到'9999-12-31 23:59:59.999999'
  • TIMESTAMP:类似于DATETIME,但自动更新到当前时间戳,并且受时区影响。其存储范围与DATETIME相似,但具体行为会根据MySQL的配置有所不同,特别是与服务器时区相关的自动调整

在Java 8及以后版本中,与MySQL的这些日期时间类型相对应,可以使用java.time包下的类

  • DATE 对应 LocalDate:只包含日期部分,无时间信息。
  • TIME 对应 LocalTime:只包含时间部分,无日期信息。
  • DATETIME 可以对应 LocalDateTime:同时包含日期和时间,但不包含时区信息。如果需要时区信息,可以使用 ZonedDateTime 结合具体的时区信息。
  • TIMESTAMP 在Java中通常与 LocalDateTime 或 Instant 相对应,具体取决于应用场景。如果TIMESTAMP用于记录带有时区的绝对时间点,使用 Instant 更合适,因为它也是基于UTC时间的;如果是无时区的日期时间,则使用 LocalDateTime

注意:一般情况下,我们不需要存储时区,因为大部分项目都不涉及到国际化,只在国内开展业务的话,是不需要考虑时区的,依赖本地服务器的时区就可以减化日期时间的处理,但如果你的业务涉及到国际化,就必须考虑时区的问题了。

一般推荐将日期时间转换为UTC时区后存储到数据库,从数据库读取日期时间数据时,根据需要将其转换为应用程序的本地时区或用户指定的时区,以减少时区转换带来的问题。

你的项目中是如何处理日期时间和时区的问题呢?欢迎跟我留言来进行讨论!

本文由博客一文多发平台 OpenWrite 发布!文章来源地址https://www.toymoban.com/news/detail-861154.html

到了这里,关于为啥在编程的世界里,日期时间处理这么难?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java日期时间处理详解

    在Java的世界里,处理日期和时间是常见的任务。尤其在Java 8之前, SimpleDateFormat 是处理日期和时间的主要方式。然而,Java 8引入了新的日期时间API,其中 LocalDateTime 和 DateTimeFormatter 成为了新的选择。本文将探讨这三者的区别,利弊以及它们的具体使用方法。 SimpleDateFormat 是

    2024年02月02日
    浏览(47)
  • 前端常见需求整理 - 日期处理(包含moment、时间戳、日期对象)

    moment对象 使用 UI 框架的时间相关组件时(如 ant-design),默认的绑定值的格式往往为这种。 字符串 部分栗子 对应 YYYY-MM-DD HH:mm:ss 2022-04-12 20:30:00 YYYY/MM/DD HH:mm:ss 2022/04/12 20:30:00 YYYY/MM/DD hh:mm:ss 2022/04/12 08:30:00 YYYY/M/D HH:mm:ss 2022/4/12 20:30:00 YYYY/MM/DD HH:mm 2022/04/12 20:30 日期对象 通过

    2024年02月09日
    浏览(46)
  • R语言 | 日期和时间的处理

    目录 一、日期的设定与使用 1.1 as.Date()函数 1.2 weekdays()函数 1.3 months()函数 1.4 quarters()函数 1.5 Sys.localeconv()函数 1.6 Sys.Date()函数 1.7 再谈seq()函数 1.8 使用不同格式表示日期  二、时间的设定与使用 2.1 Sys.time()函数 2.2 as.POSIXct()函数 2.3 时间也是可以做比较的 2.4  seq()函数与时间

    2024年02月02日
    浏览(37)
  • Python中的时间和日期处理

    在Python开发中,我们经常需要处理日期和时间。Python提供了一些内置模块,如 datetime 、 time 和 calendar ,这些模块让我们能够轻松地获取、操作和格式化日期和时间。本文将介绍如何在Python中使用这些模块进行日期和时间的处理。 在Python中,我们可以使用 datetime 模块的 date

    2024年02月11日
    浏览(40)
  • 52_Pandas处理日期和时间列(字符串转换、日期提取等)

    将解释如何操作表示 pandas.DataFrame 的日期和时间(日期和时间)的列。字符串与 datetime64[ns] 类型的相互转换,将日期和时间提取为数字的方法等。 以下内容进行说明。 如何将 datetime64[ns] 类型指定为索引并将其处理为时序数据以及如何使用,请参考以下文章。 26_Pandas.DataFr

    2024年01月22日
    浏览(50)
  • Python - 字符串转日期时间,格式的处理以及时间加减计算

    1,字符串转日期 运行结果: 注意事项: a, 日期时间转换时,读取的格式要和给定的格式一样,否则会因为无法匹配而报错 【格式1 和 格式2 需要保持一直】 b, 转换之后的日期格式会自动加上\\\'秒\\\'位 2,时间格式处理 根据自己的需求,通过strftime( )函数内的控制符把日期时间格

    2024年02月12日
    浏览(53)
  • Windows bat 批处理 日期时间格式化

    有一个批处理脚本,脚本中根据当前日期,动态的生成日志文件, 如:当前是 2023年06月20日,我希望生成的日志文件名为:XX_20230620.log Windows 在批处理中 获取日期和时间的方式如下: echo %time% 输出的时间格式: HH:MM:SS.NN HH :时 MM :分 SS :秒 NN :厘秒(注意不是毫秒,1秒

    2024年02月11日
    浏览(71)
  • Python处理日期和时间库之arrow使用详解

    日期和时间处理是许多应用程序中的常见任务,但在 Python 中,标准库中的  datetime  模块有时可能会让这些任务变得复杂和繁琐。幸运的是,有一个名为 Arrow 的第三方库,它提供了简化日期和时间处理的功能,使其更加直观和易用。本文将深入探讨 Arrow 库的基本概念、安装

    2024年01月25日
    浏览(39)
  • Python 日期和时间处理教程:datetime 模块的使用

    Python 中的日期不是独立的数据类型,但我们可以导入一个名为 datetime 的模块来使用日期作为日期对象。 示例:导入 datetime 模块并显示当前日期: 当我们执行上面示例中的代码时,结果将是: 日期包含年、月、日、小时、分钟、秒和微秒。datetime 模块有许多方法可以返回有

    2024年02月08日
    浏览(45)
  • 如何在编程中中实现负载均衡和容错处理

    容错是指系统(计算机、网络、云集群等)在其一个或多个组件发生故障时继续运行而不会中断的能力。 创建容错系统的目的是防止由单点故障引起的中断,确保任务关键型应用程序或系统的高可用性和业务连续性。 容错系统使用备份组件自动替换故障组件,确保不会丢失

    2024年02月11日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包