All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.lulihu.dateTime.DateTimeKit Maven / Gradle / Ivy

package net.lulihu.dateTime;

import net.lulihu.ObjectKit.StrKit;
import net.lulihu.exception.ToolBoxException;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.Locale;

/**
 * 时间工具类
 */
public class DateTimeKit {
    /**
     * 毫秒
     */
    public final static long MS = 1;
    /**
     * 每秒钟的毫秒数
     */
    public final static long SECOND_MS = MS * 1000;
    /**
     * 每分钟的毫秒数
     */
    public final static long MINUTE_MS = SECOND_MS * 60;
    /**
     * 每小时的毫秒数
     */
    public final static long HOUR_MS = MINUTE_MS * 60;
    /**
     * 每天的毫秒数
     */
    public final static long DAY_MS = HOUR_MS * 24;

    /**
     * 标准日期时间格式,精确到月
     */
    public final static String NORM_DATETIME_MONTH_PATTERN = "yyyy-MM";

    /**
     * 标准日期格式
     */
    public final static String NORM_DATE_PATTERN = "yyyy-MM-dd";

    /**
     * 标准时间格式
     */
    public final static String NORM_TIME_PATTERN = "HH:mm:ss";

    /**
     * 标准日期时间格式,精确到小时
     */
    public final static String NORM_DATETIME_HOUR_PATTERN = "yyyy-MM-dd HH";

    /**
     * 标准日期时间格式,精确到分
     */
    public final static String NORM_DATETIME_MINUTE_PATTERN = "yyyy-MM-dd HH:mm";
    /**
     * 标准日期时间格式,精确到秒
     */
    public final static String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
    /**
     * 标准日期时间格式,精确到毫秒
     */
    public final static String NORM_DATETIME_MS_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS";
    /**
     * HTTP头中日期时间格式
     */
    public final static String HTTP_DATETIME_PATTERN = "EEE, dd MMM yyyy HH:mm:ss z";

    /**
     * 标准日期时间格式,精确到小时
     */
    public final static ThreadLocal NORM_DATETIME_HOUR_FORMAT = ThreadLocal.withInitial(() -> new SimpleDateFormat(NORM_DATETIME_HOUR_PATTERN));

    /**
     * 标准日期(不含时间)格式化器
     */
    public final static ThreadLocal NORM_DATE_FORMAT = ThreadLocal.withInitial(() -> new SimpleDateFormat(NORM_DATE_PATTERN));

    /**
     * 标准时间格式化器
     */
    public final static ThreadLocal NORM_TIME_FORMAT = ThreadLocal.withInitial(() -> new SimpleDateFormat(NORM_TIME_PATTERN));

    /**
     * 标准日期时间格式化器
     */
    public final static ThreadLocal NORM_DATETIME_FORMAT = ThreadLocal.withInitial(() -> new SimpleDateFormat(NORM_DATETIME_PATTERN));

    /**
     * HTTP日期时间格式化器
     */
    public final static ThreadLocal HTTP_DATETIME_FORMAT = ThreadLocal.withInitial(() -> new SimpleDateFormat(HTTP_DATETIME_PATTERN, Locale.US));

    /**
     * 当前时间,格式 yyyy-MM-dd HH:mm:ss
     *
     * @return 当前时间的标准形式字符串
     */
    public static String now() {
        return formatDateTime(date());
    }

    /**
     * 当前时间long
     *
     * @param isNano 是否为高精度时间
     * @return 时间
     */
    public static long current(boolean isNano) {
        return isNano ? System.nanoTime() : System.currentTimeMillis();
    }

    /**
     * 当前日期,格式 yyyy-MM-dd
     *
     * @return 当前日期的标准形式字符串
     */
    public static String today() {
        return formatDate(new DateTime());
    }

    /**
     * @return 当前月份
     */
    public static int thisMonth() {
        return month(date());
    }

    /**
     * @return 今年
     */
    public static int thisYear() {
        return year(date());
    }

    /**
     * @return 当前时间
     */
    public static DateTime date() {
        return new DateTime();
    }

    /**
     * Long类型时间转为Date
     *
     * @param date Long类型Date(Unix时间戳)
     * @return 时间对象
     */
    public static DateTime date(long date) {
        return new DateTime(date);
    }


    /**
     * 获取精确到秒的时间戳
     */
    public static Long getSecondTime(Date date) {
        long time = date.getTime();
        String value = String.valueOf(time);
        String sub = StrKit.sub(value, 0, value.length() - 3);
        return Long.valueOf(sub);
    }

    /**
     * 精确到秒的时间戳转为 DateTime对象
     *
     * @param secondTime 时间戳
     * @return DateTime
     */
    public static DateTime secondTimeToDate(Long secondTime) {
        return date(secondTime * 1000);
    }

    /**
     * 转换为Calendar对象
     *
     * @param date 日期对象
     * @return Calendar对象
     */
    public static Calendar toCalendar(Date date) {
        final Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal;
    }

    /**
     * 获得月份,从1月开始计数
     *
     * @param date 日期
     * @return 月份
     */
    public static int month(Date date) {
        return toCalendar(date).get(Calendar.MONTH) + 1;
    }

    /**
     * 获得年
     *
     * @param date 日期
     * @return 年
     */
    public static int year(Date date) {
        return toCalendar(date).get(Calendar.YEAR);
    }

    /**
     * 获得季节
     *
     * @param date 日期
     * @return 第几个季节
     */
    public static int season(Date date) {
        return toCalendar(date).get(Calendar.MONTH) / 3 + 1;
    }

    /**
     * 获得指定日期年份和季节
* 格式:[20131]表示2013年第一季度 * * @param date 日期 * @return Season ,类似于 20132 */ public static String yearAndSeason(Date date) { return yearAndSeason(toCalendar(date)); } /** * 获得指定日期区间内的年份和季节
* * @param startDate 其实日期(包含) * @param endDate 结束日期(包含) * @return Season列表 ,元素类似于 20132 */ public static LinkedHashSet yearAndSeasons(Date startDate, Date endDate) { final LinkedHashSet seasons = new LinkedHashSet<>(); if (startDate == null || endDate == null) return seasons; final Calendar cal = Calendar.getInstance(); cal.setTime(startDate); while (true) { if (startDate.after(endDate)) { break; } seasons.add(yearAndSeason(cal)); if (startDate.equals(endDate)) { break; } cal.add(Calendar.MONTH, 3); startDate = cal.getTime(); } cal.setTime(endDate); seasons.add(yearAndSeason(cal)); return seasons; } // ------------------------------------ Format start ---------------------------------------------- /** * 根据特定格式格式化日期 * * @param date 被格式化的日期 * @param format 格式 * @return 格式化后的字符串 */ public static String format(Date date, String format) { return new SimpleDateFormat(format).format(date); } /** * 格式 yyyy-MM-dd HH:mm:ss * * @param date 被格式化的日期 * @return 格式化后的日期 */ public static String formatDateTime(Date date) { if (null == date) { return null; } return NORM_DATETIME_FORMAT.get().format(date); } /** * 格式 yyyy-MM-dd HH * * @param date 被格式化的日期 * @return 格式化后的字符串 */ public static String formatDateHour(Date date) { if (null == date) { return null; } return NORM_DATETIME_HOUR_FORMAT.get().format(date); } /** * 格式 yyyy-MM-dd * * @param date 被格式化的日期 * @return 格式化后的字符串 */ public static String formatDate(Date date) { if (null == date) { return null; } return NORM_DATE_FORMAT.get().format(date); } /** * 格式化为Http的标准日期格式 * * @param date 被格式化的日期 * @return HTTP标准形式日期字符串 */ public static String formatHttpDate(Date date) { if (null == date) { return null; } return HTTP_DATETIME_FORMAT.get().format(date); } // ------------------------------------ Format end ---------------------------------------------- // ------------------------------------ Parse start ---------------------------------------------- /** * 构建DateTime对象 * * @param dateStr Date字符串 * @param simpleDateFormat 格式化器 * @return DateTime对象 */ public static DateTime parse(String dateStr, SimpleDateFormat simpleDateFormat) { try { return new DateTime(simpleDateFormat.parse(dateStr)); } catch (Exception e) { throw new ToolBoxException(StrKit.format("解析 [{}] 格式化 [{}] 错误!", dateStr, simpleDateFormat.toPattern()), e); } } /** * 将特定格式的日期转换为Date对象 * * @param dateString 特定格式的日期 * @param format 格式,例如yyyy-MM-dd * @return 日期对象 */ public static DateTime parse(String dateString, String format) { return parse(dateString, new SimpleDateFormat(format)); } /** * 格式yyyy-MM-dd HH:mm * * @param dateString 标准形式的时间字符串 * @return 日期对象 */ public static DateTime parseTimeMinutes(String dateString) { return parse(dateString, "yyyy-MM-dd HH:mm"); } /** * 格式yyyy-MM-dd HH:mm:ss * * @param dateString 标准形式的时间字符串 * @return 日期对象 */ public static DateTime parseDateTime(String dateString) { return parse(dateString, NORM_DATETIME_FORMAT.get()); } /** * 格式yyyy-MM-dd * * @param dateString 标准形式的日期字符串 * @return 日期对象 */ public static DateTime parseDate(String dateString) { return parse(dateString, NORM_DATE_FORMAT.get()); } /** * 格式HH:mm:ss * * @param timeString 标准形式的日期字符串 * @return 日期对象 */ public static DateTime parseTime(String timeString) { return parse(timeString, NORM_TIME_FORMAT.get()); } /** * 格式:
* 1、yyyy-MM-dd HH:mm:ss
* 2、yyyy-MM-dd
* 3、HH:mm:ss
* 4、yyyy-MM-dd HH:mm * 5、yyyy-MM-dd HH:mm:ss.SSS * * @param dateStr 日期字符串 * @return 日期 */ public static DateTime parse(String dateStr) { if (null == dateStr) { return null; } dateStr = dateStr.trim(); int length = dateStr.length(); try { if (length == NORM_DATETIME_PATTERN.length()) { return parseDateTime(dateStr); } else if (length == NORM_DATE_PATTERN.length()) { return parseDate(dateStr); } else if (length == NORM_TIME_PATTERN.length()) { return parseTime(dateStr); } else if (length == NORM_DATETIME_MINUTE_PATTERN.length()) { return parse(dateStr, NORM_DATETIME_MINUTE_PATTERN); } else if (length >= NORM_DATETIME_MS_PATTERN.length() - 2) { return parse(dateStr, NORM_DATETIME_MS_PATTERN); } } catch (Exception e) { throw new ToolBoxException(StrKit.format("使用格式[{}]解析错误!", dateStr)); } // 没有更多匹配的时间格式 throw new ToolBoxException(StrKit.format(" [{}]格式不适合日期模式!", dateStr)); } // ------------------------------------ Parse end ---------------------------------------------- // ------------------------------------ Offset start ---------------------------------------------- /** * 获取某月的开始时间 * * @param date 日期 * @return 某月的开始时间 */ public static DateTime getBeginTimeOfMonth(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); calendar.set(Calendar.DAY_OF_MONTH, 1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); return new DateTime(calendar.getTime()); } /** * 获取某天的开始时间 * * @param date 日期 * @return 某天的开始时间 */ public static DateTime getBeginTimeOfDay(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); return new DateTime(calendar.getTime()); } /** * 获取某天的结束时间 * * @param date 日期 * @return 某天的结束时间 */ public static DateTime getEndTimeOfDay(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 59); calendar.set(Calendar.SECOND, 59); calendar.set(Calendar.MILLISECOND, 999); return new DateTime(calendar.getTime()); } /** * 昨天 * * @return 昨天 */ public static DateTime yesterday() { return offsetDay(new DateTime(), -1); } /** * 上周 * * @return 上周 */ public static DateTime lastWeek() { return offsetWeek(new DateTime(), -1); } /** * 上个月 * * @return 上个月 */ public static DateTime lastMouth() { return offsetMonth(new DateTime(), -1); } /** * 偏移秒 * * @param date 日期 * @param offset 偏移秒数,正数向未来偏移,负数向历史偏移 * @return 偏移后的日期 */ public static DateTime offsetSecond(Date date, int offset) { return offsetDate(date, Calendar.SECOND, offset); } /** * 偏移天 * * @param date 日期 * @param offset 偏移天数,正数向未来偏移,负数向历史偏移 * @return 偏移后的日期 */ public static DateTime offsetDay(Date date, int offset) { return offsetDate(date, Calendar.DAY_OF_YEAR, offset); } /** * 偏移周 * * @param date 日期 * @param offset 偏移周数,正数向未来偏移,负数向历史偏移 * @return 偏移后的日期 */ public static DateTime offsetWeek(Date date, int offset) { return offsetDate(date, Calendar.WEEK_OF_YEAR, offset); } /** * 偏移月 * * @param date 日期 * @param offset 偏移月数,正数向未来偏移,负数向历史偏移 * @return 偏移后的日期 */ public static DateTime offsetMonth(Date date, int offset) { return offsetDate(date, Calendar.MONTH, offset); } /** * 偏移年 * * @param date 日期 * @param offset 偏移年数,正数向未来偏移,负数向历史偏移 * @return 偏移后的日期 */ public static DateTime offsetYear(Date date, int offset) { return offsetDate(date, Calendar.YEAR, offset); } /** * 指定日期增加(小时) * * @param date 指定的一个原始日期 * @param amount 数值增量 * @return 新日期 */ public static Date offsetHour(Date date, int amount) { return offsetDate(date, Calendar.HOUR_OF_DAY, amount); } /** * 指定日期增加(分钟) * * @param date 指定的一个原始日期 * @param amount 数值增量 * @return 新日期 */ public static Date offsetMinute(Date date, int amount) { return offsetDate(date, Calendar.MINUTE, amount); } /** * 获取指定日期偏移指定时间后的时间 * * @param date 基准日期 * @param calendarField 偏移的粒度大小(小时、天、月等)使用Calendar中的常数 * @param offset 偏移量,正数为向后偏移,负数为向前偏移 * @return 偏移后的日期 */ public static DateTime offsetDate(Date date, int calendarField, int offset) { Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.add(calendarField, offset); return new DateTime(cal.getTime()); } // ------------------------------------ Offset end ---------------------------------------------- /** * 计算指定指定时间区间内的周数 *

* 不能跨年 * * @param start 开始时间 * @param end 结束时间 * @return 周数 */ public static int weekCount(Date start, Date end) { final Calendar startCalendar = Calendar.getInstance(); startCalendar.setTime(start); final Calendar endCalendar = Calendar.getInstance(); endCalendar.setTime(end); final int startWeekOfYear = startCalendar.get(Calendar.WEEK_OF_YEAR); final int endWeekOfYear = endCalendar.get(Calendar.WEEK_OF_YEAR); int count = endWeekOfYear - startWeekOfYear + 1; if (Calendar.SUNDAY != startCalendar.get(Calendar.DAY_OF_WEEK)) { count--; } return count; } /** * 判断两个日期相差的天数
* 返回 minuend - subtrahend 的差 * * @param subtrahend 减数日期 * @param minuend 被减数日期 * @return 日期差 */ public static long diffDay(Date subtrahend, Date minuend) { return diff(subtrahend, minuend, 24 * 60 * 60 * 1000); } /** * 判断两个日期相差的分钟数
* 返回 minuend - subtrahend 的差 * * @param subtrahend 减数日期 * @param minuend 被减数日期 * @return 日期差 */ public static long diffMinute(Date subtrahend, Date minuend) { return diff(subtrahend, minuend, 60 * 1000); } /** * 判断两个日期相差的小时数
* 返回 minuend - subtrahend 的差 * * @param subtrahend 减数日期 * @param minuend 被减数日期 * @return 日期差 */ public static long diffHour(Date subtrahend, Date minuend) { return diff(subtrahend, minuend, 60 * 60 * 1000); } /** * 判断两个日期相差的秒数
* 返回 minuend - subtrahend 的差 * * @param subtrahend 减数日期 * @param minuend 被减数日期 * @return 日期差 */ public static long diffSecond(Date subtrahend, Date minuend) { return diff(subtrahend, minuend, 1000); } /** * 判断两个日期相差的时长
* 返回 minuend - subtrahend 的差 * * @param subtrahend 减数日期 * @param minuend 被减数日期 * @param diffField 相差的选项:相差的天、小时 * @return 日期差 */ public static long diff(Date subtrahend, Date minuend, long diffField) { long diff = minuend.getTime() - subtrahend.getTime(); return diff / diffField; } /** * 计时,常用于记录某段代码的执行时间,单位:纳秒 * * @param preTime 之前记录的时间 * @return 时间差,纳秒 */ public static long spendNt(long preTime) { return System.nanoTime() - preTime; } /** * 计时,常用于记录某段代码的执行时间,单位:毫秒 * * @param preTime 之前记录的时间 * @return 时间差,毫秒 */ public static long spendMs(long preTime) { return System.currentTimeMillis() - preTime; } /** * 格式化成yyMMddHHmm后转换为int型 * * @param date 日期 * @return int */ public static int toIntSecond(Date date) { return Integer.parseInt(format(date, "yyMMddHHmm")); } /** * 计时器
* 计算某个过程花费的时间,精确到毫秒 * * @return Timer */ public static Timer timer() { return new Timer(); } /** * 生日转为年龄,计算法定年龄 * * @param birthDay 生日,标准日期字符串 * @return 年龄 */ public static int ageOfNow(String birthDay) { return ageOfNow(parse(birthDay)); } /** * 生日转为年龄,计算法定年龄 * * @param birthDay 生日 * @return 年龄 */ public static int ageOfNow(Date birthDay) { return age(birthDay, date()); } /** * 计算相对于dateToCompare的年龄,长用于计算指定生日在某年的年龄 * * @param birthDay 生日 * @param dateToCompare 需要对比的日期 * @return 年龄 */ public static int age(Date birthDay, Date dateToCompare) { Calendar cal = Calendar.getInstance(); cal.setTime(dateToCompare); if (cal.before(birthDay)) { throw new IllegalArgumentException(StrKit.format("生日时间在指定时间之后 {}!", formatDate(dateToCompare))); } int year = cal.get(Calendar.YEAR); int month = cal.get(Calendar.MONTH); int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH); cal.setTime(birthDay); int age = year - cal.get(Calendar.YEAR); int monthBirth = cal.get(Calendar.MONTH); if (month == monthBirth) { int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH); if (dayOfMonth < dayOfMonthBirth) { //如果生日在当月,但是未达到生日当天的日期,年龄减一 age--; } } else if (month < monthBirth) { //如果当前月份未达到生日的月份,年龄计算减一 age--; } return age; } // ------------------------------------------------------------------------ Private method start /** * 获得指定日期年份和季节
* 格式:[20131]表示2013年第一季度 * * @param cal 日期 */ private static String yearAndSeason(Calendar cal) { return String.valueOf(cal.get(Calendar.YEAR)) + (cal.get(Calendar.MONTH) / 3 + 1); } // ------------------------------------------------------------------------ Private method end }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy