Java使用Joda-Time处理日期和时间

2024-04-25 18:58

本文主要是介绍Java使用Joda-Time处理日期和时间,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Java使用Joda-Time处理日期和时间

  • 1. Maven配置
  • 2. Joda-Time微架构
  • 3. 初识 org.joda.time.DateTime
  • 4. 创建Joda-Time
    • 4.1 获取当前系统时间
    • 4.2 通过给定的毫秒值创建
    • 4.3 通过给定的对象创建
    • 4.4 通过指定字段值创建
  • 5. Joda-Time日期操作
  • 6. Joda-Time日期格式化
  • 7. 一些源码
    • 7.1 计算指定年的毫秒数的方法
    • 7.2 将UTC毫秒数切换成本地时区对应的毫秒数
  • 8. 功能示例
    • 8.1 获取本周的开始日期和结束日期
    • 8.2 获取当前日期的所属周
    • 8.3 日期格式化和解析
  • 参考

1. Maven配置

<dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>2.10</version>
</dependency>

2. Joda-Time微架构

在这里插入图片描述

3. 初识 org.joda.time.DateTime

通过org.joda.time.DateTime的类图我们可以看到,其核心的Field主要是iMillis和iChronology。DateTime的核心是UTC 1970年1月1日以来的毫秒值 iMillis,而所有对日期的操作通过 年表 iChronology 来实现。从根本上讲,年表是一种日历系统 — 一种计算时间的特殊方式 — 并且是一种在其中执行日历算法的框架。

org.joda.time.base.BaseDateTime

    /** The millis from 1970-01-01T00:00:00Z */private volatile long iMillis;/** The chronology to use */private volatile Chronology iChronology;

目前Joda-Time提供8种日历系统:

  • Buddhist
  • Coptic
  • Ethiopic
  • Gregorian-Julian cutover
  • Gregorian
  • Islamic
  • ISO(Default)- ISO8601
  • Julian

图1 org.joda.time.DateTime的类图
org.joda.time.DateTime的类图
图2 年表核心类图

org.joda.time.chrono.AssembledChronology

Abstract Chronology that enables chronologies to be assembled from a container of fields.

org.joda.time.chrono.ZonedChronology

Wraps another Chronology to add support for time zones.

org.joda.time.chrono.ZonedChronology.ZonedDateTimeField

A DateTimeField that decorates another to add timezone behaviour.

org.joda.time.chrono.ISOChronology

Implements a chronology that follows the rules of the ISO8601 standard, which is compatible with Gregorian for all modern dates.

org.joda.time.chrono.GregorianChronology

Implements a pure proleptic Gregorian calendar system, which defines every fourth year as leap, unless the year is divisible by 100 and not by 400. This improves upon the Julian calendar leap year rule.

在这里插入图片描述

4. 创建Joda-Time

4.1 获取当前系统时间

其核心是通过 java.lang.System#currentTimeMillis 获取系统当前毫秒值。相关构造方法:

  • org.joda.time.DateTime#DateTime()
  • org.joda.time.DateTime#DateTime(org.joda.time.DateTimeZone)
  • org.joda.time.DateTime#DateTime(org.joda.time.Chronology)

4.2 通过给定的毫秒值创建

相关构造方法:

  • org.joda.time.DateTime#DateTime(long)
  • org.joda.time.DateTime#DateTime(long, org.joda.time.DateTimeZone)
  • org.joda.time.DateTime#DateTime(long, org.joda.time.Chronology)

4.3 通过给定的对象创建

解析给定对象,并转换成Joda-Time对象。支持的对象包括java.util.Calendar, java.lang.Long, java.lang.String, java.util.Date, org.joda.time.ReadableInstant等。其中转换通过对象转换器实现,公共接口为org.joda.time.convert.InstantConverter

  • org.joda.time.DateTime#DateTime(java.lang.Object)
  • org.joda.time.DateTime#DateTime(java.lang.Object, org.joda.time.DateTimeZone)
  • org.joda.time.DateTime#DateTime(java.lang.Object, org.joda.time.Chronology)

4.4 通过指定字段值创建

通过制定年、月、日、时、分、秒、毫秒值创建对象。

  • org.joda.time.DateTime#DateTime(int, int, int, int, int, int, int)
  • org.joda.time.DateTime#DateTime(int, int, int, int, int, int, int, org.joda.time.DateTimeZone)
  • org.joda.time.DateTime#DateTime(int, int, int, int, int, int, int, org.joda.time.Chronology)

5. Joda-Time日期操作

Joda-Time对日期的操作是通过org.joda.time.DateTime.Property来实现的,Property将DateTime与日历系统的org.joda.time.DateTimeField进行绑定,并最终通过DateTimeField的操作来实现对日期的操作。

以下摘录自org.joda.time.DateTime.Property的JavaDoc。

DateTime.Property binds a DateTime to a DateTimeField allowing powerful datetime functionality to be easily accessed.
The simplest use of this class is as an alternative get method, here used to get the year ‘1972’ (as an int) and the month ‘December’ (as a String).
DateTime dt = new DateTime(1972, 12, 3, 0, 0, 0, 0);
int year = dt.year().get();
String monthStr = dt.month().getAsText();

Methods are also provided that allow date modification. These return new instances of DateTime - they do not modify the original.
The example below yields two independent immutable date objects 20 years apart.
DateTime dt = new DateTime(1972, 12, 3, 0, 0, 0, 0);
DateTime dt20 = dt.year().addToCopy(20);

Serious modification of dates (ie. more than just changing one or two fields) should use the MutableDateTime class.
DateTime.Propery itself is thread-safe and immutable, as well as the DateTime being operated on.

6. Joda-Time日期格式化

根据格式化pattern创建org.joda.time.format.DateTimeFormatter
根据时区调整Joda-Time(变更毫秒值)
调用日历系统获取各字段值,构建格式化日期串

org.joda.time.format.DateTimeFormatterBuilder.Composite#printTo(java.lang.Appendable, long, org.joda.time.Chronology, int, org.joda.time.DateTimeZone, java.util.Locale)

		public void printTo(Appendable appendable, long instant, Chronology chrono,int displayOffset, DateTimeZone displayZone, Locale locale) throws IOException {InternalPrinter[] elements = iPrinters;if (elements == null) {throw new UnsupportedOperationException();}if (locale == null) {// Guard against default locale changing concurrently.locale = Locale.getDefault();}int len = elements.length;for (int i = 0; i < len; i++) {elements[i].printTo(appendable, instant, chrono, displayOffset, displayZone, locale);}}

7. 一些源码

7.1 计算指定年的毫秒数的方法

org.joda.time.chrono.GregorianChronology#calculateFirstDayOfYearMillis

	long calculateFirstDayOfYearMillis(int year) {// Initial value is just temporary.int leapYears = year / 100;if (year < 0) {// Add 3 before shifting right since /4 and >>2 behave differently// on negative numbers. When the expression is written as// (year / 4) - (year / 100) + (year / 400),// it works for both positive and negative values, except this optimization// eliminates two divisions.leapYears = ((year + 3) >> 2) - leapYears + ((leapYears + 3) >> 2) - 1;} else {leapYears = (year >> 2) - leapYears + (leapYears >> 2);if (isLeapYear(year)) {leapYears--;}}return (year * 365L + (leapYears - DAYS_0000_TO_1970)) * DateTimeConstants.MILLIS_PER_DAY;}

7.2 将UTC毫秒数切换成本地时区对应的毫秒数

org.joda.time.DateTimeZone#convertUTCToLocal

/*** Converts a standard UTC instant to a local instant with the same* local time. This conversion is used before performing a calculation* so that the calculation can be done using a simple local zone.** @param instantUTC  the UTC instant to convert to local* @return the local instant with the same local time* @throws ArithmeticException if the result overflows a long* @since 1.5*/public long convertUTCToLocal(long instantUTC) {int offset = getOffset(instantUTC);long instantLocal = instantUTC + offset;// If there is a sign change, but the two values have the same sign...if ((instantUTC ^ instantLocal) < 0 && (instantUTC ^ offset) >= 0) {throw new ArithmeticException("Adding time zone offset caused overflow");}return instantLocal;}

8. 功能示例

8.1 获取本周的开始日期和结束日期

	@Testpublic void week() {// 获取当前日期DateTime dateTime = new DateTime();String pattern = "yyyy-MM-dd HH:mm:ss";// 本周开始时间 00:00:00String monday = dateTime.dayOfWeek().withMinimumValue().withTimeAtStartOfDay().toString(pattern);// 本周结束时间 23:59:59String sunday = dateTime.dayOfWeek().withMaximumValue().millisOfDay().withMaximumValue().toString(pattern);System.out.println(monday);System.out.println(sunday);}

8.2 获取当前日期的所属周

	@Testpublic void getWeek() {// 创建DateTimeDateTime dateTime = new DateTime(2018, 12, 31, 0, 0, 0);// 获取年int weekyear = dateTime.getWeekyear();// 获取周int weekOfWeekyear = dateTime.getWeekOfWeekyear();// 结果:1System.out.println(weekyear);// 结果:2019System.out.println(weekOfWeekyear);}

8.3 日期格式化和解析

    @Testpublic void format() {// toStringString date = new DateTime().toString("yyyy-MM-dd");System.out.println(date);}@Testpublic void parse() {// create formatterDateTimeFormatter formater = DateTimeFormat.forPattern("yyyy-MM-dd");// parse date stringDateTime dateTime = formater.parseDateTime("2019-04-25");// 2019-04-25T00:00:00.000+08:00System.out.println(dateTime);}

参考

Joda-Time 简介
Calendar systems
joda-time

这篇关于Java使用Joda-Time处理日期和时间的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/935516

相关文章

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

使用Python构建一个Hexo博客发布工具

《使用Python构建一个Hexo博客发布工具》虽然Hexo的命令行工具非常强大,但对于日常的博客撰写和发布过程,我总觉得缺少一个直观的图形界面来简化操作,下面我们就来看看如何使用Python构建一个... 目录引言Hexo博客系统简介设计需求技术选择代码实现主框架界面设计核心功能实现1. 发布文章2. 加

在Spring Boot中浅尝内存泄漏的实战记录

《在SpringBoot中浅尝内存泄漏的实战记录》本文给大家分享在SpringBoot中浅尝内存泄漏的实战记录,结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录使用静态集合持有对象引用,阻止GC回收关键点:可执行代码:验证:1,运行程序(启动时添加JVM参数限制堆大小):2,访问 htt

SpringBoot集成Milvus实现数据增删改查功能

《SpringBoot集成Milvus实现数据增删改查功能》milvus支持的语言比较多,支持python,Java,Go,node等开发语言,本文主要介绍如何使用Java语言,采用springboo... 目录1、Milvus基本概念2、添加maven依赖3、配置yml文件4、创建MilvusClient

浅析Java中如何优雅地处理null值

《浅析Java中如何优雅地处理null值》这篇文章主要为大家详细介绍了如何结合Lambda表达式和Optional,让Java更优雅地处理null值,感兴趣的小伙伴可以跟随小编一起学习一下... 目录场景 1:不为 null 则执行场景 2:不为 null 则返回,为 null 则返回特定值或抛出异常场景

SpringMVC获取请求参数的方法

《SpringMVC获取请求参数的方法》:本文主要介绍SpringMVC获取请求参数的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下... 目录1、通过ServletAPI获取2、通过控制器方法的形参获取请求参数3、@RequestParam4、@

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

使用Python开发一个带EPUB转换功能的Markdown编辑器

《使用Python开发一个带EPUB转换功能的Markdown编辑器》Markdown因其简单易用和强大的格式支持,成为了写作者、开发者及内容创作者的首选格式,本文将通过Python开发一个Markd... 目录应用概览代码结构与核心组件1. 初始化与布局 (__init__)2. 工具栏 (setup_t

SpringBoot应用中出现的Full GC问题的场景与解决

《SpringBoot应用中出现的FullGC问题的场景与解决》这篇文章主要为大家详细介绍了SpringBoot应用中出现的FullGC问题的场景与解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录Full GC的原理与触发条件原理触发条件对Spring Boot应用的影响示例代码优化建议结论F

深入理解Apache Kafka(分布式流处理平台)

《深入理解ApacheKafka(分布式流处理平台)》ApacheKafka作为现代分布式系统中的核心中间件,为构建高吞吐量、低延迟的数据管道提供了强大支持,本文将深入探讨Kafka的核心概念、架构... 目录引言一、Apache Kafka概述1.1 什么是Kafka?1.2 Kafka的核心概念二、Ka