001/** 002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package io.jboot.utils; 017 018import com.jfinal.kit.SyncWriteMap; 019 020import java.sql.Timestamp; 021import java.text.ParseException; 022import java.text.SimpleDateFormat; 023import java.time.*; 024import java.time.format.DateTimeFormatter; 025import java.util.*; 026 027/** 028 * @author michael yang (fuhai999@gmail.com) 029 */ 030public class DateUtil { 031 032 public static String datePatternWithoutDividing = "yyyyMMdd"; 033 public static String datePattern = "yyyy-MM-dd"; 034 public static final String dateMinutePattern = "yyyy-MM-dd HH:mm"; 035 public static final String dateMinutePattern2 = "yyyy-MM-dd'T'HH:mm"; 036 public static String datetimePattern = "yyyy-MM-dd HH:mm:ss"; 037 public static final String dateMillisecondPattern = "yyyy-MM-dd HH:mm:ss SSS"; 038 public static final String dateCSTPattern = "EEE MMM dd HH:mm:ss zzz yyyy"; 039 040 public static String dateChinesePattern = "yyyy年MM月dd日"; 041 public static String datetimeChinesePattern = "yyyy年MM月dd日 HH时mm分ss秒"; 042 043 private static final String[] WEEKS = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"}; 044 045 private static final ThreadLocal<HashMap<String, SimpleDateFormat>> TL = ThreadLocal.withInitial(() -> new HashMap<>()); 046 047 private static final Map<String, DateTimeFormatter> dateTimeFormatters = new SyncWriteMap<>(); 048 049 public static DateTimeFormatter getDateTimeFormatter(String pattern) { 050 DateTimeFormatter ret = dateTimeFormatters.get(pattern); 051 if (ret == null) { 052 ret = DateTimeFormatter.ofPattern(pattern); 053 dateTimeFormatters.put(pattern, ret); 054 } 055 return ret; 056 } 057 058 public static SimpleDateFormat getSimpleDateFormat(String pattern) { 059 SimpleDateFormat ret = TL.get().get(pattern); 060 if (ret == null) { 061 if (dateCSTPattern.equals(pattern)) { 062 ret = new SimpleDateFormat(dateCSTPattern, Locale.US); 063 } else { 064 ret = new SimpleDateFormat(pattern); 065 } 066 TL.get().put(pattern, ret); 067 } 068 return ret; 069 } 070 071 072 public static String toDateString(Date date) { 073 return toString(date, datePattern); 074 } 075 076 077 public static String toDateMinuteString(Date date) { 078 return toString(date, dateMinutePattern); 079 } 080 081 public static String toDateTimeString(Date date) { 082 return toString(date, datetimePattern); 083 } 084 085 086 public static String toDateMillisecondString(Date date) { 087 return toString(date, dateMillisecondPattern); 088 } 089 090 091 public static String toString(Date date, String pattern) { 092 return date == null ? null : getSimpleDateFormat(pattern).format(date); 093 } 094 095 096 public static String toString(LocalDateTime localDateTime, String pattern) { 097 return localDateTime.format(getDateTimeFormatter(pattern)); 098 } 099 100 public static String toString(LocalDate localDate, String pattern) { 101 return localDate.format(getDateTimeFormatter(pattern)); 102 } 103 104 public static String toString(LocalTime localTime, String pattern) { 105 return localTime.format(getDateTimeFormatter(pattern)); 106 } 107 108 109 public static Date parseDate(Object value) { 110 if (value instanceof Number) { 111 return new Date(((Number) value).longValue()); 112 } 113 if (value instanceof Timestamp) { 114 return new Date(((Timestamp) value).getTime()); 115 } 116 if (value instanceof LocalDate) { 117 return DateUtil.toDate((LocalDate) value); 118 } 119 if (value instanceof LocalDateTime) { 120 return DateUtil.toDate((LocalDateTime) value); 121 } 122 if (value instanceof LocalTime) { 123 return DateUtil.toDate((LocalTime) value); 124 } 125 String s = value.toString(); 126 if (StrUtil.isNumeric(s)) { 127 return new Date(Long.parseLong(s)); 128 } 129 return DateUtil.parseDate(s); 130 } 131 132 133 public static Date parseDate(String dateString) { 134 if (StrUtil.isBlank(dateString)) { 135 return null; 136 } 137 dateString = dateString.trim(); 138 try { 139 SimpleDateFormat sdf = getSimpleDateFormat(getPattern(dateString)); 140 try { 141 return sdf.parse(dateString); 142 } catch (ParseException ex) { 143 //2022-10-23 00:00:00.0 144 int lastIndexOf = dateString.lastIndexOf("."); 145 if (lastIndexOf == 19) { 146 return parseDate(dateString.substring(0, lastIndexOf)); 147 } 148 149 //2022-10-23 00:00:00,0 150 lastIndexOf = dateString.lastIndexOf(","); 151 if (lastIndexOf == 19) { 152 return parseDate(dateString.substring(0, lastIndexOf)); 153 } 154 155 //2022-10-23 00:00:00 000123 156 lastIndexOf = dateString.lastIndexOf(" "); 157 if (lastIndexOf == 19) { 158 return parseDate(dateString.substring(0, lastIndexOf)); 159 } 160 161 if (dateString.contains(".") || dateString.contains("/")) { 162 dateString = dateString.replace(".", "-").replace("/", "-"); 163 return sdf.parse(dateString); 164 } else { 165 throw ex; 166 } 167 } 168 } catch (ParseException ex) { 169 throw new IllegalArgumentException("The date format is not supported for the date string: " + dateString); 170 } 171 } 172 173 174 private static String getPattern(String dateString) { 175 int length = dateString.length(); 176 if (length == datetimePattern.length()) { 177 return datetimePattern; 178 } else if (length == datePattern.length()) { 179 return datePattern; 180 } else if (length == dateMinutePattern.length()) { 181 if (dateString.contains("T")) { 182 return dateMinutePattern2; 183 } 184 return dateMinutePattern; 185 } else if (length == dateMillisecondPattern.length()) { 186 return dateMillisecondPattern; 187 } else if (length == datePatternWithoutDividing.length()) { 188 return datePatternWithoutDividing; 189 } else if (length == dateCSTPattern.length()) { 190 return dateCSTPattern; 191 } else { 192 throw new IllegalArgumentException("The date format is not supported for the date string: " + dateString); 193 } 194 } 195 196 197 public static Date parseDate(String dateString, String pattern) { 198 if (StrUtil.isBlank(dateString)) { 199 return null; 200 } 201 try { 202 return getSimpleDateFormat(pattern).parse(dateString.trim()); 203 } catch (ParseException e) { 204 throw new IllegalArgumentException("The date format is not supported for the date string: " + dateString); 205 } 206 } 207 208 209 public static LocalDateTime parseLocalDateTime(String localDateTimeString, String pattern) { 210 return LocalDateTime.parse(localDateTimeString, getDateTimeFormatter(pattern)); 211 } 212 213 public static LocalDate parseLocalDate(String localDateString, String pattern) { 214 return LocalDate.parse(localDateString, getDateTimeFormatter(pattern)); 215 } 216 217 218 public static LocalTime parseLocalTime(String localTimeString, String pattern) { 219 return LocalTime.parse(localTimeString, getDateTimeFormatter(pattern)); 220 } 221 222 223 /** 224 * java.util.Date --> java.time.LocalDateTime 225 */ 226 public static LocalDateTime toLocalDateTime(Date date) { 227 if (date == null) { 228 return null; 229 } 230 // java.sql.Date 不支持 toInstant(),需要先转换成 java.util.Date 231 if (date instanceof java.sql.Date) { 232 date = new Date(date.getTime()); 233 } 234 235 Instant instant = date.toInstant(); 236 ZoneId zone = ZoneId.systemDefault(); 237 return LocalDateTime.ofInstant(instant, zone); 238 } 239 240 /** 241 * java.util.Date --> java.time.LocalDate 242 */ 243 public static LocalDate toLocalDate(Date date) { 244 if (date == null) { 245 return null; 246 } 247 // java.sql.Date 不支持 toInstant(),需要先转换成 java.util.Date 248 if (date instanceof java.sql.Date) { 249 date = new Date(date.getTime()); 250 } 251 252 Instant instant = date.toInstant(); 253 ZoneId zone = ZoneId.systemDefault(); 254 LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone); 255 return localDateTime.toLocalDate(); 256 } 257 258 /** 259 * java.util.Date --> java.time.LocalTime 260 */ 261 public static LocalTime toLocalTime(Date date) { 262 if (date == null) { 263 return null; 264 } 265 // java.sql.Date 不支持 toInstant(),需要先转换成 java.util.Date 266 if (date instanceof java.sql.Date) { 267 date = new Date(date.getTime()); 268 } 269 270 Instant instant = date.toInstant(); 271 ZoneId zone = ZoneId.systemDefault(); 272 LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone); 273 return localDateTime.toLocalTime(); 274 } 275 276 /** 277 * java.time.LocalDateTime --> java.util.Date 278 */ 279 public static Date toDate(LocalDateTime localDateTime) { 280 if (localDateTime == null) { 281 return null; 282 } 283 ZoneId zone = ZoneId.systemDefault(); 284 Instant instant = localDateTime.atZone(zone).toInstant(); 285 return Date.from(instant); 286 } 287 288 /** 289 * java.time.LocalDate --> java.util.Date 290 */ 291 public static Date toDate(LocalDate localDate) { 292 if (localDate == null) { 293 return null; 294 } 295 ZoneId zone = ZoneId.systemDefault(); 296 Instant instant = localDate.atStartOfDay().atZone(zone).toInstant(); 297 return Date.from(instant); 298 } 299 300 /** 301 * java.time.LocalTime --> java.util.Date 302 */ 303 public static Date toDate(LocalTime localTime) { 304 if (localTime == null) { 305 return null; 306 } 307 LocalDate localDate = LocalDate.now(); 308 LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime); 309 ZoneId zone = ZoneId.systemDefault(); 310 Instant instant = localDateTime.atZone(zone).toInstant(); 311 return Date.from(instant); 312 } 313 314 /** 315 * java.time.LocalTime --> java.util.Date 316 */ 317 public static Date toDate(LocalDate localDate, LocalTime localTime) { 318 if (localDate == null) { 319 return null; 320 } 321 322 if (localTime == null) { 323 localTime = LocalTime.of(0, 0, 0); 324 } 325 326 LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime); 327 ZoneId zone = ZoneId.systemDefault(); 328 Instant instant = localDateTime.atZone(zone).toInstant(); 329 return Date.from(instant); 330 } 331 332 333 /** 334 * 任意一天的开始时间 335 * 336 * @return date 337 */ 338 public static Date getStartOfDay(Date date) { 339 Calendar calendar = Calendar.getInstance(); 340 calendar.setTime(date); 341 calendar.set(Calendar.HOUR_OF_DAY, 0); 342 calendar.set(Calendar.MINUTE, 0); 343 calendar.set(Calendar.SECOND, 0); 344 calendar.set(Calendar.MILLISECOND, 0); 345 return calendar.getTime(); 346 } 347 348 /** 349 * 任意一天的结束时间 350 * 351 * @return date 352 */ 353 public static Date getEndOfDay(Date date) { 354 Calendar calendar = Calendar.getInstance(); 355 calendar.setTime(date); 356 calendar.set(Calendar.HOUR_OF_DAY, 24); 357 calendar.set(Calendar.MINUTE, 0); 358 calendar.set(Calendar.SECOND, 0); 359 calendar.set(Calendar.MILLISECOND, 0); 360 return calendar.getTime(); 361 } 362 363 364 /** 365 * 获取今天的开始时间 366 * 367 * @return 368 */ 369 public static Date getStartOfToday() { 370 Calendar cal = Calendar.getInstance(); 371 cal.set(Calendar.HOUR_OF_DAY, 0); 372 cal.set(Calendar.SECOND, 0); 373 cal.set(Calendar.MINUTE, 0); 374 cal.set(Calendar.MILLISECOND, 0); 375 return cal.getTime(); 376 } 377 378 379 /** 380 * 获取昨天的开始时间 381 * 382 * @return 383 */ 384 public static Date getStartOfYesterday() { 385 Calendar cal = Calendar.getInstance(); 386 cal.setTimeInMillis(getStartOfToday().getTime() - 3600L * 24 * 1000); 387 return cal.getTime(); 388 } 389 390 391 /** 392 * 获取最近 7 天的开始时间 393 * 394 * @return 395 */ 396 public static Date getStartOfNearest7Days() { 397 return getStartOfNearestDays(7); 398 } 399 400 401 /** 402 * 获取最近 N 天的开始时间 403 * 404 * @param days 405 * @return 406 */ 407 public static Date getStartOfNearestDays(int days) { 408 Calendar cal = Calendar.getInstance(); 409 cal.setTimeInMillis(getStartOfToday().getTime() - 3600L * 24 * 1000 * days); 410 return cal.getTime(); 411 } 412 413 414 /** 415 * 获取今天的结束数据 416 * 417 * @return 418 */ 419 public static Date getEndOfToday() { 420 Calendar cal = Calendar.getInstance(); 421 cal.set(Calendar.HOUR_OF_DAY, 24); 422 cal.set(Calendar.SECOND, 0); 423 cal.set(Calendar.MINUTE, 0); 424 cal.set(Calendar.MILLISECOND, 0); 425 return cal.getTime(); 426 } 427 428 429 /** 430 * 获取 本周 的开始时间 431 * 432 * @return 433 */ 434 public static Date getStartOfThisWeek() { 435 Calendar cal = Calendar.getInstance(); 436 cal.setFirstDayOfWeek(Calendar.MONDAY); 437 cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0); 438 cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); 439 return cal.getTime(); 440 } 441 442 /** 443 * 获取 本周 的结束时间 444 * 445 * @return 446 */ 447 public static Date getEndOfThisWeek() { 448 Calendar cal = Calendar.getInstance(); 449 cal.setFirstDayOfWeek(Calendar.MONDAY); 450 cal.setTime(getStartOfThisWeek()); 451 cal.add(Calendar.DAY_OF_WEEK, 7); 452 return cal.getTime(); 453 } 454 455 456 /** 457 * 获取 本月 的开始时间 458 * 459 * @return 460 */ 461 public static Date getStartOfThisMonth() { 462 Calendar cal = Calendar.getInstance(); 463 cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0); 464 cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH)); 465 return cal.getTime(); 466 } 467 468 /** 469 * 获取 本月 的结束时间 470 * 471 * @return 472 */ 473 public static Date getEndOfThisMonth() { 474 Calendar cal = Calendar.getInstance(); 475 cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0); 476 cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); 477 cal.set(Calendar.HOUR_OF_DAY, 24); 478 return cal.getTime(); 479 } 480 481 482 /** 483 * 获取上个月的开始时间 484 * 485 * @return 486 */ 487 public static Date getStartOfLastMonth() { 488 Calendar cal = Calendar.getInstance(); 489 cal.setTime(getStartOfThisMonth()); 490 cal.add(Calendar.MONTH, -1); 491 return cal.getTime(); 492 } 493 494 495 /** 496 * 获取 本季度 的开始时间 497 * 498 * @return 499 */ 500 public static Date getStartOfThisQuarter() { 501 Calendar cal = Calendar.getInstance(); 502 int currentMonth = cal.get(Calendar.MONTH) + 1; 503 if (currentMonth <= 3) { 504 cal.set(Calendar.MONTH, 0); 505 } else if (currentMonth <= 6) { 506 cal.set(Calendar.MONTH, 3); 507 } else if (currentMonth <= 9) { 508 cal.set(Calendar.MONTH, 6); 509 } else if (currentMonth <= 12) { 510 cal.set(Calendar.MONTH, 9); 511 } 512 cal.set(Calendar.DATE, 0); 513 514 cal.set(Calendar.HOUR_OF_DAY, 24); 515 cal.set(Calendar.SECOND, 0); 516 cal.set(Calendar.MINUTE, 0); 517 cal.set(Calendar.MILLISECOND, 0); 518 519 return cal.getTime(); 520 } 521 522 523 /** 524 * 获取 本季度的 结束时间 525 * 526 * @return 527 */ 528 public static Date getEndOfThisQuarter() { 529 Calendar cal = Calendar.getInstance(); 530 cal.setTime(getStartOfThisQuarter()); 531 cal.add(Calendar.MONTH, 3); 532 return cal.getTime(); 533 } 534 535 536 /** 537 * 获取 季度 的开始时间 538 * 539 * @param quarterNumber 540 * @return 541 */ 542 public static Date getStartOfQuarter(int quarterNumber) { 543 if (quarterNumber < 1 || quarterNumber > 4) { 544 throw new IllegalArgumentException("quarterNumber must equals 1,2,3,4"); 545 } 546 Calendar cal = Calendar.getInstance(); 547 if (quarterNumber == 1) { 548 cal.set(Calendar.MONTH, 0); 549 } else if (quarterNumber == 2) { 550 cal.set(Calendar.MONTH, 3); 551 } else if (quarterNumber == 3) { 552 cal.set(Calendar.MONTH, 6); 553 } else { 554 cal.set(Calendar.MONTH, 9); 555 } 556 557 cal.set(Calendar.DATE, 0); 558 cal.set(Calendar.HOUR_OF_DAY, 24); 559 cal.set(Calendar.SECOND, 0); 560 cal.set(Calendar.MINUTE, 0); 561 cal.set(Calendar.MILLISECOND, 0); 562 563 return cal.getTime(); 564 } 565 566 567 /** 568 * 获取 季度 的结束时间 569 * 570 * @param quarterNumber 571 * @return 572 */ 573 public static Date getEndOfQuarter(int quarterNumber) { 574 Calendar cal = Calendar.getInstance(); 575 cal.setTime(getStartOfQuarter(quarterNumber)); 576 cal.add(Calendar.MONTH, 3); 577 return cal.getTime(); 578 } 579 580 581 /** 582 * 获取 今年 的开始时间 583 * 584 * @return 585 */ 586 public static Date getStartOfThisYear() { 587 Calendar cal = Calendar.getInstance(); 588 cal.setTime(new Date()); 589 cal.set(cal.get(Calendar.YEAR), 0, 1, 0, 0, 0); 590 return cal.getTime(); 591 } 592 593 594 /** 595 * 获取 今年 的结束时间 596 * 597 * @return 598 */ 599 public static Date getEndOfThisYear() { 600 Calendar cal = Calendar.getInstance(); 601 cal.setTime(getStartOfThisYear()); 602 cal.add(Calendar.YEAR, 1); 603 return cal.getTime(); 604 } 605 606 607 /** 608 * 获取 去年的 开始时间 609 * 610 * @return 611 */ 612 public static Date getStartOfLastYear() { 613 Calendar cal = Calendar.getInstance(); 614 cal.setTime(getStartOfThisYear()); 615 cal.add(Calendar.YEAR, -1); 616 return cal.getTime(); 617 } 618 619 /** 620 * 获取两个时间直接的间隔:单位 秒 621 * 622 * @param date1 623 * @param date2 624 * @return 625 */ 626 public static int diffSecond(Date date1, Date date2) { 627 long date1ms = date1.getTime(); 628 long date2ms = date2.getTime(); 629 return Math.abs((int) ((date1ms - date2ms) / (1000))); 630 } 631 632 /** 633 * 获取两个时间直接的间隔:单位 分钟 634 * 635 * @param date1 636 * @param date2 637 * @return 638 */ 639 public static int diffMinute(Date date1, Date date2) { 640 long date1ms = date1.getTime(); 641 long date2ms = date2.getTime(); 642 return Math.abs((int) ((date1ms - date2ms) / (1000 * 60))); 643 } 644 645 646 /** 647 * 获取两个时间直接的间隔:单位 小时 648 * 649 * @param date1 650 * @param date2 651 * @return 652 */ 653 public static int diffHours(Date date1, Date date2) { 654 long date1ms = date1.getTime(); 655 long date2ms = date2.getTime(); 656 return Math.abs((int) ((date1ms - date2ms) / (1000 * 60 * 60))); 657 } 658 659 /** 660 * 获取两个时间直接的间隔:单位 天 661 * 662 * @param date1 663 * @param date2 664 * @return 665 */ 666 public static int diffDays(Date date1, Date date2) { 667 long date1ms = date1.getTime(); 668 long date2ms = date2.getTime(); 669 return Math.abs((int) ((date1ms - date2ms) / (1000 * 60 * 60 * 24))); 670 } 671 672 /** 673 * 获取两个时间直接的间隔:单位 星期 674 * 675 * @param date1 676 * @param date2 677 * @return 678 */ 679 public static int diffWeeks(Date date1, Date date2) { 680 long date1ms = date1.getTime(); 681 long date2ms = date2.getTime(); 682 return Math.abs((int) ((date1ms - date2ms) / (1000 * 60 * 60 * 24 * 7))); 683 } 684 685 /** 686 * 获取两个时间直接的间隔:单位 月 687 * 688 * @param date1 689 * @param date2 690 * @return 691 */ 692 public static int diffMonths(Date date1, Date date2) { 693 int diffYears = diffYears(date1, date2) * 12; 694 int number1 = getMonthNumber(date1); 695 int number2 = getMonthNumber(date2); 696 return Math.abs(diffYears + number1 - number2); 697 } 698 699 /** 700 * 获取两个时间直接的间隔:单位 年 701 * 702 * @param date1 703 * @param date2 704 * @return 705 */ 706 public static int diffYears(Date date1, Date date2) { 707 int number1 = getYearNumber(date1); 708 int number2 = getYearNumber(date2); 709 return Math.abs(number1 - number2); 710 } 711 712 713 /** 714 * 获取日期的月份 715 * 716 * @param date 717 * @return 718 */ 719 public static int getMonthNumber(Date date) { 720 Calendar cal = Calendar.getInstance(); 721 cal.setTime(date); 722 return cal.get(Calendar.MONTH) + 1; 723 } 724 725 726 /** 727 * 获取日期的季度 728 * 729 * @param date 730 * @return 731 */ 732 public static int getQuarterNumber(Date date) { 733 int monthNumber = getMonthNumber(date); 734 if (monthNumber >= 1 && monthNumber <= 3) { 735 return 1; 736 } else if (monthNumber >= 4 && monthNumber <= 6) { 737 return 2; 738 } else if (monthNumber >= 7 && monthNumber <= 9) { 739 return 3; 740 } else { 741 return 4; 742 } 743 } 744 745 746 /** 747 * 获取日期的年份 748 * 749 * @param date 750 * @return 751 */ 752 public static int getYearNumber(Date date) { 753 Calendar cal = Calendar.getInstance(); 754 cal.setTime(date); 755 return cal.get(Calendar.YEAR); 756 } 757 758 759 /** 760 * 获取日期的是当年的第几天 761 * 762 * @param date 763 * @return 764 */ 765 public static int getDayOfYearNumber(Date date) { 766 Calendar cal = Calendar.getInstance(); 767 cal.setTime(date); 768 return cal.get(Calendar.DAY_OF_YEAR); 769 } 770 771 /** 772 * 获取日期的当月的第几天 773 * 774 * @param date 775 * @return 776 */ 777 public static int getDayOfMonthNumber(Date date) { 778 Calendar cal = Calendar.getInstance(); 779 cal.setTime(date); 780 return cal.get(Calendar.DAY_OF_MONTH); 781 } 782 783 /** 784 * 获取日期的当星期的第几天 785 * 786 * @param date 787 * @return 788 */ 789 public static int getDayOfWeekNumber(Date date) { 790 Calendar cal = Calendar.getInstance(); 791 cal.setFirstDayOfWeek(Calendar.MONDAY); 792 cal.setTime(date); 793 return cal.get(Calendar.DAY_OF_WEEK); 794 } 795 796 797 /** 798 * 获取日期的是当年的第个星期 799 * 800 * @param date 801 * @return 802 */ 803 public static int getWeekOfYearNumber(Date date) { 804 Calendar cal = Calendar.getInstance(); 805 cal.setFirstDayOfWeek(Calendar.MONDAY); 806 cal.setTime(date); 807 return cal.get(Calendar.WEEK_OF_YEAR); 808 } 809 810 /** 811 * 获取日期的当月的第几星期 812 * 813 * @param date 814 * @return 815 */ 816 public static int getWeekOfMonthNumber(Date date) { 817 Calendar cal = Calendar.getInstance(); 818 cal.setFirstDayOfWeek(Calendar.MONDAY); 819 cal.setTime(date); 820 return cal.get(Calendar.WEEK_OF_MONTH); 821 } 822 823 824 /** 825 * 取得在指定时间上加减seconds天后的时间 826 * 827 * @param date 指定的时间 828 * @param seconds 秒钟,正为加,负为减 829 * @return 在指定时间上加减seconds天后的时间 830 */ 831 public static Date addSeconds(Date date, int seconds) { 832 Calendar cal = Calendar.getInstance(); 833 cal.setTime(date); 834 cal.add(Calendar.SECOND, seconds); 835 return cal.getTime(); 836 } 837 838 839 /** 840 * 取得在指定时间上加减minutes天后的时间 841 * 842 * @param date 指定的时间 843 * @param minutes 分钟,正为加,负为减 844 * @return 在指定时间上加减minutes天后的时间 845 */ 846 public static Date addMinutes(Date date, int minutes) { 847 Calendar cal = Calendar.getInstance(); 848 cal.setTime(date); 849 cal.add(Calendar.MINUTE, minutes); 850 return cal.getTime(); 851 } 852 853 /** 854 * 取得在指定时间上加减hours天后的时间 855 * 856 * @param date 指定的时间 857 * @param hours 小时,正为加,负为减 858 * @return 在指定时间上加减dhours天后的时间 859 */ 860 public static Date addHours(Date date, int hours) { 861 Calendar cal = Calendar.getInstance(); 862 cal.setTime(date); 863 cal.add(Calendar.HOUR, hours); 864 return cal.getTime(); 865 } 866 867 /** 868 * 取得在指定时间上加减days天后的时间 869 * 870 * @param date 指定的时间 871 * @param days 天数,正为加,负为减 872 * @return 在指定时间上加减days天后的时间 873 */ 874 public static Date addDays(Date date, int days) { 875 Calendar cal = Calendar.getInstance(); 876 cal.setTime(date); 877 cal.add(Calendar.DAY_OF_MONTH, days); 878 return cal.getTime(); 879 } 880 881 /** 882 * 取得在指定时间上加减weeks天后的时间 883 * 884 * @param date 指定的时间 885 * @param weeks 星期,正为加,负为减 886 * @return 在指定时间上加减weeks天后的时间 887 */ 888 public static Date addWeeks(Date date, int weeks) { 889 Calendar cal = Calendar.getInstance(); 890 cal.setTime(date); 891 cal.add(Calendar.WEEK_OF_YEAR, weeks); 892 return cal.getTime(); 893 } 894 895 /** 896 * 取得在指定时间上加减months月后的时间 897 * 898 * @param date 指定时间 899 * @param months 月数,正为加,负为减 900 * @return 在指定时间上加减months月后的时间 901 */ 902 public static Date addMonths(Date date, int months) { 903 Calendar cal = Calendar.getInstance(); 904 cal.setTime(date); 905 cal.add(Calendar.MONTH, months); 906 return cal.getTime(); 907 } 908 909 /** 910 * 取得在指定时间上加减years年后的时间 911 * 912 * @param date 指定时间 913 * @param years 年数,正为加,负为减 914 * @return 在指定时间上加减years年后的时间 915 */ 916 public static Date addYears(Date date, int years) { 917 Calendar cal = Calendar.getInstance(); 918 cal.setTime(date); 919 cal.add(Calendar.YEAR, years); 920 return cal.getTime(); 921 } 922 923 924 /** 925 * 判断 A 的时间是否在 B 的时间 "之后" 926 */ 927 public static boolean isAfter(Date self, Date other) { 928 return self != null && other != null && self.getTime() > other.getTime(); 929 } 930 931 /** 932 * 判断 A 的时间是否在 B 的时间 "之后" 933 */ 934 public static boolean isBefore(Date self, Date other) { 935 return self != null && other != null && self.getTime() < other.getTime(); 936 } 937 938 /** 939 * 是否是相同的一天 940 */ 941 public static boolean isSameDay(Date self, Date other) { 942 return self != null && other != null && getYearNumber(self) == getYearNumber(other) 943 && getDayOfYearNumber(self) == getDayOfYearNumber(other); 944 } 945 946 /** 947 * 是否是相同的星期 948 */ 949 public static boolean isSameWeek(Date self, Date other) { 950 return self != null && other != null && getYearNumber(self) == getYearNumber(other) 951 && getWeekOfYearNumber(self) == getWeekOfYearNumber(other); 952 } 953 954 /** 955 * 是否是相同的月份 956 */ 957 public static boolean isSameMonth(Date self, Date other) { 958 return self != null && other != null && getYearNumber(self) == getYearNumber(other) 959 && getMonthNumber(self) == getMonthNumber(other); 960 } 961 962 /** 963 * 是否是相同的月份 964 */ 965 public static boolean isSameQuarter(Date self, Date other) { 966 return self != null && other != null && getYearNumber(self) == getYearNumber(other) 967 && getQuarterNumber(self) == getQuarterNumber(other); 968 } 969 970 /** 971 * 是否是相同的月份 972 */ 973 public static boolean isSameYear(Date self, Date other) { 974 return self != null && other != null && getYearNumber(self) == getYearNumber(other); 975 } 976 977 978 /** 979 * 此日期是否是今天 980 */ 981 public static boolean isToday(Date date) { 982 return isSameDay(new Date(), date); 983 } 984 985 /** 986 * 此日期是否是本星期 987 */ 988 public static boolean isThisWeek(Date date) { 989 return isSameWeek(new Date(), date); 990 } 991 992 /** 993 * 此日期是否是本月份 994 */ 995 public static boolean isThisMonth(Date date) { 996 return isSameMonth(new Date(), date); 997 } 998 999 1000 /** 1001 * 此日期是否是本月份 1002 */ 1003 public static boolean isThisQuarter(Date date) { 1004 return isSameQuarter(new Date(), date); 1005 } 1006 1007 /** 1008 * 此日期是否是本年份 1009 */ 1010 public static boolean isThisYear(Date date) { 1011 return date != null && getYearNumber(new Date()) == getYearNumber(date); 1012 } 1013 1014 /** 1015 * 判断是否是润年 1016 */ 1017 public static boolean isLeapYear(Date date) { 1018 return date != null && new GregorianCalendar().isLeapYear(getYearNumber(date)); 1019 } 1020 1021 /** 1022 * 求出指定的时间那天是星期几 1023 */ 1024 public static String getWeekDay(Date date) { 1025 return date == null ? null : DateUtil.WEEKS[getDayOfWeekNumber(date) - 1]; 1026 } 1027 1028 1029 public static void main(String[] args) { 1030 System.out.println("两天后的开始时间:" + toDateTimeString(getStartOfDay(addDays(new Date(), 2)))); 1031 System.out.println("两天后的结束时间:" + toDateTimeString(getEndOfDay(addDays(new Date(), 2)))); 1032 1033 System.out.println("CST时间解析:" + toDateTimeString(parseDate("Mon Sep 02 11:23:45 CST 2019"))); 1034 1035 1036 System.out.println("当天24点时间:" + toDateTimeString(getEndOfToday())); 1037 System.out.println("当前时间:" + toDateTimeString(new Date())); 1038 System.out.println("当天0点时间:" + toDateTimeString(getStartOfToday())); 1039 System.out.println("昨天0点时间:" + toDateTimeString(getStartOfYesterday())); 1040 System.out.println("近7天时间:" + toDateTimeString(getStartOfNearest7Days())); 1041 System.out.println("本周周一0点时间:" + toDateTimeString(getStartOfThisWeek())); 1042 System.out.println("本周周日24点时间:" + toDateTimeString(getEndOfThisWeek())); 1043 System.out.println("本月初0点时间:" + toDateTimeString(getStartOfThisMonth())); 1044 System.out.println("本月未24点时间:" + toDateTimeString(getEndOfThisMonth())); 1045 System.out.println("上月初0点时间:" + toDateTimeString(getStartOfLastMonth())); 1046 System.out.println("本季度开始点时间:" + toDateTimeString(getStartOfThisQuarter())); 1047 System.out.println("本季度结束点时间:" + toDateTimeString(getEndOfThisQuarter())); 1048 System.out.println("本年开始点时间:" + toDateTimeString(getStartOfThisYear())); 1049 System.out.println("本年结束点时间:" + toDateTimeString(getEndOfThisYear())); 1050 System.out.println("上年开始点时间:" + toDateTimeString(getStartOfLastYear())); 1051 System.out.println("============="); 1052 System.out.println("秒间隔:" + diffSecond(parseDate("2020-02-11 12:21:55"), parseDate("2020-02-11 12:22:58"))); 1053 System.out.println("分钟间隔:" + diffMinute(parseDate("2020-02-11 12:21:55"), parseDate("2020-02-11 12:22:01"))); 1054 System.out.println("小时间隔:" + diffHours(parseDate("2020-02-11 12:21:55"), parseDate("2020-02-12 12:22:01"))); 1055 System.out.println("天间隔:" + diffDays(parseDate("2020-02-11 12:21:55"), parseDate("2020-02-12 12:22:01"))); 1056 System.out.println("星期间隔:" + diffWeeks(parseDate("2020-01-11 12:21:55"), parseDate("2020-02-12 12:22:01"))); 1057 System.out.println("月间隔:" + diffMonths(parseDate("2019-10-11 12:21:55"), parseDate("2020-09-11 12:21:55"))); 1058 System.out.println("年间隔:" + diffYears(parseDate("1990-01-11 12:21:55"), parseDate("2020-02-12 12:22:01"))); 1059 System.out.println("当前年份:" + getYearNumber(new Date())); 1060 System.out.println("当前月份:" + getMonthNumber(new Date())); 1061 System.out.println("============="); 1062 1063 System.out.println("新增秒:" + toDateTimeString(addSeconds(parseDate("2020-02-11 12:21:55"), 20))); 1064 System.out.println("新增分钟:" + toDateTimeString(addMinutes(parseDate("2020-02-11 12:21:55"), 20))); 1065 System.out.println("新增小时:" + toDateTimeString(addHours(parseDate("2020-02-11 12:21:55"), 20))); 1066 System.out.println("新增天:" + toDateTimeString(addDays(parseDate("2020-02-11 12:21:55"), 20))); 1067 System.out.println("新增星期:" + toDateTimeString(addWeeks(parseDate("2020-02-11 12:21:55"), 10))); 1068 System.out.println("新增月份:" + toDateTimeString(addMonths(parseDate("2020-02-11 12:21:55"), 20))); 1069 System.out.println("新增年份:" + toDateTimeString(addYears(parseDate("2020-02-11 12:21:55"), 20))); 1070 1071 System.out.println("============="); 1072 System.out.println("今天星期:" + getWeekDay(parseDate("2020-11-24"))); 1073 System.out.println("isToday:" + isToday(parseDate("2020-12-01"))); 1074 System.out.println("isThisWeek:" + isThisWeek(parseDate("2020-11-24"))); 1075 System.out.println("isThisMonth:" + isThisMonth(parseDate("2020-10-02"))); 1076 System.out.println("isThisQuarter:" + isThisQuarter(parseDate("2020-10-02"))); 1077 System.out.println("isThisYear:" + isThisYear(parseDate("2020-02-02"))); 1078 System.out.println("第1季度:" + toDateTimeString(getEndOfQuarter(1))); 1079 System.out.println("第2季度:" + toDateTimeString(getEndOfQuarter(2))); 1080 System.out.println("第3季度:" + toDateTimeString(getEndOfQuarter(3))); 1081 System.out.println("第4季度:" + toDateTimeString(getEndOfQuarter(4))); 1082 System.out.println("本季度:" + toDateTimeString(getStartOfThisQuarter())); 1083 System.out.println("本季度:" + toDateTimeString(getEndOfThisQuarter())); 1084 1085 1086 System.out.println("datetime-local解析:" + parseDate("2022-12-03T16:00")); 1087 1088 } 1089}