/[classpath]/classpath/java/util/GregorianCalendar.java
ViewVC logotype

Diff of /classpath/java/util/GregorianCalendar.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.34 by mkoch, Thu Jan 27 22:20:42 2005 UTC revision 1.35 by smarothy, Tue Feb 1 14:16:00 2005 UTC
# Line 182  public class GregorianCalendar extends C Line 182  public class GregorianCalendar extends C
182    private static final int EPOCH_DAYS = 719162;    private static final int EPOCH_DAYS = 719162;
183    
184    /**    /**
    * Retrieves the resource bundle.  The resources should be loaded  
    * via this method only. Iff an application uses this method, the  
    * resourcebundle is required.  
    *  
    * @param locale the locale in use for this calendar.  
    * @return A resource bundle for the calendar for the specified locale.  
    */  
   private static ResourceBundle getBundle(Locale locale)  
   {  
     return ResourceBundle.getBundle(bundleName, locale,  
                                     ClassLoader.getSystemClassLoader());  
   }  
   
   /**  
185     * Constructs a new GregorianCalender representing the current     * Constructs a new GregorianCalender representing the current
186     * time, using the default time zone and the default locale.     * time, using the default time zone and the default locale.
187     */     */
# Line 250  public class GregorianCalendar extends C Line 236  public class GregorianCalendar extends C
236    private GregorianCalendar(TimeZone zone, Locale locale, boolean unused)    private GregorianCalendar(TimeZone zone, Locale locale, boolean unused)
237    {    {
238      super(zone, locale);      super(zone, locale);
239      ResourceBundle rb = getBundle(locale);      ResourceBundle rb = ResourceBundle.getBundle(bundleName, locale,
240                                                     ClassLoader
241                                                     .getSystemClassLoader());
242      gregorianCutover = ((Date) rb.getObject("gregorianCutOver")).getTime();      gregorianCutover = ((Date) rb.getObject("gregorianCutOver")).getTime();
243    }    }
244    
# Line 376  public class GregorianCalendar extends C Line 364  public class GregorianCalendar extends C
364    }    }
365    
366    /**    /**
367     * <p>     * Returns the day of the week for the first day of a given month (0..11)
    * Calculate the dayOfYear from the fields array.  
    * The relativeDays is used, to account for weeks that begin before  
    * the Gregorian change and end after it.  
    * </p>  
    * <p>  
    * We return two values.  The first is used to determine, if we  
    * should use the Gregorian calendar or the Julian calendar, in order  
    * to handle the change year. The second is a relative day after the given  
    * day.  This is necessary for week calculation in the year in  
    * which the Gregorian change occurs.  
    * </p>  
    *  
    * @param year the year, negative for BC.  
    * @return an array of two integer values, the first containing a reference  
    * day in the current year, the second a relative count since this reference  
    * day.  
368     */     */
369    private int[] getDayOfYear(int year)    private int getFirstDayOfMonth(int year, int month)
370    {    {
371      if (isSet[MONTH])      int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
372        {      int dayOfYear = dayCount[month] + 1;
         int dayOfYear;  
         if (fields[MONTH] > FEBRUARY)  
           {  
             // The months after February are regular:  
             // 9 is an offset found by try and error.  
             dayOfYear = (fields[MONTH] * (31 + 30 + 31 + 30 + 31) - 9) / 5;  
             if (isLeapYear(year))  
               dayOfYear++;  
           }  
         else  
           dayOfYear = 31 * fields[MONTH];  
   
         if (isSet[DAY_OF_MONTH])  
           return new int[] { dayOfYear + fields[DAY_OF_MONTH], 0 };  
         if (isSet[WEEK_OF_MONTH] && isSet[DAY_OF_WEEK])  
           {  
             // the weekday of the first day in that month is:  
             int weekday = getWeekDay(year, ++dayOfYear);  
   
             return new int[]  
                    {  
                      dayOfYear,  
                      // the day of week in the first week  
             // (weeks starting on sunday) is:  
             fields[DAY_OF_WEEK] - weekday  
                      + // Now jump to the right week and correct the possible  
             // error made by assuming sunday is the first week day.  
             7 * (fields[WEEK_OF_MONTH]  
                      + (fields[DAY_OF_WEEK] < getFirstDayOfWeek() ? 0 : -1)  
                      + (weekday < getFirstDayOfWeek() ? -1 : 0))  
                    };  
           }  
         if (isSet[DAY_OF_WEEK] && isSet[DAY_OF_WEEK_IN_MONTH])  
           {  
             // the weekday of the first day in that month is:  
             int weekday = getWeekDay(year, ++dayOfYear);  
             return new int[]  
                    {  
                      dayOfYear,  
                      fields[DAY_OF_WEEK] - weekday  
                      + 7 * (fields[DAY_OF_WEEK_IN_MONTH]  
                      + (fields[DAY_OF_WEEK] < weekday ? 0 : -1))  
                    };  
           }  
       }  
373    
374      // MONTH + something did not succeed.      if (month > 1)
375      if (isSet[DAY_OF_YEAR])        if (isLeapYear(year))
376        return new int[] { 0, fields[DAY_OF_YEAR] };          dayOfYear++;
377    
378      if (isSet[DAY_OF_WEEK] && isSet[WEEK_OF_YEAR])      boolean greg = isGregorian(year, dayOfYear);
379        {      int day = (int) getLinearDay(year, dayOfYear, greg);
         int dayOfYear = getMinimalDaysInFirstWeek();  
   
         // the weekday of the day, that begins the first week  
         // in that year is:  
         int weekday = getWeekDay(year, dayOfYear);  
   
         return new int[]  
                {  
                  dayOfYear,  
                   
         // the day of week in the first week  
         // (weeks starting on sunday) is:  
         fields[DAY_OF_WEEK] - weekday  
                  // Now jump to the right week and correct the possible  
         // error made by assuming sunday is the first week day.  
                  + 7 * (fields[WEEK_OF_YEAR]  
                  + (fields[DAY_OF_WEEK] < getFirstDayOfWeek() ? 0 : -1)  
                  + (weekday < getFirstDayOfWeek() ? -1 : 0))  
                };  
       }  
380    
381      // As last resort return Jan, 1st.      // The epoch was a thursday.
382      return new int[] { 1, 0 };      int weekday = (day + THURSDAY) % 7;
383        if (weekday <= 0)
384          weekday += 7;
385        return weekday;
386    }    }
387    
388    /**    /**
# Line 490  public class GregorianCalendar extends C Line 400  public class GregorianCalendar extends C
400    }    }
401    
402    /**    /**
403       * Check set fields for validity, without leniency.
404       *
405       * @throws IllegalArgumentException if a field is invalid
406       */
407      private void nonLeniencyCheck() throws IllegalArgumentException
408      {
409        int[] month_days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
410        int year = fields[YEAR];
411        int month = fields[MONTH];
412        int leap = isLeapYear(year) ? 1 : 0;
413    
414        if (isSet[ERA] && fields[ERA] != AD && fields[ERA] != BC)
415          throw new IllegalArgumentException("Illegal ERA.");
416        if (isSet[YEAR] && fields[YEAR] < 1)
417          throw new IllegalArgumentException("Illegal YEAR.");
418        if (isSet[MONTH] && (month < 0 || month > 11))
419          throw new IllegalArgumentException("Illegal MONTH.");
420        if (isSet[WEEK_OF_YEAR])
421          {
422            int daysInYear = 365 + leap;
423            daysInYear += (getFirstDayOfMonth(year, 0) - 1); // pad first week
424            int last = getFirstDayOfMonth(year, 11) + 4;
425            if (last > 7)
426              last -= 7;
427            daysInYear += 7 - last;
428            int weeks = daysInYear / 7;
429            if (fields[WEEK_OF_YEAR] < 1 || fields[WEEK_OF_YEAR] > weeks)
430              throw new IllegalArgumentException("Illegal WEEK_OF_YEAR.");
431          }
432    
433        if (isSet[WEEK_OF_MONTH])
434          {
435            int weeks = (month == 1 && leap == 0) ? 4 : 5;
436            if (fields[WEEK_OF_MONTH] < 1 || fields[WEEK_OF_MONTH] > weeks)
437              throw new IllegalArgumentException("Illegal WEEK_OF_MONTH.");
438          }
439    
440        if (isSet[DAY_OF_MONTH])
441          if (fields[DAY_OF_MONTH] < 1
442              || fields[DAY_OF_MONTH] > month_days[month]
443              + ((month == 1) ? leap : 0))
444            throw new IllegalArgumentException("Illegal DAY_OF_MONTH.");
445    
446        if (isSet[DAY_OF_YEAR]
447            && (fields[DAY_OF_YEAR] < 1 || fields[DAY_OF_YEAR] > 365 + leap))
448          throw new IllegalArgumentException("Illegal DAY_OF_YEAR.");
449    
450        if (isSet[DAY_OF_WEEK]
451            && (fields[DAY_OF_WEEK] < 1 || fields[DAY_OF_WEEK] > 7))
452          throw new IllegalArgumentException("Illegal DAY_OF_WEEK.");
453    
454        if (isSet[DAY_OF_WEEK_IN_MONTH])
455          {
456            int weeks = (month == 1 && leap == 0) ? 4 : 5;
457            if (fields[DAY_OF_WEEK_IN_MONTH] < -weeks
458                || fields[DAY_OF_WEEK_IN_MONTH] > weeks)
459              throw new IllegalArgumentException("Illegal DAY_OF_WEEK_IN_MONTH.");
460          }
461    
462        if (isSet[AM_PM] && fields[AM_PM] != AM && fields[AM_PM] != PM)
463          throw new IllegalArgumentException("Illegal AM_PM.");
464        if (isSet[HOUR] && (fields[HOUR] < 0 || fields[HOUR] > 12))
465          throw new IllegalArgumentException("Illegal HOUR.");
466        if (isSet[HOUR_OF_DAY]
467            && (fields[HOUR_OF_DAY] < 0 || fields[HOUR_OF_DAY] > 23))
468          throw new IllegalArgumentException("Illegal HOUR_OF_DAY.");
469        if (isSet[MINUTE] && (fields[MINUTE] < 0 || fields[MINUTE] > 59))
470          throw new IllegalArgumentException("Illegal MINUTE.");
471        if (isSet[SECOND] && (fields[SECOND] < 0 || fields[SECOND] > 59))
472          throw new IllegalArgumentException("Illegal SECOND.");
473        if (isSet[MILLISECOND]
474            && (fields[MILLISECOND] < 0 || fields[MILLISECOND] > 999))
475          throw new IllegalArgumentException("Illegal MILLISECOND.");
476        if (isSet[ZONE_OFFSET]
477            && (fields[ZONE_OFFSET] < -12 * 60 * 60 * 1000L
478            || fields[ZONE_OFFSET] > 12 * 60 * 60 * 1000L))
479          throw new IllegalArgumentException("Illegal ZONE_OFFSET.");
480        if (isSet[DST_OFFSET]
481            && (fields[DST_OFFSET] < -12 * 60 * 60 * 1000L
482            || fields[DST_OFFSET] > 12 * 60 * 60 * 1000L))
483          throw new IllegalArgumentException("Illegal DST_OFFSET.");
484      }
485    
486      /**
487     * Converts the time field values (<code>fields</code>) to     * Converts the time field values (<code>fields</code>) to
488     * milliseconds since the epoch UTC (<code>time</code>).     * milliseconds since the epoch UTC (<code>time</code>).
489     *     *
# Line 498  public class GregorianCalendar extends C Line 492  public class GregorianCalendar extends C
492     */     */
493    protected synchronized void computeTime()    protected synchronized void computeTime()
494    {    {
495        // 1  YEAR + MONTH + DAY_OF_MONTH
496        // 2  YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
497        // 3  YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
498        // 4  YEAR + DAY_OF_YEAR
499        // 5  YEAR + DAY_OF_WEEK + WEEK_OF_YEAR
500      int millisInDay = 0;      int millisInDay = 0;
501      int era = isSet[ERA] ? fields[ERA] : AD;      int era = fields[ERA];
502      int year = isSet[YEAR] ? fields[YEAR] : 1970;      int year = fields[YEAR];
503      int month = isSet[MONTH] ? fields[MONTH] : 0;      int month = fields[MONTH];
504      int day = isSet[DAY_OF_MONTH] ? fields[DAY_OF_MONTH] : 1;      int day = fields[DAY_OF_MONTH];
505      int minute = isSet[MINUTE] ? fields[MINUTE] : 0;  
506      int second = isSet[SECOND] ? fields[SECOND] : 0;      int minute = fields[MINUTE];
507      int millis = isSet[MILLISECOND] ? fields[MILLISECOND] : 0;      int second = fields[SECOND];
508        int millis = fields[MILLISECOND];
509      int[] month_days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };      int[] month_days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
510      int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };      int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
511      int hour = 0;      int hour = 0;
512    
513        if (! isLenient())
514          nonLeniencyCheck();
515    
516        if (! isSet[MONTH])
517          {
518            if (isSet[DAY_OF_WEEK] || isSet[WEEK_OF_YEAR])
519              { // case 5
520                int first = getFirstDayOfMonth(year, 0);
521                int offs;
522                if ((8 - first) >= getMinimalDaysInFirstWeek())
523                  // start counting on first week
524                  offs = 1;
525                else
526                  offs = 1 + (8 - first);
527    
528                month = 0;
529                day = offs + 7 * (fields[WEEK_OF_YEAR] - 1);
530                day += fields[DAY_OF_WEEK] - first;
531              }
532            else
533              { // case 4
534                month = 0;
535                day = fields[DAY_OF_YEAR];
536              }
537          }
538        else
539          {
540            if (isSet[DAY_OF_WEEK])
541              {
542                int first = getFirstDayOfMonth(year, month);
543    
544                if (isSet[DAY_OF_WEEK_IN_MONTH])
545                  { // case 3
546                    int offs = fields[DAY_OF_WEEK] - first;
547                    if (offs < 0)
548                      offs += 7;
549                    day = 1 + 7 * (fields[DAY_OF_WEEK_IN_MONTH] - 1);
550                    day += offs;
551                  }
552                else
553                  { // case 2
554                    day = 1 + 7 * (fields[WEEK_OF_MONTH] - 1);
555                    day += fields[DAY_OF_WEEK] - first;
556                  }
557              }
558    
559            // case 1
560          }
561      if (era == BC && year > 0)      if (era == BC && year > 0)
562        year = 1 - year;        year = 1 - year;
563    
564        // rest of code assumes day/month/year set
565      // should negative BC years be AD?      // should negative BC years be AD?
566      // get the hour (but no check for validity)      // get the hour (but no check for validity)
567      if (isSet[HOUR_OF_DAY])      if (isSet[HOUR_OF_DAY])
# Line 528  public class GregorianCalendar extends C Line 577  public class GregorianCalendar extends C
577            hour = 0;            hour = 0;
578        }        }
579    
580      if (isLenient())      // Read the era,year,month,day fields and convert as appropriate.
581        {      // Calculate number of milliseconds into the day
582          // Read the era,year,month,day fields and convert as appropriate.      // This takes care of both h, m, s, ms over/underflows.
583          // Calculate number of milliseconds into the day      long allMillis = (((hour * 60L) + minute) * 60L + second) * 1000L + millis;
584          // This takes care of both h, m, s, ms over/underflows.      day += allMillis / (24 * 60 * 60 * 1000L);
585          long allMillis = (((hour * 60L) + minute) * 60L + second) * 1000L      millisInDay = (int) (allMillis % (24 * 60 * 60 * 1000L));
                          + millis;  
         day += allMillis / (24 * 60 * 60 * 1000L);  
         millisInDay = (int) (allMillis % (24 * 60 * 60 * 1000L));  
586    
587          if (isSet[MONTH])      if (month < 0)
588          {
589            year += (int) month / 12;
590            month = month % 12;
591            if (month < 0)
592            {            {
593              if (month < 0)              month += 12;
594                {              year--;
                 year += (int) month / 12;  
                 month = month % 12;  
                 if (month < 0)  
                   {  
                     month += 12;  
                     year--;  
                   }  
               }  
             if (month > 11)  
               {  
                 year += (month / 12);  
                 month = month % 12;  
               }  
595            }            }
596          }
597        if (month > 11)
598          {
599            year += (month / 12);
600            month = month % 12;
601          }
602    
603        month_days[1] = isLeapYear(year) ? 29 : 28;
604    
605          if (isSet[DAY_OF_MONTH])      while (day <= 0)
606          {
607            if (month == 0)
608            {            {
609                year--;
610              month_days[1] = isLeapYear(year) ? 29 : 28;              month_days[1] = isLeapYear(year) ? 29 : 28;
   
             while (day <= 0)  
               {  
                 if (month == 0)  
                   {  
                     year--;  
                     month_days[1] = isLeapYear(year) ? 29 : 28;  
                   }  
                 month = (month + 11) % 12;  
                 day += month_days[month];  
               }  
             while (day > month_days[month])  
               {  
                 day -= (month_days[month]);  
                 month = (month + 1) % 12;  
                 if (month == 0)  
                   {  
                     year++;  
                     month_days[1] = isLeapYear(year) ? 29 : 28;  
                   }  
               }  
611            }            }
612            month = (month + 11) % 12;
613            day += month_days[month];
614        }        }
615      else      while (day > month_days[month])
616        {        {
617          // non-lenient          day -= (month_days[month]);
618          if (month < 0 || month > 11 || hour < 0 || hour >= 24 || minute < 0          month = (month + 1) % 12;
619              || minute > 59 || second < 0 || second > 59 || millis < 0          if (month == 0)
620              || millis >= 1000)            {
621            throw new IllegalArgumentException();              year++;
622          if (day < 1 || day > month_days[month])              month_days[1] = isLeapYear(year) ? 29 : 28;
623            throw new IllegalArgumentException();            }
         millisInDay = (((hour * 60) + minute) * 60 + second) * 1000 + millis;  
624        }        }
625    
626      // ok, by here we have valid day,month,year,era and millisinday      // ok, by here we have valid day,month,year,era and millisinday

Legend:
Removed from v.1.34  
changed lines
  Added in v.1.35

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26