DateUtil.java 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  1. package com.ym.mec.util.date;
  2. import org.apache.commons.lang.StringUtils;
  3. import java.text.ParseException;
  4. import java.text.SimpleDateFormat;
  5. import java.util.*;
  6. /**
  7. * 与日期、时间操作有关的工具类。
  8. * <p>
  9. * <strong>注意:某些方法会将输入时间转换成格林威治时间,时区默认为东八区。可以通过方法 <code>DateUtil#setTimeZone</code>改变默认时区。 </strong>
  10. * </p>
  11. */
  12. public class DateUtil {
  13. private static final String CHINESE_DATA_FORMAT = "yyyy年MM月dd日 HH:mm:ss";
  14. public static final String DEFAULT_PATTERN = "yyyy-MM-dd";
  15. public static final String DATE_FORMAT_MIN = "yyyy年MM月dd日";
  16. /**
  17. * 默认使用的Locale。默认Locale为 US
  18. */
  19. public static final Locale DEFAULT_LOCALE = Locale.US;
  20. // ~ 静态属性及初始化 /////////////////////////////////////////////
  21. /** 默认的时区,一般是使用东八区。即比标准的格林威治时间快8个小时。 */
  22. public static TimeZone TIME_ZONE = TimeZone.getDefault();
  23. /**
  24. * ISO8601基本日期格式 yyyyMMdd ,如:20021225 代表2002年12月25日。
  25. */
  26. public static final String ISO_DATE_FORMAT = "yyyyMMdd";
  27. /**
  28. * ISO8601扩展日期格式 yyyy-MM-dd ,如:2002-12-25 代表2002年12月25日。
  29. */
  30. public static final String ISO_EXPANDED_DATE_FORMAT = "yyyy-MM-dd";
  31. /**
  32. * ISO8601基本时间格式 HHmmssSSSzzz ,如:143212333-0500 代表西5区,14点32分12秒333毫秒 24小时制
  33. */
  34. public static final String ISO_TIME_FORMAT = "HHmmssSSSzzz";
  35. /**
  36. * ISO8601基本时间格式 HH:mm:ss,SSSzzz ,如:14:32:12,333-0500 代表西5区,14点32分12秒333毫秒 24小时制
  37. */
  38. public static final String ISO_EXPANDED_TIME_FORMAT = "HH:mm:ss,SSSzzz";
  39. /**
  40. * ISO8601基本日期格式 yyyyMMddTHHmmssSSSzzz ,如:20021225T143212333-0500 代表西5区 2002年12月25日 14点32分12秒333毫秒
  41. */
  42. public static final String ISO_DATE_TIME_FORMAT = "yyyyMMdd'T'HHmmssSSSzzz";
  43. /**
  44. * ISO8601基本日期格式 yyyy-MM-ddTHH:mm:ss,SSSzzz ,如:2002-12-25T14:32:12,333-0500 代表西5区 2002年12月25日 14点32分12秒333毫秒
  45. */
  46. public static final String ISO_EXPANDED_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss,SSSzzz";
  47. /**
  48. * 基本时间格式 HHmmss ,如:143212 代表14点32分12秒 24小时制
  49. */
  50. public static final String TIME_FORMAT = "HHmmss";
  51. /**
  52. * 基本时间格式 HH:mm:ss ,如:14:32:12 代表14点32分12秒 24小时制
  53. */
  54. public static final String EXPANDED_TIME_FORMAT = "HH:mm:ss";
  55. /**
  56. * 日期格式 yyyyMMdd HHmmss ,如:20021225 143212 代表 2002年12月25日 14点32分12秒
  57. */
  58. public static final String DATE_TIME_FORMAT = "yyyyMMdd HHmmss";
  59. /**
  60. * 日期格式 yyyy-MM-dd HH:mm:ss ,如:2002-12-25 14:32:12 代表 2002年12月25日 14点32分12秒
  61. */
  62. public static final String EXPANDED_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
  63. /**
  64. * 西方国家的日期格式 MMM dd, yyyy ,如:February 3, 1982 代表1982年2月3日
  65. */
  66. public static final String ENGLISH_DATE = "MMM dd, yyyy";
  67. /**
  68. * 西方国家的时间格式 MMM dd, yyyy H:mm:ss.SSS ,如:February 3, 1982 12:12:12.005 代表1982年2月3日 12点12分12秒5毫秒
  69. */
  70. public static final String ENGLISH_DATE_TIME = "MMM dd, yyyy H:mm:ss.SSS";
  71. /**
  72. * 美国日期格式 yyyy.MM.dd G 'at' HH:mm:ss z ,如:2001.07.04 AD at 12:08:56 PDT 代表2001年7月4日 12点8分56秒
  73. */
  74. public static final String US_DATE_TIME_1 = "yyyy.MM.dd G 'at' HH:mm:ss z";
  75. /**
  76. * 美国日期格式 yyyyy.MMMMM.dd GGG hh:mm aaa ,如:02001.July.04 AD 12:08 PM 代表2001年7月4日 12点8分
  77. */
  78. public static final String US_DATE_TIME_2 = "yyyyy.MMMMM.dd GGG hh:mm aaa";
  79. /**
  80. * 美国日期格式 EEE, d MMM yyyy HH:mm:ss Z ,如:Wed, 4 Jul 2001 12:08:56 -0700 代表2001年7月4日 12点8分56秒 星期三
  81. */
  82. public static final String US_DATE_TIME_3 = "EEE, d MMM yyyy HH:mm:ss Z";
  83. // 第1年1月1日 (格里高利历)
  84. public static final int JAN_1_1_JULIAN_DAY = 1721426;
  85. // 1970年1月1日 (格里高利历)
  86. public static final int EPOCH_JULIAN_DAY = 2440588;
  87. public static final int EPOCH_YEAR = 1970;
  88. // 一周、一天、一小时、一分钟、一秒,换算成毫秒的全局变量。
  89. public static final int ONE_SECOND = 1000;
  90. public static final int ONE_MINUTE = 60 * ONE_SECOND;
  91. public static final int ONE_HOUR = 60 * ONE_MINUTE;
  92. public static final long ONE_DAY = 24 * ONE_HOUR;
  93. public static final long ONE_WEEK = 7 * ONE_DAY;
  94. // ~ 方法 ////////////////////////////////////////////////////////////////
  95. /**
  96. * 设置系统默认的<code>java.util.TimeZone</code>
  97. *
  98. * @param timeZone <code>java.util.TimeZone</code>
  99. */
  100. public static void setTimeZone(TimeZone timeZone) {
  101. TIME_ZONE = timeZone;
  102. }
  103. public static Date toDateTime(String isoDateString) {
  104. return stringToDate(isoDateString, EXPANDED_DATE_TIME_FORMAT);
  105. }
  106. public static Date toDate(String isoDateString) {
  107. return stringToDate(isoDateString, ISO_EXPANDED_DATE_FORMAT);
  108. }
  109. public static Date stringToDate(String isoDateString) {
  110. return stringToDate(isoDateString, EXPANDED_DATE_TIME_FORMAT);
  111. }
  112. public static Date stringToDate(String isoDateString, String pattern) {
  113. if (StringUtils.isBlank(pattern)) {
  114. return null;
  115. // throw new IllegalArgumentException("匹配模式不能为空!");
  116. }
  117. return stringToDate(isoDateString, new SimpleDateFormat(pattern));
  118. }
  119. public static Date stringToDate(String isoDateString, SimpleDateFormat simpleDateFormat) {
  120. if (StringUtils.isBlank(isoDateString)) {
  121. // throw new IllegalArgumentException("日期字符串不能为空!");
  122. return null;
  123. }
  124. try {
  125. return simpleDateFormat.parse(isoDateString);
  126. } catch (ParseException e) {
  127. // throw new RuntimeException(e);
  128. }
  129. return null;
  130. }
  131. public static String getDateTime(Date date) {
  132. return format(date, EXPANDED_DATE_TIME_FORMAT);
  133. }
  134. public static String getDate(Date date) {
  135. return format(date, ISO_EXPANDED_DATE_FORMAT);
  136. }
  137. public static String getDATEFORMAT(Date date) {
  138. return format(date, ISO_DATE_FORMAT);
  139. }
  140. public static String format(Date date, String pattern) {
  141. return format(date, new SimpleDateFormat(pattern));
  142. }
  143. /**
  144. * 将<code>java.util.Date</code>按照给定的模式转换成日期字符串。
  145. *
  146. * @param date <code>java.util.Date</code>
  147. * @param formatter 给定的模式
  148. * @return 转换后的日期字符串
  149. */
  150. public static String getDate(Date date, SimpleDateFormat formatter) {
  151. if (date == null || formatter == null) {
  152. return null;
  153. // throw new RuntimeException("日期和模式不能为空!");
  154. }
  155. formatter.setTimeZone(TIME_ZONE);
  156. return formatter.format(date);
  157. }
  158. /**
  159. * 将<code>java.util.Date</code>按照给定的模式转换成日期字符串。
  160. *
  161. * @param date <code>java.util.Date</code>
  162. * @param formatter 给定的模式
  163. * @return 转换后的日期字符串
  164. */
  165. public static String format(Date date, SimpleDateFormat formatter) {
  166. return getDate(date, formatter);
  167. }
  168. // 获取年份
  169. public static String getYear(Date date) {
  170. return format(date, ISO_EXPANDED_DATE_FORMAT).split("-")[0];
  171. }
  172. // 获取月份
  173. public static String getMonth(Date date) {
  174. return format(date, ISO_EXPANDED_DATE_FORMAT).split("-")[1];
  175. }
  176. // 获取日期
  177. public static String getDay(Date date) {
  178. return format(date, ISO_EXPANDED_DATE_FORMAT).split("-")[2];
  179. }
  180. // 获取时分秒
  181. public static String getTime(Date date) {
  182. return format(date, EXPANDED_DATE_TIME_FORMAT).split(" ")[1];
  183. }
  184. /**
  185. * 确定给定的年份是否为闰年。
  186. *
  187. * <pre>
  188. * </pre>
  189. *
  190. * @param date <code>java.util.Date</code>
  191. * @return True 如果是闰年
  192. */
  193. public static boolean isLeapYear(Date date) {
  194. if (date == null) {
  195. throw new RuntimeException("输入日期不能为空!");
  196. }
  197. GregorianCalendar cal = new GregorianCalendar();
  198. cal.setTime(date);
  199. return cal.isLeapYear(cal.get(Calendar.YEAR));
  200. }
  201. public static int getHour(Date date) {
  202. if (date == null) {
  203. return -1;
  204. }
  205. Calendar calendar = Calendar.getInstance();
  206. calendar.setTime(date);
  207. return calendar.get(Calendar.HOUR_OF_DAY);
  208. }
  209. public static int geMinute(Date date) {
  210. if (date == null) {
  211. return -1;
  212. }
  213. Calendar calendar = Calendar.getInstance();
  214. calendar.setTime(date);
  215. return calendar.get(Calendar.MINUTE);
  216. }
  217. /**
  218. * 根据日历的规则,为给定的日历字段添加或减去指定的时间量。
  219. *
  220. * @param date <code>java.util.Date</code>
  221. * @param field 给定的日历字段
  222. * @param amount 数量
  223. * @return 运算后的 <code>java.util.Date</code>
  224. */
  225. public static Date add(Date date, int field, int amount) {
  226. if (date == null) {
  227. throw new RuntimeException("日期不能为空!");
  228. }
  229. Calendar cal = GregorianCalendar.getInstance(TIME_ZONE);
  230. cal.setTime(date);
  231. cal.add(field, amount);
  232. return cal.getTime();
  233. }
  234. /**
  235. * 增加或减少指定数量的年份。
  236. *
  237. * @param date <code>java.util.Date</code>
  238. * @param amount 数量
  239. * @return 运算后的 <code>java.util.Date</code>
  240. */
  241. public static Date addYears(Date date, int amount) {
  242. return add(date, Calendar.YEAR, amount);
  243. }
  244. /**
  245. * 增加或减少指定数量的月份。
  246. *
  247. * @param date <code>java.util.Date</code>
  248. * @param amount 数量
  249. * @return 运算后的 <code>java.util.Date</code>
  250. */
  251. public static Date addMonths(Date date, int amount) {
  252. return add(date, Calendar.MONTH, amount);
  253. }
  254. /**
  255. * 修改周,时间按周的量增加或减少。
  256. *
  257. * @param date <code>java.util.Date</code>
  258. * @param amount 数量
  259. * @return 运算后的 <code>java.util.Date</code>
  260. */
  261. public static Date addWeeks(Date date, int amount) {
  262. return add(date, Calendar.WEEK_OF_YEAR, amount);
  263. }
  264. /**
  265. * 增加或减少指定数量的日数。
  266. *
  267. * @param date <code>java.util.Date</code>
  268. * @param amount 数量
  269. * @return 运算后的 <code>java.util.Date</code>
  270. */
  271. public static Date addDays(Date date, int amount) {
  272. return add(date, Calendar.DAY_OF_MONTH, amount);
  273. }
  274. /**
  275. * 增加或减少指定数量的小时数。
  276. *
  277. * @param date <code>java.util.Date</code>
  278. * @param amount 数量
  279. * @return 运算后的 <code>java.util.Date</code>
  280. */
  281. public static Date addHours(Date date, int amount) {
  282. return add(date, Calendar.HOUR_OF_DAY, amount);
  283. }
  284. /**
  285. * 增加或减少指定数量的分钟数。
  286. *
  287. * @param date <code>java.util.Date</code>
  288. * @param amount 数量
  289. * @return 运算后的 <code>java.util.Date</code>
  290. */
  291. public static Date addMinutes(Date date, int amount) {
  292. return add(date, Calendar.MINUTE, amount);
  293. }
  294. /**
  295. * 增加或减少指定数量的秒钟数。
  296. *
  297. * @param date <code>java.util.Date</code>
  298. * @param amount 数量
  299. * @return 运算后的 <code>java.util.Date</code>
  300. */
  301. public static Date addSeconds(Date date, int amount) {
  302. return add(date, Calendar.SECOND, amount);
  303. }
  304. /**
  305. * 增加或减少指定数量的毫秒数。
  306. *
  307. * @param date <code>java.util.Date</code>
  308. * @param amount 数量
  309. * @return 运算后的 <code>java.util.Date</code>
  310. */
  311. public static Date addMilliseconds(Date date, int amount) {
  312. return add(date, Calendar.MILLISECOND, amount);
  313. }
  314. /**
  315. * 在给定的日历字段上添加或减去(上/下)单个时间单元,不更改更大的字段。
  316. *
  317. * @param date <code>java.util.Date</code>
  318. * @param field 给定的日历字段
  319. * @param up 添加或减去(上/下)
  320. * @return 运算后的 <code>java.util.Date</code>
  321. */
  322. public static Date roll(Date date, int field, boolean up) {
  323. Calendar cal = GregorianCalendar.getInstance(TIME_ZONE);
  324. cal.setTime(date);
  325. cal.roll(field, up);
  326. return cal.getTime();
  327. }
  328. /**
  329. * 向指定日历字段添加指定(有符号的)时间量,不更改更大的字段。
  330. *
  331. * @param date <code>java.util.Date</code>
  332. * @param field 给定的日历字段
  333. * @param amount 数量
  334. * @return 运算后的 <code>java.util.Date</code>
  335. */
  336. public static Date roll(Date date, int field, int amount) {
  337. Calendar cal = GregorianCalendar.getInstance(TIME_ZONE);
  338. cal.setTime(date);
  339. cal.roll(field, amount);
  340. return cal.getTime();
  341. }
  342. /**
  343. * 将毫秒时间戳转换成格里高利历的日数。日数是只从格里高利历第1年1月1日算起的日数。
  344. *
  345. * @param millis 给定的毫秒时间戳
  346. * @return 格里高利历的日数
  347. */
  348. public static int millisToJulianDay(long millis) {
  349. return EPOCH_JULIAN_DAY - JAN_1_1_JULIAN_DAY + (int) (millis / ONE_DAY);
  350. }
  351. /**
  352. * 将<code>java.util.Date</code>转换成格里高利历的日数。 日数是只从格里高利历第1年1月1日算起的日数。
  353. *
  354. * @param date <code>java.util.Date</code>
  355. * @return 格里高利历的日数
  356. */
  357. public static int dateToJulianDay(Date date) {
  358. return millisToJulianDay(date.getTime());
  359. }
  360. /**
  361. * 计算两个日期之间相差的秒钟数。如果第一个日期在第二个日期之前,则返回正,反之返回负。
  362. *
  363. * @param early 第一个日期
  364. * @param late 第二个日期
  365. * @return 两个日期之间相差的秒钟数
  366. */
  367. public static int secondsBetween(Date early, Date late) {
  368. return (int) ((late.getTime() / ONE_SECOND) - (early.getTime() / ONE_SECOND));
  369. }
  370. /**
  371. * 计算两个日期之间相差的分钟数。如果第一个日期在第二个日期之前,则返回正,反之返回负。
  372. *
  373. * @param early 第一个日期
  374. * @param late 第二个日期
  375. * @return 两个日期之间相差的分钟数
  376. */
  377. public static int minutesBetween(Date early, Date late) {
  378. Calendar c1 = Calendar.getInstance();
  379. Calendar c2 = Calendar.getInstance();
  380. c1.setTime(early);
  381. c2.setTime(late);
  382. return (int) ((late.getTime() / ONE_MINUTE) - (early.getTime() / ONE_MINUTE));
  383. }
  384. /**
  385. * 计算两个日期之间相差的小时数。如果第一个日期在第二个日期之前,则返回正,反之返回负。
  386. *
  387. * @param early 第一个日期
  388. * @param late 第二个日期
  389. * @return 两个日期之间相差的小时数
  390. */
  391. public static int hoursBetween(Date early, Date late) {
  392. return (int) ((late.getTime() / ONE_HOUR) - (early.getTime() / ONE_HOUR));
  393. }
  394. /**
  395. * 计算两个日期之间相差的天数。如果第一个日期在第二个日期之前,则返回正,反之返回负。
  396. *
  397. * @param early 第一个日期
  398. * @param late 第二个日期
  399. * @return 两个日期之间相差的天数
  400. */
  401. public static int daysBetween(Date early, Date late) {
  402. Calendar c1 = Calendar.getInstance();
  403. Calendar c2 = Calendar.getInstance();
  404. c1.setTime(early);
  405. c2.setTime(late);
  406. return dateToJulianDay(c2.getTime()) - dateToJulianDay(c1.getTime());
  407. }
  408. /**
  409. * 计算两个日期之间相差的月数。如果第一个日期在第二个日期之前,则返回正,反之返回负。
  410. *
  411. * @param early 第一个日期
  412. * @param late 第二个日期
  413. * @return 两个日期之间相差的月数
  414. */
  415. public static int monthsBetween(Date early, Date late) {
  416. Calendar c1 = Calendar.getInstance();
  417. Calendar c2 = Calendar.getInstance();
  418. c1.setTime(early);
  419. c2.setTime(late);
  420. return ((c2.get(Calendar.YEAR) * 12) + c2.get(Calendar.MONTH)) - ((c1.get(Calendar.YEAR) * 12) + c1.get(Calendar.MONTH));
  421. }
  422. /**
  423. * 计算两个日期之间相差的年数。如果第一个日期在第二个日期之前,则返回正,反之返回负。
  424. *
  425. * @param early 第一个日期
  426. * @param late 第二个日期
  427. * @return 两个日期之间相差的年数
  428. */
  429. public static int yearsBetween(Date early, Date late) {
  430. Calendar c1 = Calendar.getInstance();
  431. Calendar c2 = Calendar.getInstance();
  432. c1.setTime(early);
  433. c2.setTime(late);
  434. return c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
  435. }
  436. /**
  437. * 将格里高利历日数转换成 <code>java.sql.Date</code>
  438. *
  439. * @param julian 格里高利历日数
  440. * @return <code>java.sql.Date</code>
  441. */
  442. public static java.sql.Date julianDayToSqlDate(long julian) {
  443. return new java.sql.Date(julianDayToMillis(julian));
  444. }
  445. /**
  446. * 将格里高利历日数转换成 <code>java.util.Date</code>
  447. *
  448. * @param julian 格里高利历日数
  449. * @return <code>java.util.Date</code>
  450. */
  451. public static Date julianDayToDate(long julian) {
  452. return new Date(julianDayToMillis(julian));
  453. }
  454. /**
  455. * 将格里高利历日数转换成毫秒时间戳。
  456. *
  457. * @param julian 格里高利历日数
  458. * @return 毫秒时间戳
  459. */
  460. public static long julianDayToMillis(long julian) {
  461. return (julian - EPOCH_JULIAN_DAY + JAN_1_1_JULIAN_DAY) * ONE_DAY;
  462. }
  463. /**
  464. * 将日历转换成儒略历日期。算法参见: <a href="http://quasar.as.utexas.edu/BillInfo/JulianDatesG.html">Julian Day Calculations
  465. * (Gregorian Calendar)</a>, 由 Bill Jeffrys 提供。
  466. *
  467. * @param c 日历实例
  468. * @return 儒略历日期
  469. */
  470. public static float toJulian(Calendar c) {
  471. int Y = c.get(Calendar.YEAR);
  472. int M = c.get(Calendar.MONTH);
  473. int D = c.get(Calendar.DATE);
  474. int A = Y / 100;
  475. int B = A / 4;
  476. int C = 2 - A + B;
  477. float E = (int) (365.25f * (Y + 4716));
  478. float F = (int) (30.6001f * (M + 1));
  479. float JD = (C + D + E + F) - 1524.5f;
  480. return JD;
  481. }
  482. /**
  483. * 将日期转换成儒略历日期。算法参见: <a href="http://quasar.as.utexas.edu/BillInfo/JulianDatesG.html">Julian Day Calculations
  484. * (Gregorian Calendar)</a>, 由 Bill Jeffrys 提供。
  485. *
  486. * @param date 日期
  487. * @return 儒略历日期
  488. */
  489. public static float toJulian(Date date) {
  490. Calendar c = Calendar.getInstance();
  491. c.setTime(date);
  492. return toJulian(c);
  493. }
  494. protected static float normalizedJulian(float JD) {
  495. float f = Math.round(JD + 0.5f) - 0.5f;
  496. return f;
  497. }
  498. /**
  499. * 给定此 <code>java.util.Date</code> 的时间值,返回指定日历字段可能拥有的最大值。
  500. *
  501. * @param date <code>java.util.Date</code>
  502. * @param field 日历字段
  503. * @return 对于此 <code>java.util.Date</code> 的时间值而言,给定日历字段的最大值
  504. */
  505. public static Date getActualMaximum(Date date, int field) {
  506. Calendar c = Calendar.getInstance();
  507. c.setTime(date);
  508. c.set(field, c.getActualMaximum(field));
  509. return c.getTime();
  510. }
  511. /**
  512. * 给定此 <code>java.util.Date</code> 的时间值,返回指定日历字段可能拥有的最小值。
  513. *
  514. * @param date <code>java.util.Date</code>
  515. * @param field 日历字段
  516. * @return 对于此 <code>java.util.Date</code> 的时间值而言,给定日历字段的最小值
  517. */
  518. public static Date getActualMinimum(Date date, int field) {
  519. Calendar c = Calendar.getInstance();
  520. c.setTime(date);
  521. c.set(field, c.getActualMinimum(field));
  522. return c.getTime();
  523. }
  524. /**
  525. * 截取日期,只保留年、月、日部分。
  526. *
  527. * @param date <code>java.util.Date</code>
  528. * @return 截取后的<code>java.util.Date</code>
  529. */
  530. public static Date trunc(Date date) {
  531. if (date != null) {
  532. Calendar c1 = Calendar.getInstance();
  533. c1.setTime(date);
  534. Calendar c2 = (Calendar) c1.clone();
  535. c1.clear();
  536. c1.set(Calendar.YEAR, c2.get(Calendar.YEAR));
  537. c1.set(Calendar.MONTH, c2.get(Calendar.MONTH));
  538. c1.set(Calendar.DAY_OF_MONTH, c2.get(Calendar.DAY_OF_MONTH));
  539. return c1.getTime();
  540. }
  541. return null;
  542. }
  543. /**
  544. * 返回当天的最后一秒
  545. *
  546. * @param date <code>java.util.Date</code>
  547. * @return 截取后的<code>java.util.Date</code>
  548. */
  549. public static Date dayEnd(Date date) {
  550. Calendar c1 = Calendar.getInstance();
  551. c1.setTime(date);
  552. Calendar c2 = (Calendar) c1.clone();
  553. c1.clear();
  554. c1.set(Calendar.YEAR, c2.get(Calendar.YEAR));
  555. c1.set(Calendar.MONTH, c2.get(Calendar.MONTH));
  556. c1.set(Calendar.DAY_OF_MONTH, c2.get(Calendar.DAY_OF_MONTH));
  557. // 23:59:59
  558. c1.set(Calendar.HOUR_OF_DAY, 23);
  559. c1.set(Calendar.MINUTE, 59);
  560. c1.set(Calendar.SECOND, 59);
  561. return c1.getTime();
  562. }
  563. /**
  564. * 判断两个日期是否是同一天,精确到天。
  565. *
  566. * @param date1 <code>java.util.Date</code>
  567. * @param date2 <code>java.util.Date</code>
  568. * @return true 如果两个日期是同一天
  569. */
  570. public static boolean isSameDay(Date date1, Date date2) {
  571. if (date1 == null || date2 == null) {
  572. throw new RuntimeException("日期不能为空!");
  573. }
  574. Calendar cal1 = Calendar.getInstance();
  575. cal1.setTime(date1);
  576. Calendar cal2 = Calendar.getInstance();
  577. cal2.setTime(date2);
  578. return isSameDay(cal1, cal2);
  579. }
  580. /**
  581. * 判断两个日期是否是同一天,精确到天。
  582. *
  583. * @param cal1 <code>java.util.Calendar</code>
  584. * @param cal2 <code>java.util.Calendar</code>
  585. * @return true 如果两个日期是同一天
  586. */
  587. public static boolean isSameDay(Calendar cal1, Calendar cal2) {
  588. if (cal1 == null || cal2 == null) {
  589. throw new RuntimeException("日期不能为空!");
  590. }
  591. return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) && cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) && cal1.get(Calendar.DAY_OF_YEAR) == cal2
  592. .get(Calendar.DAY_OF_YEAR));
  593. }
  594. /**
  595. * 判断两个时间是否完全相等,精确到毫秒。
  596. *
  597. * @param date1 <code>java.util.Date</code>
  598. * @param date2 <code>java.util.Date</code>
  599. * @return true 如果两个时间完全相等
  600. */
  601. public static boolean isSameLocalTime(Date date1, Date date2) {
  602. if (date1 == null || date2 == null) {
  603. throw new RuntimeException("日期不能为空!");
  604. }
  605. Calendar cal1 = Calendar.getInstance();
  606. cal1.setTime(date1);
  607. Calendar cal2 = Calendar.getInstance();
  608. cal2.setTime(date2);
  609. return isSameLocalTime(cal1, cal2);
  610. }
  611. /**
  612. * 判断两个时间是否完全相等,精确到毫秒。
  613. *
  614. * @param cal1 <code>java.util.Calendar</code>
  615. * @param cal2 <code>java.util.Calendar</code>
  616. * @return true 如果两个时间完全相等
  617. */
  618. public static boolean isSameLocalTime(Calendar cal1, Calendar cal2) {
  619. if (cal1 == null || cal2 == null) {
  620. throw new RuntimeException("日期不能为空!");
  621. }
  622. return (cal1.get(Calendar.MILLISECOND) == cal2.get(Calendar.MILLISECOND) && cal1.get(Calendar.SECOND) == cal2.get(Calendar.SECOND)
  623. && cal1.get(Calendar.MINUTE) == cal2.get(Calendar.MINUTE) && cal1.get(Calendar.HOUR) == cal2.get(Calendar.HOUR)
  624. && cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR) && cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)
  625. && cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) && cal1.getClass() == cal2.getClass());
  626. }
  627. public static String formatHuman(Date date) {
  628. if (date != null) {
  629. Long seconds = (System.currentTimeMillis() - date.getTime()) / 1000;
  630. if (seconds <= 0) {
  631. return "刚刚";
  632. }
  633. if (seconds < 60) {
  634. return seconds + "秒前";
  635. }
  636. Long min = seconds / 60;
  637. if (min < 60) {
  638. return min + "分钟前";
  639. }
  640. Long hour = seconds / 3600;
  641. if (hour < 12) {
  642. return hour + "小时前";
  643. }
  644. return format(date, "yyyy-MM-dd HH:mm:ss");
  645. } else {
  646. return "";
  647. }
  648. }
  649. public static String formatHumanShort(Date date) {
  650. Long seconds = (System.currentTimeMillis() - date.getTime()) / 1000;
  651. if (seconds <= 0) {
  652. return "刚刚";
  653. }
  654. if (seconds < 60) {
  655. return seconds + "秒前";
  656. }
  657. Long min = seconds / 60;
  658. if (min < 60) {
  659. return min + "分钟前";
  660. }
  661. Long hour = seconds / 3600;
  662. if (hour < 12) {
  663. return hour + "小时前";
  664. }
  665. return format(date, "yyyy-MM-dd");
  666. }
  667. /**
  668. * 解析毫秒时间格式
  669. *
  670. * @param millis
  671. * @return
  672. */
  673. public static Date parseMillis(Long millis) {
  674. Calendar calendar = Calendar.getInstance();
  675. calendar.setTimeInMillis(millis);
  676. return calendar.getTime();
  677. }
  678. /**
  679. * 返回date所在月的第一天
  680. *
  681. * @return
  682. */
  683. public static Date getFirstDayOfMonth(Date date) {
  684. String str = DateUtil.getYear(date) + "-" + DateUtil.getMonth(date) + "-01";
  685. return DateUtil.stringToDate(str, DateUtil.ISO_EXPANDED_DATE_FORMAT);
  686. }
  687. // 取最近的时间
  688. public static Date getMaxDate(Date lastDate, Date newDate) {
  689. if (lastDate != null && newDate != null) {
  690. if (newDate.after(lastDate)) {
  691. return newDate;
  692. } else {
  693. return lastDate;
  694. }
  695. } else if (lastDate != null) {
  696. return lastDate;
  697. } else {
  698. return newDate;
  699. }
  700. }
  701. // 取最老的时间
  702. public static Date getMinDate(Date lastDate, Date newDate) {
  703. if (lastDate != null && newDate != null) {
  704. if (newDate.before(lastDate)) {
  705. return newDate;
  706. } else {
  707. return lastDate;
  708. }
  709. } else if (lastDate != null) {
  710. return lastDate;
  711. } else {
  712. return newDate;
  713. }
  714. }
  715. /**
  716. * 将字符串转换为指定格式的日期
  717. *
  718. * @param dateStr
  719. * @param pattern
  720. * @return
  721. */
  722. public static Date strToDate(String dateStr, String pattern) {
  723. Date date = null;
  724. try {
  725. SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern, DEFAULT_LOCALE);
  726. date = simpleDateFormat.parse(dateStr);
  727. } catch (ParseException e) {
  728. e.printStackTrace();
  729. }
  730. return date; // null if parse faile
  731. }
  732. /**
  733. * 时间转字符串
  734. * @param date
  735. * @return
  736. */
  737. public static String dateToString(Date date) {
  738. SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
  739. return df.format(date);
  740. }
  741. /**
  742. * 时间转字符串
  743. * @param date
  744. * @return
  745. */
  746. public static String dateToString(Date date, SimpleDateFormat df) {
  747. return df.format(date);
  748. }
  749. /**
  750. * 时间转字符串
  751. * @param date
  752. * @return
  753. */
  754. public static String dateToString(Date date, String format) {
  755. SimpleDateFormat df = new SimpleDateFormat(format);
  756. return df.format(date);
  757. }
  758. /**
  759. * @describe 获取时间段内对应星期数的集合
  760. * @author Joburgess
  761. * @date 2019/10/25
  762. * @param startTime 开始时间
  763. * @param endTime 结束时间
  764. * @param weekNum 周几
  765. * @return java.util.List<java.util.Date>
  766. */
  767. public static List<Date> getWeekDays(Date startTime, Date endTime, int weekNum){
  768. Calendar calendar = Calendar.getInstance();
  769. List<Date> dates=new ArrayList<>();
  770. for(Date x = startTime; x.compareTo(endTime) <= 0;){
  771. calendar.setTime(x);
  772. calendar.add(Calendar.DATE, 1);
  773. x = calendar.getTime();
  774. if(calendar.get(Calendar.DAY_OF_WEEK) == weekNum){
  775. dates.add(x);
  776. }
  777. }
  778. return dates;
  779. }
  780. /**
  781. * @describe 根据日期获取所在周的周一
  782. * @author Joburgess
  783. * @date 2019/10/25
  784. * @param date: 日期
  785. * @return java.util.Date
  786. */
  787. public static Date getWeekMondayWithDate(Date date) {
  788. Calendar cal = Calendar.getInstance();
  789. try {
  790. date=new SimpleDateFormat(DEFAULT_PATTERN).parse(new SimpleDateFormat(DEFAULT_PATTERN).format(date));
  791. } catch (ParseException e) {
  792. e.printStackTrace();
  793. }
  794. cal.setTime(date);
  795. int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
  796. if (1 == dayWeek) {
  797. cal.add(Calendar.DAY_OF_MONTH, -1);
  798. }
  799. cal.setFirstDayOfWeek(Calendar.MONDAY);
  800. int day = cal.get(Calendar.DAY_OF_WEEK);
  801. cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
  802. return cal.getTime();
  803. }
  804. /**
  805. * @describe 根据日期获取所在周获取下周一的时间
  806. * @author Joburgess
  807. * @date 2019/10/25
  808. * @param date:
  809. * @return java.util.Date
  810. */
  811. public static Date getNextWeekMonday(Date date) {
  812. Calendar cal = Calendar.getInstance();
  813. cal.setTime(getWeekMondayWithDate(date));
  814. cal.add(Calendar.DATE, 7);
  815. return cal.getTime();
  816. }
  817. /**
  818. * @describe 根据日期获取所在周获取下周日的时间
  819. * @author Joburgess
  820. * @date 2019/10/25
  821. * @param date:
  822. * @return java.util.Date
  823. */
  824. public static Date getNextWeekSunday(Date date) {
  825. Calendar cal = Calendar.getInstance();
  826. cal.setTime(getWeekMondayWithDate(date));
  827. cal.add(Calendar.DATE, 13);
  828. return cal.getTime();
  829. }
  830. /**
  831. * @describe 在指定时间上加上指定天数,忽略时分秒
  832. * @author Joburgess
  833. * @date 2019/10/30
  834. * @param date: 日期
  835. * @param days: 天数
  836. * @return java.util.Date
  837. */
  838. public static Date addDays1(Date date,int days) {
  839. Calendar cal = Calendar.getInstance();
  840. cal.setTime(getWeekMondayWithDate(date));
  841. cal.add(Calendar.DATE, days);
  842. return cal.getTime();
  843. }
  844. /**
  845. * 时间转换为中文格式
  846. * @param date
  847. * @return
  848. */
  849. public static String date2ChineseDate(Date date){
  850. return new SimpleDateFormat(CHINESE_DATA_FORMAT).format(date);
  851. }
  852. /**
  853. * @describe 判断多个时间区段是否存在重叠
  854. * @author Joburgess
  855. * @date 2019/10/27
  856. * @param dateZones:
  857. * @return boolean
  858. */
  859. public static boolean checkDateZoneOverlap(List<DateZone> dateZones){
  860. dateZones.sort(Comparator.comparing(DateZone::getStartTime));
  861. if(dateZones.size()<=1){
  862. return false;
  863. }else{
  864. for (int i=0;i<dateZones.size()-1;i++){
  865. if(dateZones.get(i+1).getStartTime().before(dateZones.get(i).getEndTime())){
  866. return true;
  867. }
  868. }
  869. }
  870. return false;
  871. }
  872. /**
  873. * @describe 时间区段辅助类
  874. * @author Joburgess
  875. * @date 2019/10/27
  876. * @return
  877. */
  878. public static class DateZone{
  879. private Date startTime;
  880. private Date endTime;
  881. public DateZone() {
  882. }
  883. public DateZone(Date startTime, Date endTime) {
  884. this.startTime = startTime;
  885. this.endTime = endTime;
  886. }
  887. public Date getStartTime() {
  888. return startTime;
  889. }
  890. public void setStartTime(Date startTime) {
  891. this.startTime = startTime;
  892. }
  893. public Date getEndTime() {
  894. return endTime;
  895. }
  896. public void setEndTime(Date endTime) {
  897. this.endTime = endTime;
  898. }
  899. }
  900. /**
  901. * @describe 时间转换为星期数
  902. * @author Joburgess
  903. * @date 2019/10/28
  904. * @param date: 日期
  905. * @return java.lang.String
  906. */
  907. public static String date2Week(Date date) {
  908. Calendar calendar = Calendar.getInstance();
  909. calendar.setTime(date);
  910. int i = calendar.get(Calendar.DAY_OF_WEEK);
  911. switch (i) {
  912. case 1:
  913. return "星期日";
  914. case 2:
  915. return "星期一";
  916. case 3:
  917. return "星期二";
  918. case 4:
  919. return "星期三";
  920. case 5:
  921. return "星期四";
  922. case 6:
  923. return "星期五";
  924. case 7:
  925. return "星期六";
  926. default:
  927. return "";
  928. }
  929. }
  930. public static void main(String[] args) throws ParseException {
  931. // DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
  932. // DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  933. // System.out.println(daysBetween(df.parse("2017-07-20 10:07:42"), df.parse(df.format(new Date()))));
  934. System.out.println(getWeekMondayWithDate(new Date()));
  935. System.out.println(getNextWeekMonday(new Date()));
  936. System.out.println(getNextWeekSunday(new Date()));
  937. System.out.println(dayEnd(new Date()));
  938. }
  939. }