一、认识Joda Time 日期工具类
功能特色: A selection of key features:
LocalDate
- date without timeLocalTime
- time without dateInstant
- an instantaneous point on the time-lineDateTime
- full date and time with time-zoneDateTimeZone
- a better time-zoneDuration
andPeriod
- amounts of timeInterval
- the time between two instants- A comprehensive and flexible formatter-parser 来源: www.joda.org/joda-time/
二、引入依赖
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.10</version>
</dependency>
三、完整源码
核心功能:
- LocalDate 和 Date 互转;
- 返回未来指定N个(年月日时分秒周)的日期;
- 字符串转 LocalDate / LocalDateTime;
- …………TODO 更多功能等待继续扩展;
import org.joda.time.*;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.FormatUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
/**
* Joda time 日期工具类
*
* @author drew
* @create 2021-06-27 16:36
*/
public class JodaTimeUtils {
/**
* 日期时间
*/
private static final String yyyyMMddHHmmss = "yyyy-MM-dd HH:mm:ss";
/**
* 年月日
*/
private static final String yyyyMMdd = "yyyy-MM-dd";
/**
* 时分秒
*/
private static final String HHMMSS = "HH:mm:ss";
/**
* 秒
*/
private static final String DATE_TYPE_SECONDS = "seconds";
/**
* 分
*/
private static final String DATE_TYPE_MINUTE = "minute";
/**
* 时
*/
private static final String DATE_TYPE_HOUR = "hour";
/**
* 日
*/
private static final String DATE_TYPE_DAY = "day";
/**
* 周
*/
private static final String DATE_TYPE_WEEK = "week";
/**
* 月
*/
private static final String DATE_TYPE_MONTH = "month";
/**
* 年
*/
private static final String DATE_TYPE_YEAR = "year";
/**
* 获取指定日期的当前月份(例如 输入 new LocalDate() 返回当前日期的英文月份)
*
* @param dateOfBirth 出生日期(或指定日期)
* @return 月份
*/
public static String getBirthMonthTextEn(LocalDate dateOfBirth) {
return dateOfBirth.monthOfYear().getAsText(Locale.ENGLISH);
}
/**
* 返回中文月份(例如 new LocalDate() 返回 六月)
*
* @param date
* @return
*/
public static String getBirthMonthTextCn(LocalDate date) {
// 或 return date.monthOfYear().getAsText(Locale.CHINESE);
return date.monthOfYear().getAsText(Locale.CHINA);
}
/**
* 获取指定日期的月份数字
*
* @param date 日期格式:yyyy-MM-dd
* @return 1 - 12
*/
public static int getBirthMonthNumber(LocalDate date) {
return date.getMonthOfYear();
}
/**
* java.util.Date 转 org.joda.LocalDate
*
* @param date 日期
* @return org.joda.LocalDate
*/
public static LocalDate toLocalDate(Date date) {
return new LocalDate(LocalDate.fromDateFields(date));
}
/**
* 日期时间字符串转 org.joda.LocalDate
*
* @param dateStr 日期字符串(例如:“yyyy-MM-dd”)
* @return org.joda.LocalDate
*/
public static LocalDate toLocalDate(String dateStr) {
return new LocalDate(LocalDate.parse(dateStr, DateTimeFormat.forPattern(yyyyMMdd)));
}
/**
* java.util.Date 转 org.joda.LocalDateTime
*
* @param date 日期
* @return org.joda.LocalDateTime
*/
public static LocalDateTime toLocalDateTime(Date date) {
return new LocalDateTime(LocalDateTime.fromDateFields(date));
}
/**
* 日期时间字符串转 org.joda.LocalDate
*
* @param dateStr 日期字符串(例如:“yyyy-MM-dd”)
* @return org.joda.LocalDate
*/
public static LocalDateTime toLocalDateTime(String dateStr) {
return new LocalDateTime(LocalDateTime.parse(dateStr, DateTimeFormat.forPattern(yyyyMMddHHmmss)));
}
@Deprecated
public static boolean isLeap(LocalDate localDate, String dateType) {
if (dateType.equals(DATE_TYPE_DAY)) {
return localDate.dayOfYear().isLeap();
}
if (dateType.equals(DATE_TYPE_YEAR)) {
return localDate.year().isLeap();
}
// localDate.centuryOfEra().isLeap();
// localDate.era().isLeap();
// localDate.weekOfWeekyear().isLeap();
// localDate.monthOfYear().isLeap();
// localDate.dayOfWeek().isLeap();
// localDate.dayOfMonth().isLeap();
// localDate.weekyear().isLeap();
return false;
}
/**
* 获取指定的未来时间点
*
* @param localDateTime org.joda.time.LocalDateTime
* @param dateType 日期类型(年月日时分秒周)
* @param number 跨度
* @return org.joda.LocalDateTime
*/
public static LocalDateTime plus(LocalDateTime localDateTime, String dateType, int number) {
if (dateType.equals(DATE_TYPE_YEAR)) {
return localDateTime.plusYears(number);
}
if (dateType.equals(DATE_TYPE_MONTH)) {
return localDateTime.plusMonths(number);
}
if (dateType.equals(DATE_TYPE_WEEK)) {
return localDateTime.plusWeeks(number);
}
if (dateType.equals(DATE_TYPE_DAY)) {
return localDateTime.plusDays(number);
}
if (dateType.equals(DATE_TYPE_HOUR)) {
return localDateTime.plusHours(number);
}
if (dateType.equals(DATE_TYPE_MINUTE)) {
return localDateTime.plusMinutes(number);
}
if (dateType.equals(DATE_TYPE_SECONDS)) {
return localDateTime.plusSeconds(number);
}
return localDateTime;
}
/**
* 获取指定日期月份第一天/最后一天
*
* @param dateStr 日期字符串(格式:yyyy-MM-dd)
* @param isFirst true 第一天,false 最后一天
* @return 日期 org.joda.time.LocalDate
*/
public static LocalDate getFirstOrLastDayOfMonth(String dateStr, boolean isFirst) {
LocalDate localDate = new LocalDate(LocalDate.parse(dateStr, DateTimeFormat.forPattern(yyyyMMdd)));
return localDate.withDayOfMonth(isFirst ? localDate.dayOfMonth().getMinimumValue() : localDate.dayOfMonth().getMaximumValue());
}
/**
* 获取指定日期所在星期第一天/最后一天的日期 (规定:第一天为周一,最后一天为周日)
*
* @param dateStr 日期字符串(格式:yyyy-MM-dd)
* @param isFirst true 第一天,false 最后一天
* @return 日期 org.joda.time.LocalDate
*/
public static LocalDate getFirstOrLastDayOfWeek(String dateStr, boolean isFirst) {
LocalDate localDate = new LocalDate(LocalDate.parse(dateStr, DateTimeFormat.forPattern(yyyyMMdd)));
return isFirst ? localDate.withDayOfWeek(localDate.dayOfWeek().getMinimumValue()) : localDate.withDayOfWeek(localDate.dayOfWeek().getMaximumValue());
}
/**
* 获取指定日期年份第一天/最后一天
*
* @param dateStr 日期字符串(格式:yyyy-MM-dd)
* @param isFirst true 第一天,false 最后一天
* @return 日期 org.joda.time.LocalDate
*/
public static LocalDate getFirstOrLastDayOfYear(String dateStr, boolean isFirst) {
LocalDate localDate = new LocalDate(LocalDate.parse(dateStr, DateTimeFormat.forPattern(yyyyMMdd)));
return isFirst ? localDate.withDayOfYear(localDate.dayOfYear().getMinimumValue()) : localDate.withDayOfYear(localDate.dayOfYear().getMaximumValue());
}
/**
* 获取指定日期的虽在年份的第一天
*
* @param dateStr 日期字符串(格式:yyyy-MM-dd)
* @return 日期 org.joda.time.LocalDate
*/
public static LocalDate getFirstDayOfYear(String dateStr) {
LocalDate localDate = new LocalDate(LocalDate.parse(dateStr, DateTimeFormat.forPattern(yyyyMMdd)));
return localDate.withDayOfYear(localDate.dayOfYear().getMinimumValue());
}
/**
* 获取当前日期字符串
*
* @return 返回格式为:yyyy-MM-dd
*/
public static String getNowYMd() {
return LocalDate.now().toString(yyyyMMdd);
}
/**
* 获取当前日期时间字符串
*
* @return 返回值格式为:yyyy-MM-dd HH:mm:ss
*/
public static String getNowYMdHms() {
return LocalDateTime.now().toString(yyyyMMddHHmmss);
}
/**
* 返回当前日期中文写法(包含 日期-星期-时间)
*
* @return 结果实例:2021年6月27日 星期日 下午07时16分02秒
*/
public static String getNowFullDateTime() {
return LocalDateTime.now().toString(DateTimeFormat.fullDateTime());
}
/**
* 返回当前日期中文写法(包含 日期-时间)
*
* @return 结果实例:2021年6月27日 下午07时16分02秒
*/
public static String getNowLongDateTime() {
return LocalDateTime.now().toString(DateTimeFormat.longDateTime());
}
/**
* 返回当前日期中文写法(只包含 日期)
*
* @return 结果实例:2021年6月27日
*/
public static String getNowLongDate() {
return LocalDateTime.now().toString(DateTimeFormat.longDate());
}
/**
* 返回当前日期中文写法(只包含 时间)
*
* @return 结果实例:下午07时20分00秒
*/
public static String getNowLongTime() {
return LocalDateTime.now().toString(DateTimeFormat.longTime());
}
/**
* 获取某时间段内所有周的列表(开始时间,结束时间)
*
* @param startDate 开始日期
* @param endDate 结束日期
* @return 所有周列表
*/
public static List<String[]> getWeekList(Date startDate, Date endDate) {
List<String[]> weekList = new ArrayList<>();
//转换成joda-time的对象
DateTime firstDay = new DateTime(startDate).dayOfWeek().withMinimumValue();
DateTime lastDay = new DateTime(endDate).dayOfWeek().withMaximumValue();
//计算两日期间的区间天数
Period p = new Period(firstDay, lastDay, PeriodType.days());
int days = p.getDays();
if (days > 0) {
int weekLength = 7;
for (int i = 0; i < days; i = i + weekLength) {
String monDay = firstDay.plusDays(i).toString(yyyyMMdd);
String sunDay = firstDay.plusDays(i + 6).toString(yyyyMMdd);
String[] week = {monDay, sunDay};
weekList.add(week);
}
}
return weekList;
}
/**
* 根据不同的周期类型(年月日时分秒周),计算相隔多少个周期
*
* @param localDateTime1 第一个日期
* @param localDateTime2 第二个日期
* @return 正数:第一个日期 < 第二个日期;负数:第一个日期 > 第二个日期
*/
public static int betweenDays(LocalDateTime localDateTime1, LocalDateTime localDateTime2, String dateType) {
if (localDateTime1.isEqual(localDateTime2)) {
return 0;
}
if (dateType.equals(DATE_TYPE_HOUR)) {
return Hours.hoursBetween(localDateTime1, localDateTime2).getHours();
}
if (dateType.equals(DATE_TYPE_MINUTE)) {
return Minutes.minutesBetween(localDateTime1, localDateTime2).getMinutes();
}
if (dateType.equals(DATE_TYPE_SECONDS)) {
return Seconds.secondsBetween(localDateTime1, localDateTime2).getSeconds();
}
if (dateType.equals(DATE_TYPE_DAY)) {
return Days.daysBetween(localDateTime1, localDateTime2).getDays();
}
if (dateType.equals(DATE_TYPE_WEEK)) {
return Weeks.weeksBetween(localDateTime1, localDateTime2).getWeeks();
}
if (dateType.equals(DATE_TYPE_MONTH)) {
return Months.monthsBetween(localDateTime1, localDateTime2).getMonths();
}
if (dateType.equals(DATE_TYPE_YEAR)) {
return Years.yearsBetween(localDateTime1, localDateTime2).getYears();
}
return 0;
}
public static void main(String[] args) {
// System.out.println(isAfterPayDay(new DateTime()));
// System.out.println(daysToNewYear(new LocalDate()));
// System.out.println(isRentalOverdue(new DateTime()));
// System.out.println(getBirthMonthTextEn(new LocalDate()));
// System.out.println(getBirthMonthTextCn(new LocalDate()));
// System.out.println(getBirthMonthNumber(new LocalDate()));
// System.out.println(toLocalDate(new Date()));
// System.out.println(toLocalDate("2021-12-31").minusDays(2));
// System.out.println(toLocalDateTime(new Date()));
// System.out.println(toLocalDateTime("2021-12-31 10:23:59").plusDays(2));
// System.out.println(new LocalDate().year().isLeap());
// System.out.println(isLeap(new LocalDate(), DATE_TYPE_YEAR));
// System.out.println(isLeap(new LocalDate(), DATE_TYPE_DAY));
// System.out.println(plus(new LocalDateTime(), DATE_TYPE_DAY, 20));
// System.out.println(new LocalDateTime().year().addToCopy(20));// 20年后的此刻
// System.out.println(new LocalDateTime().monthOfYear().addToCopy(20)); // 20个月后的此刻
// System.out.println(new LocalDateTime().dayOfYear().addToCopy(20));// 20日后的此刻
// System.out.println(new LocalDateTime().dayOfWeek().addToCopy(20));// 20日后的此刻
// System.out.println(getFirstOrLastDayOfMonth("2021-06-01", false)); // 2021-06-30
// System.out.println(getFirstOrLastDayOfMonth("2021-02-01", false)); // 2021-02-28
// System.out.println(getFirstOrLastDayOfMonth("2421-12-01", false)); // 2021-12-31
// System.out.println(getFirstOrLastDayOfWeek("2021-06-01", false)); // 2021-06-06
// System.out.println(getFirstDayOfYear("2021-12-21")); // 2021-01-01
// System.out.println(getFirstOrLastDayOfYear("2021-01-01", false)); // 2021-12-31
// System.out.println(getNowYMd());
// System.out.println(getNowYMdHms());
// System.out.println(getNowLongDateTime());
// System.out.println(getNowLongDate());
// System.out.println(getNowLongTime());
// getWeekList(new Date(), toLocalDate("2021-03-01").toDate()).forEach(it -> {
// for (String s : it) {
// System.out.print(s + "\t");
// }
// System.out.println();
// });
// System.out.println(System.currentTimeMillis());
System.out.println(betweenDays(toLocalDateTime("2021-06-01 00:00:00"), toLocalDateTime("2021-06-10 00:00:00"), DATE_TYPE_DAY));
}
}