| 1 7 8 20 21 package java.util; 22 23 import java.io.IOException ; 24 import java.io.ObjectInputStream ; 25 import sun.util.calendar.BaseCalendar; 26 import sun.util.calendar.CalendarDate; 27 import sun.util.calendar.CalendarSystem; 28 import sun.util.calendar.CalendarUtils; 29 import sun.util.calendar.Era; 30 import sun.util.calendar.Gregorian; 31 import sun.util.calendar.JulianCalendar; 32 import sun.util.calendar.ZoneInfo; 33 34 282 public class GregorianCalendar extends Calendar { 283 308 309 313 321 public static final int BC = 0; 322 323 329 static final int BCE = 0; 330 331 339 public static final int AD = 1; 340 341 347 static final int CE = 1; 348 349 private static final int EPOCH_OFFSET = 719163; private static final int EPOCH_YEAR = 1970; 351 352 static final int MONTH_LENGTH[] 353 = {31,28,31,30,31,30,31,31,30,31,30,31}; static final int LEAP_MONTH_LENGTH[] 355 = {31,29,31,30,31,30,31,31,30,31,30,31}; 357 private static final int ONE_SECOND = 1000; 361 private static final int ONE_MINUTE = 60*ONE_SECOND; 362 private static final int ONE_HOUR = 60*ONE_MINUTE; 363 private static final long ONE_DAY = 24*ONE_HOUR; 364 private static final long ONE_WEEK = 7*ONE_DAY; 365 366 391 static final int MIN_VALUES[] = { 392 BCE, 1, JANUARY, 1, 0, 1, 1, SUNDAY, 1, AM, 0, 0, 0, 0, 0, -13*ONE_HOUR, 0 }; 410 static final int LEAST_MAX_VALUES[] = { 411 CE, 292269054, DECEMBER, 52, 4, 28, 365, SATURDAY, 4, PM, 11, 23, 59, 59, 999, 14*ONE_HOUR, 20*ONE_MINUTE }; 429 static final int MAX_VALUES[] = { 430 CE, 292278994, DECEMBER, 53, 6, 31, 366, SATURDAY, 6, PM, 11, 23, 59, 59, 999, 14*ONE_HOUR, 2*ONE_HOUR }; 448 449 static final long serialVersionUID = -8125100834729963327L; 451 452 private static final Gregorian gcal = 454 CalendarSystem.getGregorianCalendar(); 455 456 private static JulianCalendar jcal; 459 460 private static Era[] jeras; 462 463 static final long DEFAULT_GREGORIAN_CUTOVER = -12219292800000L; 465 466 470 478 private long gregorianCutover = DEFAULT_GREGORIAN_CUTOVER; 479 480 483 private transient long gregorianCutoverDate = 484 (((DEFAULT_GREGORIAN_CUTOVER + 1)/ONE_DAY) - 1) + EPOCH_OFFSET; 486 490 private transient int gregorianCutoverYear = 1582; 491 492 496 private transient int gregorianCutoverYearJulian = 1582; 497 498 503 private transient BaseCalendar.Date gdate; 504 505 510 private transient BaseCalendar.Date cdate; 511 512 517 private transient BaseCalendar calsys; 518 519 524 private transient int[] zoneOffsets; 525 526 530 private transient int[] originalFields; 531 532 536 540 public GregorianCalendar() { 541 this(TimeZone.getDefaultRef(), Locale.getDefault()); 542 setZoneShared(true); 543 } 544 545 551 public GregorianCalendar(TimeZone zone) { 552 this(zone, Locale.getDefault()); 553 } 554 555 561 public GregorianCalendar(Locale aLocale) { 562 this(TimeZone.getDefaultRef(), aLocale); 563 setZoneShared(true); 564 } 565 566 573 public GregorianCalendar(TimeZone zone, Locale aLocale) { 574 super(zone, aLocale); 575 gdate = (BaseCalendar.Date) gcal.newCalendarDate(zone); 576 setTimeInMillis(System.currentTimeMillis()); 577 } 578 579 588 public GregorianCalendar(int year, int month, int dayOfMonth) { 589 this(year, month, dayOfMonth, 0, 0, 0, 0); 590 } 591 592 605 public GregorianCalendar(int year, int month, int dayOfMonth, int hourOfDay, 606 int minute) { 607 this(year, month, dayOfMonth, hourOfDay, minute, 0, 0); 608 } 609 610 625 public GregorianCalendar(int year, int month, int dayOfMonth, int hourOfDay, 626 int minute, int second) { 627 this(year, month, dayOfMonth, hourOfDay, minute, second, 0); 628 } 629 630 646 GregorianCalendar(int year, int month, int dayOfMonth, 647 int hourOfDay, int minute, int second, int millis) { 648 super(); 649 gdate = (BaseCalendar.Date) gcal.newCalendarDate(getZone()); 650 this.set(YEAR, year); 651 this.set(MONTH, month); 652 this.set(DAY_OF_MONTH, dayOfMonth); 653 654 if (hourOfDay >= 12 && hourOfDay <= 23) { 657 this.internalSet(AM_PM, PM); 661 this.internalSet(HOUR, hourOfDay - 12); 662 } else { 663 this.internalSet(HOUR, hourOfDay); 666 } 667 setFieldsComputed(HOUR_MASK|AM_PM_MASK); 669 670 this.set(HOUR_OF_DAY, hourOfDay); 671 this.set(MINUTE, minute); 672 this.set(SECOND, second); 673 this.internalSet(MILLISECOND, millis); 676 } 677 678 682 693 public void setGregorianChange(Date date) { 694 long cutoverTime = date.getTime(); 695 if (cutoverTime == gregorianCutover) { 696 return; 697 } 698 complete(); 701 setGregorianChange(cutoverTime); 702 } 703 704 private void setGregorianChange(long cutoverTime) { 705 gregorianCutover = cutoverTime; 706 gregorianCutoverDate = CalendarUtils.floorDivide(cutoverTime, ONE_DAY) 707 + EPOCH_OFFSET; 708 709 if (cutoverTime == Long.MAX_VALUE) { 715 gregorianCutoverDate++; 716 } 717 718 BaseCalendar.Date d = getGregorianCutoverDate(); 719 720 gregorianCutoverYear = d.getYear(); 722 723 BaseCalendar jcal = getJulianCalendarSystem(); 724 d = (BaseCalendar.Date) jcal.newCalendarDate(TimeZone.NO_TIMEZONE); 725 jcal.getCalendarDateFromFixedDate(d, gregorianCutoverDate - 1); 726 gregorianCutoverYearJulian = d.getNormalizedYear(); 727 728 if (time < gregorianCutover) { 729 setUnnormalized(); 732 } 733 } 734 735 743 public final Date getGregorianChange() { 744 return new Date (gregorianCutover); 745 } 746 747 756 public boolean isLeapYear(int year) { 757 if ((year & 3) != 0) { 758 return false; 759 } 760 761 if (year > gregorianCutoverYear) { 762 return (year%100 != 0) || (year%400 == 0); } 764 if (year < gregorianCutoverYearJulian) { 765 return true; } 767 boolean gregorian; 768 if (gregorianCutoverYear == gregorianCutoverYearJulian) { 771 BaseCalendar.Date d = getCalendarDate(gregorianCutoverDate); gregorian = d.getMonth() < BaseCalendar.MARCH; 773 } else { 774 gregorian = year == gregorianCutoverYear; 775 } 776 return gregorian ? (year%100 != 0) || (year%400 == 0) : true; 777 } 778 779 793 public boolean equals(Object obj) { 794 return obj instanceof GregorianCalendar && 795 super.equals(obj) && 796 gregorianCutover == ((GregorianCalendar )obj).gregorianCutover; 797 } 798 799 802 public int hashCode() { 803 return super.hashCode() ^ (int)gregorianCutoverDate; 804 } 805 806 834 public void add(int field, int amount) { 835 if (amount == 0) { 838 return; } 840 841 if (field < 0 || field >= ZONE_OFFSET) { 842 throw new IllegalArgumentException (); 843 } 844 845 complete(); 847 848 if (field == YEAR) { 849 int year = internalGet(YEAR); 850 if (internalGetEra() == CE) { 851 year += amount; 852 if (year > 0) { 853 set(YEAR, year); 854 } else { set(YEAR, 1 - year); 856 set(ERA, BCE); 858 } 859 } 860 else { year -= amount; 862 if (year > 0) { 863 set(YEAR, year); 864 } else { set(YEAR, 1 - year); 866 set(ERA, CE); 868 } 869 } 870 pinDayOfMonth(); 871 } else if (field == MONTH) { 872 int month = internalGet(MONTH) + amount; 873 int year = internalGet(YEAR); 874 int y_amount; 875 876 if (month >= 0) { 877 y_amount = month/12; 878 } else { 879 y_amount = (month+1)/12 - 1; 880 } 881 if (y_amount != 0) { 882 if (internalGetEra() == CE) { 883 year += y_amount; 884 if (year > 0) { 885 set(YEAR, year); 886 } else { set(YEAR, 1 - year); 888 set(ERA, BCE); 890 } 891 } 892 else { year -= y_amount; 894 if (year > 0) { 895 set(YEAR, year); 896 } else { set(YEAR, 1 - year); 898 set(ERA, CE); 900 } 901 } 902 } 903 904 if (month >= 0) { 905 set(MONTH, (int) (month % 12)); 906 } else { 907 month %= 12; 909 if (month < 0) { 910 month += 12; 911 } 912 set(MONTH, JANUARY + month); 913 } 914 pinDayOfMonth(); 915 } else if (field == ERA) { 916 int era = internalGet(ERA) + amount; 917 if (era < 0) { 918 era = 0; 919 } 920 if (era > 1) { 921 era = 1; 922 } 923 set(ERA, era); 924 } else { 925 long delta = amount; 926 long timeOfDay = 0; 927 switch (field) { 928 case HOUR: 931 case HOUR_OF_DAY: 932 delta *= 60 * 60 * 1000; break; 934 935 case MINUTE: 936 delta *= 60 * 1000; break; 938 939 case SECOND: 940 delta *= 1000; break; 942 943 case MILLISECOND: 944 break; 945 946 case WEEK_OF_YEAR: 950 case WEEK_OF_MONTH: 951 case DAY_OF_WEEK_IN_MONTH: 952 delta *= 7; 953 break; 954 955 case DAY_OF_MONTH: case DAY_OF_YEAR: 957 case DAY_OF_WEEK: 958 break; 959 960 case AM_PM: 961 delta = amount / 2; 964 timeOfDay = 12 * (amount % 2); 965 break; 966 } 967 968 if (field >= HOUR) { 971 setTimeInMillis(time + delta); 972 return; 973 } 974 975 979 long fd = getCurrentFixedDate(); 982 timeOfDay += internalGet(HOUR_OF_DAY); 983 timeOfDay *= 60; 984 timeOfDay += internalGet(MINUTE); 985 timeOfDay *= 60; 986 timeOfDay += internalGet(SECOND); 987 timeOfDay *= 1000; 988 timeOfDay += internalGet(MILLISECOND); 989 if (timeOfDay >= ONE_DAY) { 990 fd++; 991 timeOfDay -= ONE_DAY; 992 } else if (timeOfDay < 0) { 993 fd--; 994 timeOfDay += ONE_DAY; 995 } 996 997 fd += delta; int zoneOffset = internalGet(ZONE_OFFSET) + internalGet(DST_OFFSET); 999 setTimeInMillis((fd - EPOCH_OFFSET) * ONE_DAY + timeOfDay - zoneOffset); 1000 zoneOffset -= internalGet(ZONE_OFFSET) + internalGet(DST_OFFSET); 1001 if (zoneOffset != 0) { 1003 setTimeInMillis(time + zoneOffset); 1004 long fd2 = getCurrentFixedDate(); 1005 if (fd2 != fd) { 1008 setTimeInMillis(time - zoneOffset); 1009 } 1010 } 1011 } 1012 } 1013 1014 |