java中使用Joda-Time处理时间
简介
在Java中处理日期和时间是很常见的需求,基础的工具类就是我们熟悉的Date和Calendar,然而这些工具类的api使用并不是很方便和强大,于是就诞生了Joda-Time这个专门处理日期时间的库。
核心类
使用最多的五个日期时间类:
- Instant - 不可变的类,用来表示时间轴上一个瞬时的点(时间戳)
- DateTime - 不可变的类,用来替换JDK的Calendar类
LocalDate - 不可变的类,表示一个本地的日期,而不包含时间部分(没有时区信息)
- LocalTime - 不可变的类,表示一个本地的时间,而不包含日期部分(没有时区信息)
- LocalDateTime - 不可变的类,表示一个本地的日期-时间(没有时区信息)
maven配置:
<!-- 日期工具栏依赖 -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.4</version>
</dependency>
工具类提供:
package com.macro.mall.tiny.demo.utils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.joda.time.DateTime;
* @author zhangtonghao
* @create 2022-09-05 16:00
public class JodaTimeUtils {
public static String getThisWeekEndTime() {
DateTime now = DateTime.now();
now = now.withDayOfWeek(7)
.withHourOfDay(23)
.withMinuteOfHour(59)
.withSecondOfMinute(59);
//本周日
return DateFormatUtils.format(now.toDate(), "yyyy-MM-dd HH:mm:ss");
public static String getThisWeekStartTime() {
DateTime now = DateTime.now();
now = now.withDayOfWeek(1)
.withHourOfDay(0)
.withMinuteOfHour(0)
.withSecondOfMinute(0);
//本周1
return DateFormatUtils.format(now.toDate(), "yyyy-MM-dd HH:mm:ss");
public static String getThisDayStartTime() {
DateTime now = DateTime.now();
now = now.millisOfDay()
.withMinimumValue();
return DateFormatUtils.format(now.toDate(), "yyyy-MM-dd HH:mm:ss");
public static String getThisDayEndTime() {
DateTime now = DateTime.now();
now = now.millisOfDay()
.withMaximumValue();
return DateFormatUtils.format(now.toDate(), "yyyy-MM-dd HH:mm:ss");
public static String getThisMonthStartTime() {
DateTime now = DateTime.now();
now = now.dayOfMonth().withMinimumValue()
.withHourOfDay(0)
.withMinuteOfHour(0)
.withSecondOfMinute(0);
//本月初
return DateFormatUtils.format(now.toDate(), "yyyy-MM-dd HH:mm:ss");
public static String getThisMonthEndTime() {
DateTime now = DateTime.now();
now = now.dayOfMonth().withMaximumValue()
.withHourOfDay(23)
.withMinuteOfHour(59)
.withSecondOfMinute(59);
//本月末
return DateFormatUtils.format(now.toDate(), "yyyy-MM-dd HH:mm:ss");
// i 0 本月1上一个月 类推
public static String getMonthStartTime(int i) {
DateTime now = DateTime.now();
now = now.minusMonths(i).dayOfMonth().withMinimumValue()
.withHourOfDay(0)
.withMinuteOfHour(0)
.withSecondOfMinute(0);
//本月初
return DateFormatUtils.format(now.toDate(), "yyyy-MM-dd HH:mm:ss");
public static String getMonthEndTime(int i) {
DateTime now = DateTime.now();
now = now.minusMonths(i).dayOfMonth().withMaximumValue()
.withHourOfDay(23)
.withMinuteOfHour(59)
.withSecondOfMinute(59);
//本月末
return DateFormatUtils.format(now.toDate(), "yyyy-MM-dd HH:mm:ss");
}
拓展使用:
with开头的方法(比如:withYear):用来设置DateTime实例的某个时间。因为DateTime是不可变对象,所以没有提供setter方法可供使用,with方法也没有改变原有的对象,而是返回了设置后的一个副本对象。
plus/minus开头的方法(比如:plusDay, minusMonths):用来返回在DateTime实例上增加或减少一段时间后的实例。
返回Property的方法:Property是DateTime中的属性,保存了一些有用的信息。
DateTime dt = new DateTime(2000, 11, 27, 0, 0, 0);
System.out.println(dt);
dt = dt.withYear(2017);// 设置年份为2017
System.out.println(dt);
时间获取:
DateTime dt = new DateTime(2000, 11, 27, 0, 0, 0);
System.out.println(dt);
dt = dt.withYear(2017); // 设置年份为2017
System.out.println(dt);
int year = dt.getYear();// 年
int month = dt.getMonthOfYear();// 月
int day = dt.getDayOfMonth();// 日
int hour = dt.getHourOfDay();// 小时
int minute = dt.getMinuteOfHour();// 分钟
int second = dt.getSecondOfMinute();// 秒
int millis = dt.getMillisOfSecond();// 毫秒
System.out.println(year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second + ":" + millis);
String month2 = dt.monthOfYear().getAsText();
String day2 = dt.dayOfWeek().getAsShortText();
String day3 = dt.dayOfWeek().getAsShortText(Locale.CHINESE); // 以指定格式获取
System.out.println(month2);
System.out.println(day2);
System.out.println(day3);
时间计算:
dt = dt.plusDays(1);// 加一天
dt = dt.plusHours(1);// 加一小时
dt = dt.plusYears(-1);// 减一年
System.out.println(dt.toString("yyyy-MM-dd HH:mm:ss"));
dt = dt.minusYears(1);// 减一年
dt = dt.minusMinutes(-30);// 加半个小时
System.out.println(dt.toString("yyyy-MM-dd HH:mm:ss"));
与jdk互操作:
Date date = dt.toDate();
Calendar calendar = dt.toCalendar(Locale.CHINESE);
// 某些属性进行置0操作。比如,我想得到当天的0点时刻。
DateTime now = new DateTime();
now.dayOfWeek().roundCeilingCopy();
now.dayOfWeek().roundFloorCopy();
now.minuteOfDay().roundFloorCopy();
now.secondOfMinute().roundFloorCopy();
其它:还有许多其它方法(比如dateTime.year().isLeap()来判断是不是闰年)。
工具类累加(最好先看懂上面相关的使用方法以及函数)
private static final String PATTERN_STANDARD = "yyyy-MM-dd HH:mm:ss";
private static final String PATTERN_DATE = "yyyy-MM-dd";
private static final String PATTERN_TIME = "HH:mm:ss";
* date类型 -> string类型
* @param date
* @return
public static String date2Str(Date date) {
if (date == null) {
return "";
DateTime dateTime = new DateTime(date);
return dateTime.toString(PATTERN_STANDARD);
* date类型 -> string类型
* @param date
* @param formatPattern
* @return
public static String date2Str(Date date, String formatPattern) {
if (date == null) {
return "";
DateTime dateTime = new DateTime(date);
return dateTime.toString(formatPattern);
* string类型 -> date类型
* @param timeStr
* @return
public static Date str2Date(String timeStr) {
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(PATTERN_STANDARD);
DateTime dateTime = dateTimeFormatter.parseDateTime(timeStr);
return dateTime.toDate();
* 获取指定时间
* @param year 年
* @param month 月
* @param day 日
* @param hour 时
* @param minute 分
* @param seconds 秒
* @return yyyy-MM-dd HH:mm:ss
public static String getAssignedDateTime(Integer year, Integer month, Integer day, Integer hour, Integer minute, Integer seconds) {
DateTime dt = new DateTime(year, month, day, hour, minute, seconds);
String date = dt.toString(PATTERN_STANDARD);
return date;
* 获取指定日期
* @param year
* @param month
* @param day
* @return
public static String getAssignedDate(Integer year, Integer month, Integer day) {
LocalDate dt = new LocalDate(year, month, day);
String date = dt.toString(PATTERN_DATE);
return date;
* 获取指定时间
* @param hour
* @param minutes
* @param seconds
* @return
public static String getAssignedTime(Integer hour, Integer minutes, Integer seconds) {
LocalTime dt = new LocalTime(hour, minutes, seconds);
String date = dt.toString(PATTERN_TIME);
return date;
* 判断date日期是否过期(与当前时刻比较)
* @param date
* @return
public static boolean isTimeExpired(Date date) {
if (null == date) {
return true;
String timeStr = date2Str(date);
return isBeforeNow(timeStr);
* 判断date日期是否过期(与当前时刻比较)
* @param timeStr
* @return
public static boolean isTimeExpired(String timeStr) {
if (StringUtils.isBlank(timeStr)) {
return true;
return isBeforeNow(timeStr);
* 判断timeStr是否在当前时刻之前
* @param timeStr
* @return
private static boolean isBeforeNow(String timeStr) {
DateTimeFormatter format = DateTimeFormat.forPattern(PATTERN_STANDARD);
DateTime dateTime = DateTime.parse(timeStr, format);
return dateTime.isBeforeNow();
* 加天数
* @param date
* @param days
* @return
private static Date plusDays(Date date, Integer days) {
if (null == date) {
return null;
days = null == days ? 0 : days;
DateTime dateTime = new DateTime(date);
dateTime = dateTime.plusDays(days);
return dateTime.toDate();
* 减天数
* @param date
* @param days
* @return
private static Date minusDays(Date date, Integer days) {
if (null == date) {
return null;
days = null == days ? 0 : days;
DateTime dateTime = new DateTime(date);
dateTime = dateTime.minusDays(days);
return dateTime.toDate();
* 加分钟
* @param date
* @param minutes
* @return
private static Date plusMinutes(Date date, Integer minutes) {
if (null == date) {
return null;
minutes = null == minutes ? 0 : minutes;
DateTime dateTime = new DateTime(date);
dateTime = dateTime.plusMinutes(minutes);
return dateTime.toDate();
* 减分钟
* @param date
* @param minutes
* @return
private static Date minusMinutes(Date date, Integer minutes) {
if (null == date) {
return null;
minutes = null == minutes ? 0 : minutes;
DateTime dateTime = new DateTime(date);
dateTime = dateTime.minusMinutes(minutes);
return dateTime.toDate();
* 加月份
* @param date
* @param months
* @return
private static Date plusMonths(Date date, Integer months) {
if (null == date) {
return null;
months = null == months ? 0 : months;
DateTime dateTime = new DateTime(date);
dateTime = dateTime.plusMonths(months);
return dateTime.toDate();
* 减月份
* @param date
* @param months
* @return
private static Date minusMonths(Date date, Integer months) {
if (null == date) {
return null;
months = null == months ? 0 : months;
DateTime dateTime = new DateTime(date);
dateTime = dateTime.minusMonths(months);
return dateTime.toDate();
* 判断target是否在开始和结束时间之间
* @param target
* @param startTime
* @param endTime
* @return
public static boolean isBetween(Date target, Date startTime, Date endTime) {
if (null == target || null == startTime || null == endTime) {
return false;
DateTime dateTime = new DateTime(target);
return dateTime.isAfter(startTime.getTime()) && dateTime.isBefore(endTime.getTime());
* 获取当前系统时间
* @return yyyy-MM-dd HH:mm:ss
public static String getCurrentDateTime() {
DateTime dt = new DateTime();
String time = dt.toString(PATTERN_STANDARD);
return time;
* 获取当前日期
* @return
public static String getCurrentDate() {
DateTime dt = new DateTime();
String date = dt.toString(PATTERN_DATE);
return date;
* 获取系统当前时间按照指定格式返回
* @return
public static String getCurrentTime() {
DateTime dt = new DateTime();
String time = dt.toString(PATTERN_TIME);
return time;
* 获取当前是一周星期几
* @return
public static String getWeek() {
DateTime dts = new DateTime();
String week = null;
switch (dts.getDayOfWeek()) {
case DateTimeConstants.SUNDAY:
week = "星期日";
break;
case DateTimeConstants.MONDAY:
week = "星期一";
break;
case DateTimeConstants.TUESDAY:
week = "星期二";
break;
case DateTimeConstants.WEDNESDAY:
week = "星期三";
break;
case DateTimeConstants.THURSDAY:
week = "星期四";
break;
case DateTimeConstants.FRIDAY:
week = "星期五";
break;
case DateTimeConstants.SATURDAY:
week = "星期六";
default:
break;
return week;
* 获取指定时间是一周的星期几
* @param year
* @param month
* @param day
* @return
public static String getWeek(Integer year, Integer month, Integer day) {
LocalDate dts = new LocalDate(year, month, day);
String week = null;
switch (dts.getDayOfWeek()) {
case DateTimeConstants.SUNDAY:
week = "星期日";
break;
case DateTimeConstants.MONDAY:
week = "星期一";
break;
case DateTimeConstants.TUESDAY:
week = "星期二";
break;
case DateTimeConstants.WEDNESDAY:
week = "星期三";
break;
case DateTimeConstants.THURSDAY:
week = "星期四";
break;
case DateTimeConstants.FRIDAY:
week = "星期五";
break;
case DateTimeConstants.SATURDAY:
week = "星期六";
break;
default:
break;
return week;
* 计算两个时间相差多少天
* @param startDate
* @param endDate
* @return
public static Integer diffDay(Date startDate, Date endDate) {
if (startDate == null || endDate == null) {
return null;