1 7 package com.ibm.icu.util; 8 import com.ibm.icu.util.TimeZone; 9 import com.ibm.icu.impl.CalendarCache; 10 import java.util.Date ; 11 import java.util.Locale ; 12 13 73 public class HebrewCalendar extends Calendar { 74 private static final long serialVersionUID = -1952524560588825816L; 76 77 private static String copyright = "Copyright \u00a9 1997-1998 IBM Corp. All Rights Reserved."; 78 79 83 84 88 public static final int TISHRI = 0; 89 90 94 public static final int HESHVAN = 1; 95 96 100 public static final int KISLEV = 2; 101 102 106 public static final int TEVET = 3; 107 108 112 public static final int SHEVAT = 4; 113 114 120 public static final int ADAR_1 = 5; 121 122 126 public static final int ADAR = 6; 127 128 132 public static final int NISAN = 7; 133 134 138 public static final int IYAR = 8; 139 140 144 public static final int SIVAN = 9; 145 146 150 public static final int TAMUZ = 10; 151 152 156 public static final int AV = 11; 157 158 162 public static final int ELUL = 12; 163 164 170 172 private static final int LIMITS[][] = { 173 { 0, 0, 0, 0 }, { 1, 1, 5000000, 5000000 }, { 0, 0, 12, 12 }, { 1, 1, 51, 56 }, { 0, 0, 5, 6 }, { 1, 1, 29, 30 }, { 1, 1, 353, 385 }, {}, { -1, -1, 4, 6 }, {}, {}, {}, {}, {}, {}, {}, {}, { -5000001, -5000001, 5000001, 5000001 }, {}, { -5000000, -5000000, 5000000, 5000000 }, {}, {}, }; 198 199 206 private static final int MONTH_LENGTH[][] = { 207 { 30, 30, 30 }, { 29, 29, 30 }, { 29, 30, 30 }, { 29, 29, 29 }, { 30, 30, 30 }, { 30, 30, 30 }, { 29, 29, 29 }, { 30, 30, 30 }, { 29, 29, 29 }, { 30, 30, 30 }, { 29, 29, 29 }, { 30, 30, 30 }, { 29, 29, 29 }, }; 222 223 228 private static final int MONTH_START[][] = { 229 { 0, 0, 0 }, { 30, 30, 30 }, { 59, 59, 60 }, { 88, 89, 90 }, { 117, 118, 119 }, { 147, 148, 149 }, { 147, 148, 149 }, { 176, 177, 178 }, { 206, 207, 208 }, { 235, 236, 237 }, { 265, 266, 267 }, { 294, 295, 296 }, { 324, 325, 326 }, { 353, 354, 355 }, }; 245 246 249 private static final int LEAP_MONTH_START[][] = { 250 { 0, 0, 0 }, { 30, 30, 30 }, { 59, 59, 60 }, { 88, 89, 90 }, { 117, 118, 119 }, { 147, 148, 149 }, { 177, 178, 179 }, { 206, 207, 208 }, { 236, 237, 238 }, { 265, 266, 267 }, { 295, 296, 297 }, { 324, 325, 326 }, { 354, 355, 356 }, { 383, 384, 385 }, }; 266 267 271 private static CalendarCache cache = new CalendarCache(); 272 273 277 282 public HebrewCalendar() { 283 this(TimeZone.getDefault(), ULocale.getDefault()); 284 } 285 286 293 public HebrewCalendar(TimeZone zone) { 294 this(zone, ULocale.getDefault()); 295 } 296 297 304 public HebrewCalendar(Locale aLocale) { 305 this(TimeZone.getDefault(), aLocale); 306 } 307 308 316 public HebrewCalendar(ULocale locale) { 317 this(TimeZone.getDefault(), locale); 318 } 319 320 329 public HebrewCalendar(TimeZone zone, Locale aLocale) { 330 super(zone, aLocale); 331 setTimeInMillis(System.currentTimeMillis()); 332 } 333 334 344 public HebrewCalendar(TimeZone zone, ULocale locale) { 345 super(zone, locale); 346 setTimeInMillis(System.currentTimeMillis()); 347 } 348 349 361 public HebrewCalendar(int year, int month, int date) { 362 super(TimeZone.getDefault(), ULocale.getDefault()); 363 this.set(YEAR, year); 364 this.set(MONTH, month); 365 this.set(DATE, date); 366 } 367 368 375 public HebrewCalendar(Date date) { 376 super(TimeZone.getDefault(), ULocale.getDefault()); 377 this.setTime(date); 378 } 379 380 398 public HebrewCalendar(int year, int month, int date, int hour, 399 int minute, int second) 400 { 401 super(TimeZone.getDefault(), ULocale.getDefault()); 402 this.set(YEAR, year); 403 this.set(MONTH, month); 404 this.set(DATE, date); 405 this.set(HOUR_OF_DAY, hour); 406 this.set(MINUTE, minute); 407 this.set(SECOND, second); 408 } 409 410 417 444 public void add(int field, int amount) 445 { 446 switch (field) { 447 case MONTH: 448 { 449 int month = get(MONTH); 455 int year = get(YEAR); 456 boolean acrossAdar1; 457 if (amount > 0) { 458 acrossAdar1 = (month < ADAR_1); month += amount; 460 for (;;) { 461 if (acrossAdar1 && month>=ADAR_1 && !isLeapYear(year)) { 462 ++month; 463 } 464 if (month <= ELUL) { 465 break; 466 } 467 month -= ELUL+1; 468 ++year; 469 acrossAdar1 = true; 470 } 471 } else { 472 acrossAdar1 = (month > ADAR_1); month += amount; 474 for (;;) { 475 if (acrossAdar1 && month<=ADAR_1 && !isLeapYear(year)) { 476 --month; 477 } 478 if (month >= 0) { 479 break; 480 } 481 month += ELUL+1; 482 --year; 483 acrossAdar1 = true; 484 } 485 } 486 set(MONTH, month); 487 set(YEAR, year); 488 pinField(DAY_OF_MONTH); 489 break; 490 } 491 492 default: 493 super.add(field, amount); 494 break; 495 } 496 } 497 498 530 public void roll(int field, int amount) 531 { 532 switch (field) { 533 case MONTH: 534 { 535 int month = get(MONTH); 536 int year = get(YEAR); 537 538 boolean leapYear = isLeapYear(year); 539 int yearLength = monthsInYear(year); 540 int newMonth = month + (amount % yearLength); 541 if (!leapYear) { 546 if (amount > 0 && month < ADAR_1 && newMonth >= ADAR_1) { 547 newMonth++; 548 } else if (amount < 0 && month > ADAR_1 && newMonth <= ADAR_1) { 549 newMonth--; 550 } 551 } 552 set(MONTH, (newMonth + 13) % 13); 553 pinField(DAY_OF_MONTH); 554 return; 555 } 556 default: 557 super.roll(field, amount); 558 } 559 } 560 561 565 private static final long HOUR_PARTS = 1080; 568 private static final long DAY_PARTS = 24*HOUR_PARTS; 569 570 static private final int MONTH_DAYS = 29; 574 static private final long MONTH_FRACT = 12*HOUR_PARTS + 793; 575 static private final long MONTH_PARTS = MONTH_DAYS*DAY_PARTS + MONTH_FRACT; 576 577 static private final long BAHARAD = 11*HOUR_PARTS + 204; 581 582 602 private static long startOfYear(int year) 603 { 604 long day = cache.get(year); 605 606 if (day == CalendarCache.EMPTY) { 607 int months = (235 * year - 234) / 19; 609 long frac = months * MONTH_FRACT + BAHARAD; day = months * 29 + (frac / DAY_PARTS); frac = frac % DAY_PARTS; 613 int wd = (int)(day % 7); 615 if (wd == 2 || wd == 4 || wd == 6) { 616 day += 1; 618 wd = (int)(day % 7); 619 } 620 if (wd == 1 && frac > 15*HOUR_PARTS+204 && !isLeapYear(year) ) { 621 day += 2; 625 } 626 else if (wd == 0 && frac > 21*HOUR_PARTS+589 && isLeapYear(year-1) ) { 627 day += 1; 631 } 632 cache.put(year, day); 633 } 634 return day; 635 } 636 637 643 private static int absoluteDayToDayOfWeek(long day) 645 { 646 return (int)(day % 7) + 1; 648 } 649 651 657 private final int yearType(int year) 658 { 659 int yearLength = handleGetYearLength(year); 660 661 if (yearLength > 380) { 662 yearLength -= 30; } 664 665 int type = 0; 666 667 switch (yearLength) { 668 case 353: 669 type = 0; break; 670 case 354: 671 type = 1; break; 672 case 355: 673 type = 2; break; 674 default: 675 throw new IllegalArgumentException ("Illegal year length " + yearLength + " in year " + year); 676 677 } 678 return type; 679 } 680 681 687 private static final boolean isLeapYear(int year) { 688 int x = (year*12 + 17) % 19; 690 return x >= ((x < 0) ? -7 : 12); 691 } 692 693 private static int monthsInYear(int year) { 694 return isLeapYear(year) ? 13 : 12; 695 } 696 697 701 704 protected int handleGetLimit(int field, int limitType) { 705 return LIMITS[field][limitType]; 706 } 707 708 712 protected int handleGetMonthLength(int extendedYear, int month) { 713 714 switch (month) { 715 case HESHVAN: 716 case KISLEV: 717 return MONTH_LENGTH[month][yearType(extendedYear)]; 719 720 default: 721 return MONTH_LENGTH[month][0]; 723 } 724 } 725 726 730 protected int handleGetYearLength(int eyear) { 731 return (int)(startOfYear(eyear+1) - startOfYear(eyear)); 732 } 733 734 738 759 protected void handleComputeFields(int julianDay) { 760 long d = julianDay - 347997; 761 long m = (d * DAY_PARTS) / MONTH_PARTS; int year = (int)((19 * m + 234) / 235) + 1; long ys = startOfYear(year); int dayOfYear = (int)(d - ys); 765 766 while (dayOfYear < 1) { 768 year--; 769 ys = startOfYear(year); 770 dayOfYear = (int)(d - ys); 771 } 772 773 int yearType = yearType(year); 775 int monthStart[][] = isLeapYear(year) ? LEAP_MONTH_START : MONTH_START; 776 777 int month = 0; 778 while (dayOfYear > monthStart[month][yearType]) { 779 month++; 780 } 781 month--; 782 int dayOfMonth = dayOfYear - monthStart[month][yearType]; 783 784 internalSet(ERA, 0); 785 internalSet(YEAR, year); 786 internalSet(EXTENDED_YEAR, year); 787 internalSet(MONTH, month); 788 internalSet(DAY_OF_MONTH, dayOfMonth); 789 internalSet(DAY_OF_YEAR, dayOfYear); 790 } 791 792 796 799 protected int handleGetExtendedYear() { 800 int year; 801 if (newerField(EXTENDED_YEAR, YEAR) == EXTENDED_YEAR) { 802 year = internalGet(EXTENDED_YEAR, 1); } else { 804 year = internalGet(YEAR, 1); } 806 return year; 807 } 808 809 813 protected int handleComputeMonthStart(int eyear, int month, boolean useMonth) { 814 815 while (month < 0) { 822 month += monthsInYear(--eyear); 823 } 824 while (month > 12) { 826 month -= monthsInYear(eyear++); 827 } 828 829 long day = startOfYear(eyear); 830 831 if (month != 0) { 832 if (isLeapYear(eyear)) { 833 day += LEAP_MONTH_START[month][yearType(eyear)]; 834 } else { 835 day += MONTH_START[month][yearType(eyear)]; 836 } 837 } 838 839 return (int) (day + 347997); 840 } 841 842 848 public String getType() { 849 return "hebrew"; 850 } 851 852 869 } 870 | Popular Tags |