| 1 3 package jodd.datetime; 4 5 import java.util.Calendar ; 6 import java.util.TimeZone ; 7 import java.util.Locale ; 8 9 import jodd.datetime.converter.*; 10 import jodd.datetime.formatter.DefaultFormatter; 11 import jodd.datetime.formatter.JdtFormatter; 12 import jodd.util.ObjectUtil; 13 import jodd.util.HashCodeUtil; 14 15 105 public class JDateTime implements Comparable , Cloneable { 106 107 110 protected DateTimeStamp time = new DateTimeStamp(); 111 112 115 protected int dayofweek; 116 117 120 protected int dayofyear; 121 122 125 protected boolean leap; 126 127 130 protected int weekofyear; 131 132 135 protected int weekofmonth; 136 137 140 protected JulianDateStamp jdate; 141 142 143 145 148 public static final JulianDateStamp JD_1970 = new JulianDateStamp(2440587.5); 149 150 153 public static final JulianDateStamp JD_2001 = new JulianDateStamp(2451910.5); 154 155 159 public static final JulianDateStamp JD_MJD = new JulianDateStamp(2400000.5); 160 161 165 public static final JulianDateStamp JD_RJD = new JulianDateStamp(2400000); 166 167 171 public static final JulianDateStamp JD_TJD = new JulianDateStamp(2440000.5); 172 173 174 175 177 181 public DateTimeStamp getDateTimeStamp() { 182 return time; 183 } 184 185 188 public void setDateTimeStamp(DateTimeStamp dts) { 189 set(dts.year, dts.month, dts.day, dts.hour, dts.minute, dts.second); 190 } 191 192 199 public void setJulianDate(JulianDateStamp jds) { 200 setJdOnly((JulianDateStamp) jds.clone()); 201 setParams(); 202 } 203 204 207 public JulianDateStamp getJulianDate() { 208 return jdate; 209 } 210 211 214 private void setParams() { 215 this.leap = TimeUtil.isLeapYear(time.year); 216 this.dayofweek = calcDayOfWeek(); 217 this.dayofyear = calcDayOfYear(); 218 this.weekofyear = calcWeekOfYear(getFirstDayOfWeek() ,getMustHaveDayOfFirstWeek()); 219 this.weekofmonth = weekNumber(time.day, this.dayofweek); 220 } 221 222 229 private void setJdOnly(JulianDateStamp jds) { 230 jdate = jds; 231 time = TimeUtil.fromJulianDate(jds); 232 } 233 234 245 public void set(int year, int month, int day, int hour, int minute, double second) { 246 247 double ms = (second - (int)second) * 1000; 250 if (ms > 999) { 251 ms = 999; 252 } else { 253 ms += 1e-9; 254 } 255 second = ((int) second) + ((int) ms / 1000.0); 256 jdate = TimeUtil.toJulianDate(year, month, day, hour, minute, second); 257 258 if (TimeUtil.isValidDateTime(year, month, day, hour, minute, second)) { 265 266 int ka = (int)(jdate.fraction + 0.5); 267 double frac = jdate.fraction + 0.5 - ka + 1e-10; 268 269 double d_hour = frac * 24.0; 271 272 double d_minute = (d_hour - (int)d_hour) * 60.0; 274 275 second = (d_minute - (int)d_minute) * 60.0; 276 277 second = ((int) (second * 10000) + 0.5) / 10000.0; 279 280 time.year = year; time.month = month; time.day = day; 281 time.hour = hour; time.minute = minute; time.second = second; 282 setParams(); 283 } else { 284 setJulianDate(jdate); 285 } 286 } 287 288 299 private void setJdOnly(int year, int month, int day, int hour, int minute, double second) { 300 setJdOnly(TimeUtil.toJulianDate(year, month, day, hour, minute, second)); 301 } 302 303 304 306 309 private int calcDayOfWeek() { 310 int jd = (int)(jdate.doubleValue() + 0.5); 311 return (jd % 7) + 1; 312 } 314 315 private static final int NUM_DAYS[] = {-1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; private static final int LEAP_NUM_DAYS[] = {-1, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}; 318 321 private int calcDayOfYear() { 322 if (leap == true) { 323 return LEAP_NUM_DAYS[time.month] + time.day; 324 } 325 return NUM_DAYS[time.month] + time.day; 326 } 327 328 329 339 private int calcWeekOfYear(int start, int must) { 340 341 int delta = 0; 347 if (start <= this.dayofweek) { 348 if (must < start) { 349 delta = 7; 350 } 351 } else { 352 if (must >= start) { 353 delta = -7; 354 } 355 } 356 357 int jd = (int)(jdate.doubleValue() + 0.5) + delta; 358 int WeekDay = (jd % 7) + 1; 359 360 int time_year = time.year; 361 int DayOfYearNumber = this.dayofyear + delta; 362 if (DayOfYearNumber < 1) { 363 time_year--; 364 DayOfYearNumber = TimeUtil.isLeapYear(time_year) ? 366 + DayOfYearNumber: 365 + DayOfYearNumber; 365 } else if (DayOfYearNumber > (this.leap ? 366 : 365)) { 366 DayOfYearNumber = this.leap ? DayOfYearNumber - 366: DayOfYearNumber - 365; 367 time_year++; 368 } 369 370 372 int firstDay = jd - DayOfYearNumber + 1; 373 int Jan1WeekDay = (firstDay % 7) + 1; 374 375 int YearNumber = time_year; 377 int WeekNumber = 52; 378 if ((DayOfYearNumber <= (8 - Jan1WeekDay)) && (Jan1WeekDay > must)) { 379 YearNumber--; 380 if ((Jan1WeekDay == must + 1) || ( (Jan1WeekDay == must + 2) && (TimeUtil.isLeapYear(YearNumber)) ) ) { 381 WeekNumber = 53; 382 } 383 } 384 385 int m = 365; 387 if (YearNumber == time_year) { 388 if (TimeUtil.isLeapYear(time_year) == true) { 389 m = 366; 390 } 391 if ((m - DayOfYearNumber) < (must - WeekDay)) { 392 YearNumber = time_year + 1; 393 WeekNumber = 1; 394 } 395 } 396 397 if (YearNumber == time_year) { 398 int n = DayOfYearNumber + (7 - WeekDay) + (Jan1WeekDay - 1); 399 WeekNumber = n / 7; 400 if (Jan1WeekDay > must) { 401 WeekNumber -= 1; 402 } 403 } 404 return WeekNumber; 405 } 406 407 423 private int weekNumber(int dayOfPeriod, int dayOfWeek) { 424 int periodStartDayOfWeek = (dayOfWeek - getFirstDayOfWeek() - dayOfPeriod + 1) % 7; 428 if (periodStartDayOfWeek < 0) { 429 periodStartDayOfWeek += 7; 430 } 431 432 int weekNo = (dayOfPeriod + periodStartDayOfWeek - 1) / 7; 436 437 if ((7 - periodStartDayOfWeek) >= getMinDaysInFirstWeek()) { 441 ++weekNo; 442 } 443 444 return weekNo; 445 } 446 447 449 470 471 public void add(int year, int month, int day, int hour, int minute, double second, boolean monthFix) { 472 second += time.second; 473 minute += time.minute; 474 hour += time.hour; 475 day += time.day; 476 if (monthFix == false) { 477 month += time.month; 478 year += time.year; 479 set(year, month, day, hour, minute, second); 480 } else { 481 setJdOnly(time.year, time.month, day, hour, minute, second); 487 int from = time.day; 488 month += time.month + (year * 12); setJdOnly(time.year, month, time.day, time.hour, time.minute, time.second); 490 if (time.day < from) { 491 set(time.year, time.month, 0, time.hour, time.minute, time.second); 492 } else { 493 setParams(); 494 } 495 496 506 } 507 } 508 509 510 522 public void add(int year, int month, int day, int hour, int minute, double second) { 523 add(year, month, day, hour, minute, second, getMonthFix()); 524 } 525 526 527 537 public void add(int year, int month, int day, boolean monthFix) { 538 add(year, month, day, 0, 0, 0, monthFix); 539 } 540 550 public void add(int year, int month, int day) { 551 add(year, month, day, getMonthFix()); 552 } 553 554 555 565 public void addTime(int hour, int minute, double second, boolean monthFix) { 566 add(0, 0, 0, hour, minute, second, monthFix); 567 } 568 577 public void addTime(int hour, int minute, double second) { 578 addTime(hour, minute, second, getMonthFix()); 579 } 580 581 582 588 public void addYear(int y, boolean monthFix) { 589 add(y, 0, 0, monthFix); 590 } 591 596 public void addYear(int y) { 597 addYear(y, getMonthFix()); 598 } 599 600 601 607 public void addMonth(int m, boolean monthFix) { 608 add(0, m, 0, monthFix); 609 } 610 615 public void addMonth(int m) { 616 addMonth(m, getMonthFix()); 617 } 618 619 625 public void addDay(int d, boolean monthFix) { 626 add(0, 0, d, monthFix); 627 } 628 633 public void addDay(int d) { 634 addDay(d, getMonthFix()); 635 } 636 637 643 public void addHour(int h, boolean monthFix) { 644 addTime(h, 0, 0, monthFix); 645 } 646 651 public void addHour(int h) { 652 addHour(h, getMonthFix()); 653 } 654 655 656 662 public void addMinute(int m, boolean monthFix) { 663 addTime(0, m, 0, monthFix); 664 } 665 670 public void addMinute(int m) { 671 addMinute(m, getMonthFix()); 672 } 673 674 680 public void addSecond(double s, boolean monthFix) { 681 addTime(0, 0, s, monthFix); 682 } 683 688 public void addSecond(double s) { 689 addSecond(s, getMonthFix()); 690 } 691 692 693 699 public void addMillisecond(int ms, boolean monthFix) { 700 addTime(0, 0, ms / 1000.0, monthFix); 701 } 702 707 public void addMillisecond(int ms) { 708 addMillisecond(ms, getMonthFix()); 709 } 710 711 713 725 public JDateTime(int year, int month, int day, int hour, int minute, double second) { 726 this.set(year, month, day, hour, minute, second); 727 } 728 729 736 public void set(int year, int month, int day) { 737 set(year, month, day, 0, 0, 0); 738 } 739 740 749 public JDateTime(int year, int month, int day) { 750 this.set(year, month, day); 751 } 752 753 760 public void setTime(int hour, int minute, double second) { 761 set(time.year, time.month, time.day, hour, minute, second); 762 } 763 764 771 public void setDate(int year, int month, int day) { 772 set(year, month, day, time.hour, time.minute, time.second); 773 } 774 775 776 778 786 public JDateTime(long milis) { 787 setTimeInMillis(milis); 788 } 789 790 798 public void setTimeInMillis(long millis) { 799 millis += getTimeZone().getOffset(millis); 800 JulianDateStamp now = new JulianDateStamp(); 801 now.integer = (int) (millis / TimeUtil.MILLIS_IN_DAY); 802 now.fraction = (double)(millis % TimeUtil.MILLIS_IN_DAY) / TimeUtil.MILLIS_IN_DAY; 803 now.integer += JD_1970.integer; 804 now.fraction += JD_1970.fraction; 805 if (now.fraction >= 1.0) { 806 now.integer++; 807 now.fraction -= 1.0; 808 } 809 setJulianDate(now); 810 } 811 812 821 public long getTimeInMillis() { 822 double then = (jdate.fraction - JD_1970.fraction) * TimeUtil.MILLIS_IN_DAY; 823 then += (jdate.integer - JD_1970.integer) * TimeUtil.MILLIS_IN_DAY; 824 then += then > 0 ? 1.0e-6 : -1.0e-6; 825 then -= getTimeZone().getOffset((long) then); 826 return (long) then; 827 } 828 829 830 832 837 public void setYear(int y) { 838 setDate(y, time.month, time.day); 839 } 840 841 846 public void setMonth(int m) { 847 setDate(time.year, m, time.day); 848 } 849 850 855 public void setDay(int d) { 856 setDate(time.year, time.month, d); 857 } 858 859 864 public void setHour(int h) { 865 setTime(h, time.minute, time.second); 866 } 867 868 873 public void setMinute(int m) { 874 setTime(time.hour, m, time.second); 875 876 } 877 878 883 public void setSecond(double s) { 884 setTime(time.hour, time.minute, s); 885 } 886 887 892 public void setSecond(int s) { 893 double milis = s + (time.second - (int)time.second); 894 setTime(time.hour, time.minute, milis); 895 } 896 897 902 public void setMillisecond(int m) { 903 setTime(time.hour, time.minute, ((int)time.second) + m/1000.0); 904 } 905 906 907 909 910 913 public int getYear() { 914 return time.year; 915 } 916 917 920 public int getMonth() { 921 return time.month; 922 } 923 924 928 public int getDay() { 929 return time.day; 930 } 931 932 936 public int getDayOfMonth() { 937 return time.day; 938 } 939 940 943 public int getHour() { 944 return time.hour; 945 } 946 947 950 public int getMinute() { 951 return time.minute; 952 } 953 954 958 public double getSecond() { 959 return time.second; 960 } 961 962 965 public int getMillisecond() { 966 return (int) ((time.second - (int)time.second) * 1000 + 1e-9); 967 } 968 969 971 974 public int getDayOfWeek() { 975 return dayofweek; 976 } 977 978 981 public int getDayOfYear() { 982 return dayofyear; 983 } 984 985 988 public boolean isLeapYear() { 989 return leap; 990 } 991 992 995 public int getWeekOfYear() { 996 return weekofyear; 997 } 998 999 1002 public int getWeekOfMonth() { 1003 return weekofmonth; 1004 } 1005 1006 1007 1010 private static final int MONTH_LENGTH[] = {0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 1011 1012 1015 public int getMonthLength(int m) { 1016 if ((m < 1) || (m > 12)) { 1017 throw new IllegalArgumentException ("Invalid month index: '" + m + "'."); 1018 } 1019 if (m == 2) { 1020 return this.leap ? 29 : 28; 1021 } 1022 if ((time.year == 1582) && (time.month == 10)) { 1023 return 21; 1024 } 1025 return MONTH_LENGTH[m]; 1026 } 1027 1028 1031 public int getMonthLength() { 1032 return getMonthLength(time.month); 1033 } 1034 1035 1037 1040 public void setCurrentTime() { 1041 setTimeInMillis(System.currentTimeMillis()); 1042 } 1043 1044 1047 public JDateTime() { 1048 this.setCurrentTime(); 1049 } 1050 1051 1053 1057 public void loadFrom(Object source) { 1058 |