日期處理工具類TimeUtil

具體代碼可直接到GitHub拉取源代碼:https://github.com/bj4096/common-utils

如有更好的建議歡迎大家隨時提交,共同完善

package com.sljl.core.utils;

import com.sljl.core.enums.ConstellationTypeEnum;
import com.sljl.core.enums.ZodiacTypeEnum;
import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 系統(tǒng)通用的時間工具類
 *
 * @author L.Y.F
 */
public class TimeUtil {

    /**
     * 秒(最小單位為秒炼绘,如果需要使用毫秒請自己乘以1000)
     */
    public static final int SECOND = 1;
    /**
     * 分(最小單位為秒,如果需要使用毫秒請自己乘以1000)
     */
    public static final int MINUTE = SECOND * 60;
    /**
     * 時(最小單位為秒,如果需要使用毫秒請自己乘以1000)
     */
    public static final int HOUR = MINUTE * 60;
    /**
     * 天(最小單位為秒蛤售,如果需要使用毫秒請自己乘以1000)
     */
    public static final int DAY = HOUR * 24;
    /**
     * 周(最小單位為秒吐限,如果需要使用毫秒請自己乘以1000)
     */
    public static final int WEEK = DAY * 7;
    /**
     * 月--按照通用的30天計算又固,如需特殊值請另行計算(最小單位為秒怀酷,如果需要使用毫秒請自己乘以1000)
     */
    public static final int MONTH_30 = DAY * 30;
    /**
     * 年--按照通用的365天計算,如需特殊值請另行計算(最小單位為秒崖疤,如果需要使用毫秒請自己乘以1000)
     */
    public static final int YEAR_365 = DAY * 365;

    private final static int[] dayArr = new int[]{20, 19, 21, 20, 21, 22, 23, 23, 23, 24, 23, 22};
    private final static int[] constellationArr = new int[]{10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    private final static int[] zodiacArr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

    /**
     * 將日期按照format格式轉(zhuǎn)換成字符串
     *
     * @param date
     * @param format
     *
     * @return
     */
    public static String date2String(Date date, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    /**
     * 將字符串按照format格式轉(zhuǎn)換成日期類型
     *
     * @param date
     * @param format
     *
     * @return
     *
     * @throws ParseException
     */
    public static Date string2Date(String date, String format) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.parse(date);
    }

    /**
     * 將指定的字符串日期格式轉(zhuǎn)換成其他形式的日期字符串
     *
     * @param date 日期字符串
     * @param sourceFormat 原日期字符串格式
     * @param toFormat 新日期字符串格式
     *
     * @return
     *
     * @throws ParseException
     */
    public static String stringDateToFormat(String date, String sourceFormat, String toFormat) throws ParseException {
        Date sourceDate = new SimpleDateFormat(sourceFormat).parse(date);
        return new SimpleDateFormat(toFormat).format(sourceDate);
    }

    /**
     * 獲取當(dāng)前時間戳的毫秒值
     *
     * @return
     */
    public static long getTimestamp() {
        return Calendar.getInstance().getTimeInMillis();
    }

    /**
     * 返回指定格式的當(dāng)前日期
     *
     * @param format
     *
     * @return
     */
    public static String getNow(String format) {
        return date2String(new Date(), format);
    }

    /**
     * 獲取以指定時間為基準(zhǔn)的前后N天的日期
     *
     * @param date: 指定日期
     * @param days:days > 0 = 未來時間秘车、days < 0 = 歷史時間、days == 0 = 當(dāng)前時間
     *
     * @return
     */
    public static Date dateForBeforeOrAfter(Date date, int days) {
        // 使用默認時區(qū)和語言環(huán)境獲得一個日歷劫哼。
        Calendar cal = Calendar.getInstance();
        if (null != date) {
            cal.setTime(date);
        }
        cal.add(Calendar.DAY_OF_YEAR, +days);
        return cal.getTime();
    }

    /**
     * 將毫秒值轉(zhuǎn)換成指定format格式的日期
     *
     * @param millSeconds
     *
     * @return
     */
    public static String millisecond2String(long millSeconds, String format) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(millSeconds);
        return date2String(cal.getTime(), format);
    }


    /**
     * 獲取以當(dāng)前天為基準(zhǔn)的前/后第N天的23:59:59的時間戳值叮趴,如需UnixTime請自行 / 1000
     *
     * @param days:days > 0 = 未來時間、days < 0 = 歷史時間权烧、days == 0 = 當(dāng)前時間
     *
     * @return
     */
    public static long getLastTimeStampForDay(int days) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_YEAR, +days);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime().getTime();
    }

    /**
     * 獲取當(dāng)月最后一天23:59:59的時間戳值眯亦,如需UnixTime請自行 / 1000
     *
     * @return
     */
    public static long getMonthLastDayForTimeStamp() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime().getTime();
    }

    /**
     * 當(dāng)dayOfWeek==0時,獲取指定日期所在周的周一對應(yīng)的日期般码;
     * 在此基礎(chǔ)上通過addDayOfWeek參數(shù)來靈活獲取相關(guān)周的任意周幾的日期妻率;
     * 其思路就是先拿到指定日期所在周的周一對應(yīng)日期,然后通過增減天數(shù)來獲取上周板祝,本周甚至任意周的任意周幾日期宫静;
     * 例如:
     * <pre>
     *     1. 獲取當(dāng)前日期所在周的周一日期:getDayOfWeekForDate(new Date(), 0);
     *     2. 獲取當(dāng)前日期所在周的周三日期;getDayOfWeekForDate(new Date(), 2);
     *     3. 獲取當(dāng)前日期所在周的周日日期;getDayOfWeekForDate(new Date(), 6);
     *     4. 獲取當(dāng)前日期的前一周的周一日期:getDayOfWeekForDate(new Date(), -7);
     *     5. 獲取當(dāng)前日期的前一周的周日日期:getDayOfWeekForDate(new Date(), -1);
     *     6. 獲取當(dāng)前日期的未來一周的周一日期:getDayOfWeekForDate(new Date(), 7);
     * </pre>
     *
     * @param date:指定日期
     * @param addDayOfWeek:指定日期所在周周一的基礎(chǔ)上加幾天或者減幾天的日期
     *
     * @return
     */
    public static Date getDayOfWeekForDate(Date date, int addDayOfWeek) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);
        // 判斷要計算的日期是否是周日孤里,如果是則減一天計算周六的伏伯,否則會出問題,計算到下一周去了
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 獲得當(dāng)前日期是一個星期的第幾天
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        cal.setFirstDayOfWeek(Calendar.MONDAY);// 設(shè)置一個星期的第一天捌袜,按中國的習(xí)慣一個星期的第一天是星期一
        int day = cal.get(Calendar.DAY_OF_WEEK);// 獲得當(dāng)前日期是一個星期的第幾天
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);// 根據(jù)日歷的規(guī)則说搅,給當(dāng)前日期減去星期幾與一個星期第一天的差值
        cal.add(Calendar.DATE, addDayOfWeek);
        return cal.getTime();
    }

    /**
     * 非標(biāo)出生日期格式化方法,轉(zhuǎn)換后統(tǒng)一使用標(biāo)準(zhǔn)格式y(tǒng)yyy-mm-dd
     *
     * @param sourceBirthday:原非標(biāo)出生日期虏等;該非標(biāo)日期要求必須具備年弄唧、月、日霍衫,缺一不可套才; <pre>
     * <ul>
     * 例:
     *  <li>1989年-----------------false</li>
     *  <li>2月26日-----------------false</li>
     *  <li>1980年2月1日-------------true</li>
     *  <li>1988.02.01-------------true</li>
     *  <li>1990/03/3--------------true</li>
     * </ul>
     * </pre>
     *
     * @return
     *
     * @throws Exception
     */
    public static String convertBirthday(String sourceBirthday) throws Exception {
        String targetBirthday = null;
        if (StringUtils.isNotBlank(sourceBirthday)) {
            sourceBirthday = sourceBirthday.replaceAll(" ", "");
            sourceBirthday = sourceBirthday.replaceAll("[生出]", "");
            sourceBirthday = sourceBirthday.replaceAll("號", "日");
            if (sourceBirthday.matches("(\\d{4})[年](\\d{2}|\\d{1})[月](\\d{2}|\\d{1})[日]")) {
                targetBirthday = date2String(string2Date(sourceBirthday, "yyyy年m月d日"), "yyyy-mm-dd");
            } else if (sourceBirthday.matches("(\\d{4})[.](\\d{2}|\\d{1})[.](\\d{2}|\\d{1})")) {
                targetBirthday = date2String(string2Date(sourceBirthday, "yyyy.m.d"), "yyyy-mm-dd");
            } else if (sourceBirthday.matches("(\\d{4})[/](\\d{2}|\\d{1})[/](\\d{2}|\\d{1})")) {
                targetBirthday = date2String(string2Date(sourceBirthday, "yyyy/m/d"), "yyyy-mm-dd");
            } else if (sourceBirthday.matches("(\\d{4})[-](\\d{2}|\\d{1})[-](\\d{2}|\\d{1})")) {
                targetBirthday = date2String(string2Date(sourceBirthday, "yyyy-m-d"), "yyyy-mm-dd");
            } else if (sourceBirthday.matches("(\\d{4})[年](\\d{2}|\\d{1})[月](\\d{2}|\\d{1})")) {
                targetBirthday = date2String(string2Date(sourceBirthday, "yyyy年m月d"), "yyyy-mm-dd");
            } else if (sourceBirthday.matches("\\d{8}")) {
                targetBirthday = date2String(string2Date(sourceBirthday, "yyyymmdd"), "yyyy-mm-dd");
            }
        }
        return targetBirthday;
    }

    /**
     * 通過出生日期的毫秒值計算星座
     *
     * @param birthdayTimestamp
     *
     * @return
     */
    public static ConstellationTypeEnum convertBirthday2Constellation(long birthdayTimestamp) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(birthdayTimestamp);
        // 獲取生日月份,0表示1月份
        int month = cal.get(Calendar.MONTH) + 1;
        // 獲取生日日期
        int day = cal.get(Calendar.DAY_OF_MONTH);
        return ConstellationTypeEnum.getEnum(day < dayArr[month - 1] ? constellationArr[month - 1] : constellationArr[month]);
    }

    /**
     * 通過出生日期的毫秒值計算屬相
     *
     * @param birthdayTimestamp
     *
     * @return
     */
    public static ZodiacTypeEnum convertBirthday2Zodiac(long birthdayTimestamp) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(birthdayTimestamp);
        int startYear = 1900;
        // 獲取生日年份
        int year = cal.get(Calendar.YEAR);
        year = year < 1900 ? 1900 : year;
        return ZodiacTypeEnum.getEnum(zodiacArr[(year - startYear) % zodiacArr.length]);
    }

    /**
     * 獲取今年是哪一年
     *
     * @return
     */
    public static Integer getNowYear() {
        Date date = new Date();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return Integer.valueOf(gc.get(1));
    }

    /**
     * 獲取本月是哪一月
     *
     * @return
     */
    public static int getNowMonth() {
        Date date = new Date();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return gc.get(2) + 1;
    }

    /**
     * 獲取某年某月到某年某月按天的切片日期集合(間隔天數(shù)的集合)
     *
     * @param beginYear
     * @param beginMonth
     * @param endYear
     * @param endMonth
     * @param k
     *
     * @return
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public static List getTimeList(int beginYear, int beginMonth, int endYear, int endMonth, int k) {
        List list = new ArrayList();
        if (beginYear == endYear) {
            for (int j = beginMonth; j <= endMonth; j++) {
                list.add(getTimeList(beginYear, j, k));
            }
        } else {
            {
                for (int j = beginMonth; j < 12; j++) {
                    list.add(getTimeList(beginYear, j, k));
                }
                for (int i = beginYear + 1; i < endYear; i++) {
                    for (int j = 0; j < 12; j++) {
                        list.add(getTimeList(i, j, k));
                    }
                }
                for (int j = 0; j <= endMonth; j++) {
                    list.add(getTimeList(endYear, j, k));
                }
            }
        }
        return list;
    }

    /**
     * 獲取某年某月按天切片日期集合(某個月間隔多少天的日期集合)
     *
     * @param beginYear
     * @param beginMonth
     * @param k
     *
     * @return
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static List getTimeList(int beginYear, int beginMonth, int k) {
        List list = new ArrayList();
        Calendar begincal = new GregorianCalendar(beginYear, beginMonth, 1);
        int max = begincal.getActualMaximum(Calendar.DATE);
        for (int i = 1; i < max; i = i + k) {
            list.add(begincal.getTime());
            begincal.add(Calendar.DATE, k);
        }
        begincal = new GregorianCalendar(beginYear, beginMonth, max);
        list.add(begincal.getTime());
        return list;
    }

    /**
     * 獲取兩個日期中的最大日期
     *
     * @param beginDate
     * @param endDate
     *
     * @return
     */
    public static Date max(Date beginDate, Date endDate) {
        if (beginDate == null) {
            return endDate;
        }
        if (endDate == null) {
            return beginDate;
        }
        if (beginDate.after(endDate)) {
            return beginDate;
        }
        return endDate;
    }

    /**
     * 獲取兩個日期中的最小日期
     *
     * @param beginDate
     * @param endDate
     *
     * @return
     */
    public static Date min(Date beginDate, Date endDate) {
        if (beginDate == null) {
            return endDate;
        }
        if (endDate == null) {
            return beginDate;
        }
        if (beginDate.after(endDate)) {
            return endDate;
        }
        return beginDate;
    }

    /**
     * 計算兩個日期相差/相隔的天數(shù)
     * 相差:date = "yyyy-MM-dd HH:mm:ss"
     * 相隔:date = "yyyy-MM-dd";
     *
     * @param date
     * @param otherDate
     *
     * @return
     */
    public static long calculateTwoDayDifferences(Date date, Date otherDate) {
        return (date.getTime() - otherDate.getTime()) / (DAY * 1000);
    }

    /**
     * 獲取指定日期所在月的第一天
     *
     * @return
     */
    public static Date getMonthFirstDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
        return cal.getTime();
    }

    /**
     * 獲取指定日期所在月的最后一天
     *
     * @return
     */
    public static Date getMonthLastDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        return cal.getTime();
    }

    /**
     * 返回當(dāng)前日期是周幾
     *
     * @param date
     * @return int
     */
    public static int getDayOfWeek(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int dayForWeek = 0;
        if (c.get(Calendar.DAY_OF_WEEK) == 1) {
            dayForWeek = 7;
        } else {
            dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
        }
        return dayForWeek;
    }

}


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末慕淡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子沸毁,更是在濱河造成了極大的恐慌峰髓,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件息尺,死亡現(xiàn)場離奇詭異携兵,居然都是意外死亡,警方通過查閱死者的電腦和手機搂誉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門徐紧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人炭懊,你說我怎么就攤上這事并级。” “怎么了侮腹?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵嘲碧,是天一觀的道長。 經(jīng)常有香客問我父阻,道長愈涩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任加矛,我火速辦了婚禮履婉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘斟览。我一直安慰自己毁腿,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著狸棍,像睡著了一般身害。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上草戈,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天塌鸯,我揣著相機與錄音,去河邊找鬼唐片。 笑死丙猬,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的费韭。 我是一名探鬼主播茧球,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼星持!你這毒婦竟也來了抢埋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤督暂,失蹤者是張志新(化名)和其女友劉穎揪垄,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逻翁,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡饥努,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了八回。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酷愧。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖缠诅,靈堂內(nèi)的尸體忽然破棺而出溶浴,到底是詐尸還是另有隱情,我是刑警寧澤管引,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布戳葵,位于F島的核電站,受9級特大地震影響汉匙,放射性物質(zhì)發(fā)生泄漏拱烁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一噩翠、第九天 我趴在偏房一處隱蔽的房頂上張望戏自。 院中可真熱鬧,春花似錦伤锚、人聲如沸擅笔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽猛们。三九已至念脯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間弯淘,已是汗流浹背绿店。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留庐橙,地道東北人假勿。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像态鳖,于是被迫代替她去往敵國和親转培。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容

  • # Python 資源大全中文版 我想很多程序員應(yīng)該記得 GitHub 上有一個 Awesome - XXX 系列...
    小邁克閱讀 2,996評論 1 3
  • # Awesome Python [![Awesome](https://cdn.rawgit.com/sindr...
    emily_007閱讀 2,213評論 0 3
  • 轉(zhuǎn)眼已是大年初四浆竭,年味漸淡浸须,更篇文權(quán)當(dāng)作記念吧。愿你我安好快樂邦泄。 全文完删窒。點贊的人將會一生平安,多謝支持虎韵,新年快樂...
    青淺梧桐閱讀 2,570評論 41 71
  • 系統(tǒng)環(huán)境:macOS High Sierra 10.13.4 1、安裝 RVM 1.1 開始安裝 curl -L ...
    燈風(fēng)閱讀 4,365評論 0 6
  • 今天姐姐要出發(fā)去上班了缸废,她一大早就起來做早飯包蓝,收拾屋子。下午姐姐打電話回來企量,她也是一次又一次的叮囑要注意身體测萎,蓋好...
    李李拉拉閱讀 147評論 0 1