package com.qianlq.common.util; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; /** * @author CoderQian * @date 2018-06-01 下午10:51 * mail: [email protected] * <p> * 日期工具类 */ public class DateUtils { private static final String DATE_PATTERN = "yyyy-MM-dd HH:mm:ss"; /** * 获取当前时间(格式 yyyy-MM-dd HH:mm:ss) * * @return 时间字符串 */ public static String now() { return convertDate2String(DATE_PATTERN); } /** * 获取昨天的时间(格式 yyyy-MM-dd HH:mm:ss) * * @return 时间字符串 */ public static String yesterday() { return add(Calendar.DATE, -1); } /** * 明天(格式 yyyy-MM-dd HH:mm:ss) * * @return 时间字符串 */ public static String tomorrow() { return add(Calendar.DATE, 1); } /** * 获取当前时间(格式 yyyy-MM-dd HH:mm:ss) * * @return 时间字符串 */ public static String today() { return convertDate2String("yyyy-MM-dd"); } /** * 往后多少天 * * @param field 日期类型 * @param days 天数 * @return 时间字符串 */ private static String add(int field, int days) { Calendar cal = getCalendar(); cal.add(field, days); return convertDate2String(cal.getTime()); } /** * 获取当前年份 * * @return 当前年份 */ public static int year() { return getCalendar().get(Calendar.YEAR); } /** * 获取指定日期年份 * * @param date 日期 * @return 当前年份 */ public static int year(Date date) { return getCalendar(date).get(Calendar.YEAR); } /** * 获取当前月份 * * @return 当前月份 */ public static int month() { return getCalendar().get(Calendar.MONTH) + 1; } /** * 获取指定日期月份 * * @param date 日期 * @return 当前月份 */ public static int month(Date date) { return getCalendar(date).get(Calendar.MONTH) + 1; } /** * 获取当前日 * * @return 当前日 */ public static int day() { return getCalendar().get(Calendar.DATE); } /** * 获取指定日期月份 * * @param date 日期 * @return 当前日 */ public static int day(Date date) { return getCalendar(date).get(Calendar.DATE); } /** * 获取今天是这个月第几天,即几号了 * * @return 几号 */ public static int dayInMonth() { return getCalendar().get(Calendar.DAY_OF_MONTH); } /** * 获取指定日期这个月第几天,即几号了 * * @param date 日期 * @return 几号 */ public static int dayInMonth(Date date) { return getCalendar(date).get(Calendar.DAY_OF_MONTH); } /** * 获取今天是星期几 * * @return 星期几 */ public static int week() { return getCalendar().get(Calendar.DAY_OF_WEEK) - 1; } /** * 获取指定日期是星期几 * * @param date 日期 * @return 星期几 */ public static int week(Date date) { return getCalendar(date).get(Calendar.DAY_OF_WEEK) - 1; } /** * 获取这个月是第几周 * * @return 第几周 */ public static int dayOfWeekInMonth() { return getCalendar().get(Calendar.DAY_OF_WEEK_IN_MONTH); } /** * 获取指定日期是第几周 * * @param date 日期 * @return 第几周 */ public static int dayOfWeekInMonth(Date date) { return getCalendar(date).get(Calendar.DAY_OF_WEEK_IN_MONTH); } /** * 获取今天是今年第几天 * * @return 第几天 */ public static int dayInYear() { return getCalendar().get(Calendar.DAY_OF_YEAR); } /** * 获取指定日期是第几天 * * @param date 日期 * @return 第几天 */ public static int dayInYear(Date date) { return getCalendar(date).get(Calendar.DAY_OF_YEAR); } /** * 转换日期格式为yyyy-MM-dd * * @param date 待转换的日期 * @return 日期字符串 */ public static String convertDate2String(Date date) { return convertDate2String(date, DATE_PATTERN); } /** * 转换当前日期为指定的格式 * * @param pattern 格式 * @return 日期字符串 */ public static String convertDate2String(String pattern) { return convertDate2String(new Date(), pattern); } /** * 转换格式为yyyy-mm-dd HH:mm:ss的日期字符串转化为指定格式的字符串 * * @param strDate 待转换的日期,格式为:yyyy-mm-dd HH:mm:ss * @param pattern 结果所需的格式 * @return 字符串 */ public static String convertDate2String(String strDate, String pattern) { return convertDate2String(strDate, DATE_PATTERN, pattern); } /** * 转换格式为yyyy-mm-dd HH:mm:ss的日期字符串转化为指定格式的字符串 * * @param strDate 待转换的日期,格式为:yyyy-mm-dd HH:mm:ss * @param patternSrc 待转日期格式 * @param patternDes 结果所需的格式 * @return 日期字符串 */ public static String convertDate2String(String strDate, String patternSrc, String patternDes) { return convertDate2String(convertString2Date(strDate, patternSrc), patternDes); } /** * 转换日期为指定的格式 * * @param date 待转换的日期对象 * @param pattern 格式 * @return 日期字符串 */ public static String convertDate2String(Date date, String pattern) { SimpleDateFormat df; String returnValue = ""; if (date != null) { df = new SimpleDateFormat(pattern); returnValue = df.format(date); } return returnValue; } /** * 转换yyyy-MM-dd格式的字符串转化为日期 * * @param strDate 待转换的字符串 * @return 日期 */ public static Date convertString2Date(String strDate) { return convertString2Date(strDate, DATE_PATTERN); } /** * 转换指定的格式字符串转化为日期 * * @param strDate 待转换的字符串 * @param pattern 格式 * @return 日期 */ public static Date convertString2Date(String strDate, String pattern) { SimpleDateFormat df; Date date = null; if (strDate != null) { df = new SimpleDateFormat(pattern); try { date = df.parse(strDate); } catch (ParseException e) { e.printStackTrace(); } } return date; } /** * 获取日历 * * @return 日历 */ public static Calendar getCalendar() { return Calendar.getInstance(); } /** * 获取日历 * * @param date 日历 */ public static Calendar getCalendar(Date date) { Calendar c = getCalendar(); c.setTime(date); return c; } /** * 获取日期 * * @return 日期 */ public static Date getDate(int year, int month, int day) { Calendar c = getCalendar(); c.set(Calendar.YEAR, year); c.set(Calendar.MONTH, month); c.set(Calendar.DATE, day); return c.getTime(); } /** * 获取日期绝对差 * * @param d1 日期1 * @param d2 日期2 * @param field Calendar字段,YEAR、MONTH等 * @return 日期差 */ public static long diff(Date d1, Date d2, int field) { long ms = d2.getTime() - d1.getTime(); //如果d2在d1前面 if (getCalendar(d2).before(getCalendar(d1))) { //记录后一个日期 Date d0 = d2; d2 = d1; d1 = d0; } long res = 0; switch (field) { case Calendar.YEAR: Calendar c = getCalendar(d2); //将年设置成相同的 c.set(Calendar.YEAR, year(d1)); //然后比较日期前后关系,如果d0在d1前面,年份-1 res = year(d2) - year(d1) - (c.before(getCalendar(d1)) ? 1 : 0); break; case Calendar.MONTH: int years = year(d2) - year(d1); Calendar c1 = getCalendar(d2); //将年设置成相同的 c1.set(Calendar.YEAR, year(d1)); //然后比较日期前后关系,如果d0在d1前面,月份-1 c1.set(Calendar.MONTH, month(d1) - 1); res = (month(d2) >= month(d1) ? (month(d2) - month(d1)) : (month(d2) + 12 - month(d1)) % 12) + years * 12 - (c1.before(getCalendar(d1)) ? 1 : 0); break; case Calendar.WEEK_OF_YEAR: res = ms / (7 * 24 * 60 * 60 * 1000); break; case Calendar.DATE: res = ms / (24 * 60 * 60 * 1000); break; case Calendar.HOUR: res = ms / (60 * 60 * 1000); break; case Calendar.MINUTE: res = ms / (60 * 1000); break; case Calendar.SECOND: res = ms / (1000); break; case Calendar.MILLISECOND: res = ms; break; default: break; } return res; } /** * 农历 * * @version 1.0 * @date 2015年12月23日 下午1:54:19 */ public static class Lunar { /** * 支持转换的最小农历年份 */ private static int MIN_YEAR = 1900; /** * 支持转换的最大农历年份 */ private static int MAX_YEAR = 2049; /** * 农历信息1900-2099 * 数据结构如下,共使用17位数据 * 第17位:表示闰月天数,0表示29天 1表示30天 * 第16位-第5位(共12位)表示12个月,其中第16位表示第一月,如果该月为30天则为1,29天为0 * 第4位-第1位(共4位)表示闰月是哪个月,如果当年没有闰月,则置0 */ private static long[] LUNAR_INFO = new long[]{0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6, 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0 }; /** * 天干、地支、属相 */ private static String[] GAN = new String[]{"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"}; private static String[] ZHI = new String[]{"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"}; private static String[] ANIMALS = new String[]{"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"}; /** * 月份日期 */ private static String[] CHINESE_TEN = {"初", "十", "廿", "卅"}; private static String[] CHINESE_DAY = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"}; private static String[] CHINESE_MONTH = {"正月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "腊月"}; /** * 获取指定农历年的总天数 * * @param year 年份 * @return 天数 */ public static int days4YearInLunar(int year) { int i, sum = 348; for (i = 0x8000; i > 0x8; i >>= 1) { if ((LUNAR_INFO[year - MIN_YEAR] & i) != 0) { sum += 1; } } return (sum + days4LeapInLunar(year)); } /** * 获取指定农历年闰月的天数 * * @param year 年份 * @return 天数 */ public static int days4LeapInLunar(int year) { if (leapMonth(year) != 0) { if ((LUNAR_INFO[year - MIN_YEAR] & 0x10000) != 0) { return 30; } else { return 29; } } else { return 0; } } /** * 获取指定农历年某月的总天数 * * @param year 年份 * @param month 月份 * @return 天数 */ public static int days4MonthInLunar(int year, int month) { if ((LUNAR_INFO[year - MIN_YEAR] & (0x10000 >> month)) == 0) { return 29; } else { return 30; } } /** * 获取指定农历年闰月月份,没闰月返回 0 * * @param year 年份 * @return 天数 */ public static int leapMonth(int year) { return (int) (LUNAR_INFO[year - MIN_YEAR] & 0xf); } /** * ######################################## * ########### 公历 转 农历计算 ############### * ######################################## * ====================================== 算出农历, 传入日期物件, 传回农历日期物件 * <p> * 该物件属性有 .year .month .day .isLeap .yearCyl .dayCyl .monCyl * * @param date 日期 */ public static String getLunar(Date date) { return getLunar(date, false); } public static String getLunar(Date date, boolean showTGDZ) { // 记录农历日期 int year, month, day; // 记录闰月 int leap; int temp = 0; int yearCyl, monCyl, dayCyl;//天干地支年月日 int i; boolean isLeap = false; // 1900-01-31是农历1900年正月初一 // 获取毫秒数 Date baseDate = getCalendar(convertString2Date("1900-01-31", "yyyy-mm-dd")).getTime(); // 计算当前日期距1900-01-31的天数 // 天数 int offset = (int) ((date.getTime() - baseDate.getTime()) / (24 * 60 * 60 * 1000)); //1899-12-21是农历1899年腊月甲子日 dayCyl = offset + 40; //1898-10-01是农历甲子月 monCyl = 14; // 计算当前日期距1900-01-31的年数 for (i = MIN_YEAR; i <= MAX_YEAR && offset > 0; i++) { // 农历每年天数 temp = days4YearInLunar(i); offset -= temp; monCyl += 12; } if (offset < 0) { offset += temp; i--; monCyl -= 12; } // 记录农历年 year = i; yearCyl = year - MIN_YEAR + 36; // 计算闰哪个月 leap = leapMonth(i); for (i = 1; i <= 12 && offset > 0; i++) { // 是闰月 if (leap > 0 && i == (leap + 1) && !isLeap) { --i; isLeap = true; // 计算农历闰月天数 temp = days4LeapInLunar(year); } else { // 计算农历某月天数 temp = days4MonthInLunar(year, i); } // 解除闰月 if (isLeap && i == (leap + 1)) { isLeap = false; } offset -= temp; if (!isLeap) { monCyl++; } } // 正好是闰月 if (offset == 0 && leap > 0 && i == leap + 1) { if (isLeap) { isLeap = false; } else { isLeap = true; --i; --monCyl; } } if (offset < 0) { offset += temp; --i; --monCyl; } // 农历月份 month = i; // 农历天份 day = offset + 1; return getChinaString(year, month, day, yearCyl, monCyl, dayCyl, isLeap, showTGDZ); } // ######################################## // ########### 生肖、天干、地支 ############### // ######################################## /** * 获取农历 y年的生肖 * * @return 生肖 */ public static String animalsYear(int year) { return ANIMALS[(year - 4) % 12]; } /** * 传入月日的offset 获取干支, 0=甲子 * * @param num 偏移量 * @return 干支 */ public static String animalsCycle(int num) { return (GAN[num % 10] + ZHI[num % 12]); } // ################################################# // ########### 下面是转汉字部分 ############### // ################################################# /** * 农历转汉字 * * @param year 农历年份 * @param month 农历月份 * @param day 农历日 * @param monthCyl 天干地支月份 * @param dayCyl 天干地支日 * @param isLeap 是否是闰月 * @param showTGDZ 是否显示天干地支 * @return 农历 */ private static String getChinaString(int year, int month, int day, int yearCyl, int monthCyl, int dayCyl, boolean isLeap, boolean showTGDZ) { StringBuilder res = new StringBuilder(); //显示天干地支 if (showTGDZ) { res.append(animalsCycle(yearCyl)) .append("年【") .append(getYearInChinese(year)) .append("】") .append((isLeap ? "闰" : "")).append(getMonthInChinese(month)) .append(getDayInChinese(day)) .append("(") .append(animalsCycle(monthCyl)) .append("月 ") .append(animalsCycle(dayCyl)) .append("日") .append(")"); } else { res.append(getYearInChinese(year)) .append((isLeap ? " 闰" : " ")).append(getMonthInChinese(month)) .append(getDayInChinese(day)); } return res.toString(); } /** * 农历月份转汉字 * * @param year 农历年份 * @return 月份 */ private static String getYearInChinese(int year) { if (year <= MIN_YEAR || year > MAX_YEAR) { return "出错"; } return animalsYear(year) + "年"; } /** * 农历月份转汉字 * * @param month 农历月份 * @return 月份 */ private static String getMonthInChinese(int month) { if (month <= 0 || month > 12) { return "出错"; } return CHINESE_MONTH[month - 1]; } /** * 农历日期转汉字 * * @param day 农历日 * @return 日期 */ private static String getDayInChinese(int day) { int n = day % 10 == 0 ? 9 : day % 10 - 1; if (day > 30) { return "出错"; } if (day == 10) { return "初十"; } else { return CHINESE_TEN[day / 10] + CHINESE_DAY[n]; } } } /** * 获取时间戳当天0时0分0秒的时间戳 * * @param timestamp 时间戳 * @return 时间戳 */ public static long getDayFirstTime(long timestamp) { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(timestamp); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); return calendar.getTimeInMillis(); } public static long getDayOfAnyTime(long timestamp, int hour, int minute, int second) { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(timestamp); calendar.set(Calendar.HOUR_OF_DAY, hour); calendar.set(Calendar.MINUTE, minute); calendar.set(Calendar.SECOND, second); return calendar.getTimeInMillis(); } public static String getDayOfTimestamp(long timestamp) { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(timestamp); return new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime()); } public static String getDayOfTimestamp(String timestamp) { return getDayOfTimestamp(new Long(timestamp)); } }