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

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

服务器集群同步时间手记

1.时间服务器配置(必须root用户) (1)检查ntp是否安装 [root@node1 桌面]# rpm -qa|grep ntpntp-4.2.6p5-10.el6.centos.x86_64fontpackages-filesystem-1.41-1.1.el6.noarchntpdate-4.2.6p5-10.el6.centos.x86_64 (2)修改ntp配置文件 [r

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关