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

相关文章

Java计算经纬度距离的示例代码

《Java计算经纬度距离的示例代码》在Java中计算两个经纬度之间的距离,可以使用多种方法(代码示例均返回米为单位),文中整理了常用的5种方法,感兴趣的小伙伴可以了解一下... 目录1. Haversine公式(中等精度,推荐通用场景)2. 球面余弦定理(简单但精度较低)3. Vincenty公式(高精度,

使用Java将实体类转换为JSON并输出到控制台的完整过程

《使用Java将实体类转换为JSON并输出到控制台的完整过程》在软件开发的过程中,Java是一种广泛使用的编程语言,而在众多应用中,数据的传输和存储经常需要使用JSON格式,用Java将实体类转换为J... 在软件开发的过程中,Java是一种广泛使用的编程语言,而在众多应用中,数据的传输和存储经常需要使用j

Java实现视频格式转换的完整指南

《Java实现视频格式转换的完整指南》在Java中实现视频格式的转换,通常需要借助第三方工具或库,因为视频的编解码操作复杂且性能需求较高,以下是实现视频格式转换的常用方法和步骤,需要的朋友可以参考下... 目录核心思路方法一:通过调用 FFmpeg 命令步骤示例代码说明优点方法二:使用 Jaffree(FF

Java实现图片淡入淡出效果

《Java实现图片淡入淡出效果》在现代图形用户界面和游戏开发中,**图片淡入淡出(FadeIn/Out)**是一种常见且实用的视觉过渡效果,它可以用于启动画面、场景切换、轮播图、提示框弹出等场景,通过... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细

Java如何用乘号来重复字符串的功能

《Java如何用乘号来重复字符串的功能》:本文主要介绍Java使用乘号来重复字符串的功能,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java乘号来重复字符串的功能1、利用循环2、使用StringBuilder3、采用 Java 11 引入的String.rep

Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例

《Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例》本文介绍Nginx+Keepalived实现Web集群高可用负载均衡的部署与测试,涵盖架构设计、环境配置、健康检查、... 目录前言一、架构设计二、环境准备三、案例部署配置 前端 Keepalived配置 前端 Nginx

Python logging模块使用示例详解

《Pythonlogging模块使用示例详解》Python的logging模块是一个灵活且强大的日志记录工具,广泛应用于应用程序的调试、运行监控和问题排查,下面给大家介绍Pythonlogging模... 目录一、为什么使用 logging 模块?二、核心组件三、日志级别四、基本使用步骤五、快速配置(bas

Python日期和时间完全指南与实战

《Python日期和时间完全指南与实战》在软件开发领域,‌日期时间处理‌是贯穿系统设计全生命周期的重要基础能力,本文将深入解析Python日期时间的‌七大核心模块‌,通过‌企业级代码案例‌揭示最佳实践... 目录一、背景与核心价值二、核心模块详解与实战2.1 datetime模块四剑客2.2 时区处理黄金法

SpringBoot中HTTP连接池的配置与优化

《SpringBoot中HTTP连接池的配置与优化》这篇文章主要为大家详细介绍了SpringBoot中HTTP连接池的配置与优化的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、HTTP连接池的核心价值二、Spring Boot集成方案方案1:Apache HttpCl

使用animation.css库快速实现CSS3旋转动画效果

《使用animation.css库快速实现CSS3旋转动画效果》随着Web技术的不断发展,动画效果已经成为了网页设计中不可或缺的一部分,本文将深入探讨animation.css的工作原理,如何使用以及... 目录1. css3动画技术简介2. animation.css库介绍2.1 animation.cs