joda-Time简述

目录

 

简介

引入Maven依赖

 核心类介绍

日历系统和时区

Interval和Period


简介

Java中处理时间与日期是很常见的操作,jdk中基础的工具类就是我们熟悉的Date和Calendar,然而这些工具类的api使用并不是很方便和强大。于是就诞生了Joda-Time这个专门处理日期时间的库。(JDK1.8的API已经重写了日期库,引入的java.time包,其实也是借鉴了Joda-Time)。

官网:http://joda-time.sourceforge.net/

API:http://joda-time.sourceforge.net/apidocs/index.html

引入Maven依赖

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

 核心类介绍

常用的date-time类
Instant(UN) 时间轴上一个瞬时的点
DateTime(UN) 替换JDK的Calendar类
LocalDate(UN) 本地的日期,而不包含时间部分(没有时区信息)
LocalTime(UN) 本地的时间,而不包含日期部分(没有时区信息)
LocalDateTime(UN) 本地的日期-时间(没有时区信息)

注:UN我用来表示不可变的类,表明了正如Java的String类型一样,其对象是不可变的。即,不论对它进行怎样的改变操作,返回的对象都是新对象。

DateTime实例
DateTime() 无参的构造方法,会创建一个在当前系统所在时区的当前时间,精确到毫秒。

DateTime(int year, int monthOfYear, int dayOfMonth,

int hourOfDay, int minuteOfHour, int secondOfMinute)

方便快速地构造一个指定的时间,这里精确到秒,类似地其它构造方法也可以传入毫秒。
DateTime(long instant) 创建出来的实例,是通过一个long类型的时间戳,它表示这个时间戳距1970-01-01T00:00:00Z的毫秒数。使用默认的时区。
DateTime(Object instant) 通过一个Object对象构造一个实例。这个Object对象可以是这些类型:ReadableInstant, String, Calendar和Date。其中String的格式需要是ISO8601格式。
​

DateTime dateTime = new DateTime();
System.out.println(dateTime); // out: 2016-02-26T16:02:57.582+08:00

DateTime dateTime = new DateTime(2016,2,14,0,0,0);
System.out.println(dateTime); // out: 2016-02-14T00:00:00.000+08:00

DateTime dateTime = new DateTime(1456473917004L);
System.out.println(dateTime); // out: 2016-02-26T16:05:17.004+08:00

DateTime dateTime= new DateTime(new Date());
System.out.println(dateTime); // out: 2016-02-26T16:07:59.970+08:00

DateTime dateTime = new DateTime("2016-02-15T00:00:00.000+08:00");
System.out.println(dateTime); // out: 2016-02-15T00:00:00.000+08:00

​

访问DateTime实例:

  • with开头的方法(比如:withYear):用来设置DateTime实例到某个时间,因为DateTime是不可变对象,所以没有提setter方法可供使用,with方法也没有改变原有的对象,而是返回了设置后的一个副本对象。下面这个例子,将2000-02-29的年份设置为1997。值得注意的是,因为1997年没有2月29日,所以自动转为了28日。
DateTime dateTime2000Year = new DateTime(2000,2,29,0,0,0);
System.out.println(dateTime2000Year); // out: 2000-02-29T00:00:00.000+08:00

DateTime dateTime1997Year =dateTime2000Year.withYear(1997);
System.out.println(dateTime1997Year); // out: 1997-02-28T00:00:00.000+08:00

plus/minus开头的方法(比如:plusDay, minusMonths):用来返回在DateTime实例上增加或减少一段时间后的实例。下面的例子:在当前的时刻加1天,得到了明天这个时刻的时间;在当前的时刻减1个月,得到了上个月这个时刻的时间。

DateTime now = new DateTime();
System.out.println(now); // out: 2016-02-26T16:27:58.818+08:00

DateTime tomorrow = now.plusDays(1);
System.out.println(tomorrow); // out: 2016-02-27T16:27:58.818+08:00

DateTime lastMonth = now.minusMonths(1);
System.out.println(lastMonth); // out: 2016-01-26T16:27:58.818+08:00
  • 注意,在增减时间的时候,想象成自己在翻日历,所有的计算都将符合历法,由Joda-Time自动完成,不会出现非法的日期(比如:3月31日加一个月后,并不会出现4月31日)。
  • 返回Property的方法:Property是DateTime中的属性,保存了一些有用的信息。Property对象中的一些方法在这里一并介绍。下面的例子展示了,我们可以通过不同Property中get开头的方法获取一些有用的信息:
DateTime now = new DateTime(); // 2016-02-26T16:51:28.749+08:00
now.monthOfYear().getAsText(); // February
now.monthOfYear().getAsText(Locale.KOREAN); // 2월
now.dayOfWeek().getAsShortText(); // Fri
now.dayOfWeek().getAsShortText(Locale.CHINESE); // 星期五

      有时我们需要对一个DateTime的某些属性进行置0操作。比如,我想得到当天的0点时刻。那么就需要用到Property中round开头的方法(roundFloorCopy)。如下面的例子所示:

DateTime now = new DateTime(); // 2016-02-26T16:51:28.749+08:00
now.dayOfWeek().roundCeilingCopy(); // 2016-02-27T00:00:00.000+08:00
now.dayOfWeek().roundFloorCopy(); // 2016-02-26T00:00:00.000+08:00
now.minuteOfDay().roundFloorCopy(); // 2016-02-26T16:51:00.000+08:00
now.secondOfMinute().roundFloorCopy(); // 2016-02-26T16:51:28.000+08:00
  • 其它:还有许多其它方法(比如dateTime.year().isLeap()来判断是不是闰年)。它们的详细含义,请参照Java Doc,现查现用,用需求驱动学习。

日历系统和时区

       Joda-Time默认使用的是ISO的日历系统,而ISO的日历系统是世界上公历的事实标准。然而,值得注意的是,ISO日历系统在表示1583年之前的历史时间是不精确的。
       Joda-Time默认使用的是JDK的时区设置。如果需要的话,这个默认值是可以被覆盖的。
       Joda-Time使用可插拔的机制来设计日历系统,而JDK则是使用子类的设计,比如GregorianCalendar。下面的代码,通过调用一个工厂方法获得Chronology的实现:

Chronology coptic = CopticChronology.getInstance();

      时区是作为chronology的一部分来被实现的。下面的代码获得一个Joda-Time chronology在东京的时区:

DateTimeZone zone = DateTimeZone.forID("Asia/Tokyo");

Chronology gregorianJuian = GJChronology.getInstance(zone);

Interval和Period

Joda-Time时间段表示
Interval 保存了一个开始时刻和一个结束时刻,因此能够表示一段时间,并进行这段时间的相应操作
Period 保存了一段时间,比如:6个月,3天,7小时这样的概念。可以直接创建Period,或者从Interval对象构建
Duration 保存了一个精确的毫秒数。同样地,可以直接创建Duration,也可以从Interval对象构建

 虽然,这三个类都用来表示时间段,但是在用途上来说还是有一些差别。请看下面的例子:

DateTime dt = new DateTime(2005, 3, 26, 12, 0, 0, 0);

DateTime plusPeriod = dt.plus(Period.days(1));

DateTime plusDuration = dt.plus(new Duration(24L*60L*60L*1000L));

    因为当时那个地区执行夏令时的原因,在添加一个Period的时候会添加23个小时。而添加一个Duration,则会精确地添加24个小时,而不考虑历法。所以,Period和Duration的差别不但体现在精度上,也同样体现在语义上。因为,有时候按照有些地区的历法 1天 不等于 24小时。

package com.test.test;

import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

/**
 * 
 * @ClassName: TestJoda
 * @Description: Joda-Time测试
 * @author 龙队今天赢了吗
 * @date 2018年8月8日 上午11:33:10
 *
 */
public class TestJoda {

	public static void main(String[] args) {
		// 初始化时间
		DateTime dateTime0 = new DateTime(2018, 8, 8, 1, 1, 1);

		// 年,月,日,时,分,秒,毫秒
		DateTime dateTime = new DateTime(2018, 8, 8, 1, 1, 1, 233);

		// 下面就是按照一点的格式输出时间
		String dateString = dateTime.toString("dd-MM-yyyy HH:mm:ss");

		DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
		// 时间解析
		DateTime dateTime2 = DateTime.parse("2017-8-8 7:22:45", format);

		// 时间格式化,输出==> 2018/08/8 07:22:45 星期三
		String string_u = dateTime2.toString("yyyy/MM/dd HH:mm:ss EE");
		System.out.println("2017/08/8 07:22:45 星期六三  --->  " + string_u);

		// 格式化带Locale,输出==> 2017年08月08日 07:22:45 星期三
		String string_c = dateTime2.toString("yyyy年MM月dd日 HH:mm:ss EE", Locale.CHINESE);
		System.out.println("格式化带Locale,输出==> 2018年08月08日 07:22:45 星期三   --->  " + string_c);

		DateTime dt1 = new DateTime();// 取得当前时间

		// 根据指定格式,将时间字符串转换成DateTime对象,这里的格式和上面的输出格式是一样的
		DateTime dt2 = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").parseDateTime("2012-12-26 03:27:39");

		// 计算两个日期间隔的天数
		LocalDate start = new LocalDate(2018, 8, 8);
		LocalDate end = new LocalDate(2018, 6, 6);
		int days = Days.daysBetween(start, end).getDays();

		// 计算两个日期间隔的小时数,分钟数,秒数

		// 增加日期
		DateTime dateTime1 = DateTime.parse("2018-8-8");
		dateTime1 = dateTime1.plusDays(30);
		dateTime1 = dateTime1.plusHours(3);
		dateTime1 = dateTime1.plusMinutes(3);
		dateTime1 = dateTime1.plusMonths(2);
		dateTime1 = dateTime1.plusSeconds(4);
		dateTime1 = dateTime1.plusWeeks(5);
		dateTime1 = dateTime1.plusYears(3);

		dateTime = dateTime.plusDays(1) // 增加天
				.plusYears(1)// 增加年
				.plusMonths(1)// 增加月
				.plusWeeks(1)// 增加星期
				.minusMillis(1)// 减分钟
				.minusHours(1)// 减小时
				.minusSeconds(1);// 减秒数

		// 判断是否闰月
		DateTime dt4 = new DateTime();
		org.joda.time.DateTime.Property month = dt4.monthOfYear();
		System.out.println("是否闰月:" + month.isLeap());

		// 取得 3秒前的时间
		DateTime dt5 = dateTime1.secondOfMinute().addToCopy(-3);
		dateTime1.getSecondOfMinute();// 得到整分钟后,过的秒钟数
		dateTime1.getSecondOfDay();// 得到整天后,过的秒钟数
		dateTime1.secondOfMinute();// 得到分钟对象,例如做闰年判断等使用

		// DateTime与java.util.Date对象,当前系统TimeMillis转换
		DateTime dt6 = new DateTime(new Date());
		Date date = dateTime1.toDate();
		DateTime dt7 = new DateTime(System.currentTimeMillis());
		dateTime1.getMillis();

		Calendar calendar = Calendar.getInstance();
		dateTime = new DateTime(calendar);
	}

}

猜你喜欢

转载自blog.csdn.net/weixin_42171657/article/details/81503947