/[classpath]/classpath/java/text/SimpleDateFormat.java
ViewVC logotype

Diff of /classpath/java/text/SimpleDateFormat.java

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

revision 1.28.2.1 by gnu_andrew, Sat Jan 15 17:02:16 2005 UTC revision 1.28.2.2 by gnu_andrew, Sun Jan 16 15:15:12 2005 UTC
# Line 341  public class SimpleDateFormat extends Da Line 341  public class SimpleDateFormat extends Da
341    }    }
342    
343    /**    /**
344     * This method returns the format symbol information used for parsing     * This method returns a copy of the format symbol information used
345     * and formatting dates.     * for parsing and formatting dates.
346     *     *
347     * @return The date format symbols.     * @return a copy of the date format symbols.
348     */     */
349    public DateFormatSymbols getDateFormatSymbols()    public DateFormatSymbols getDateFormatSymbols()
350    {    {
351      return formatData;      return (DateFormatSymbols) formatData.clone();
352    }    }
353    
354    /**    /**
# Line 356  public class SimpleDateFormat extends Da Line 356  public class SimpleDateFormat extends Da
356     * and formatting dates.     * and formatting dates.
357     *     *
358     * @param formatData The date format symbols.     * @param formatData The date format symbols.
359       * @throws NullPointerException if <code>formatData</code> is null.
360     */     */
361     public void setDateFormatSymbols(DateFormatSymbols formatData)     public void setDateFormatSymbols(DateFormatSymbols formatData)
362     {     {
363         if (formatData == null)
364           {
365             throw new
366               NullPointerException("The supplied format data was null.");
367           }
368       this.formatData = formatData;       this.formatData = formatData;
369     }     }
370    
# Line 614  public class SimpleDateFormat extends Da Line 620  public class SimpleDateFormat extends Da
620      boolean saw_timezone = false;      boolean saw_timezone = false;
621      int quote_start = -1;      int quote_start = -1;
622      boolean is2DigitYear = false;      boolean is2DigitYear = false;
623      for (; fmt_index < fmt_max; ++fmt_index)      try
624        {        {
625          char ch = pattern.charAt(fmt_index);          for (; fmt_index < fmt_max; ++fmt_index)
         if (ch == '\'')  
626            {            {
627              int index = pos.getIndex();              char ch = pattern.charAt(fmt_index);
628              if (fmt_index < fmt_max - 1              if (ch == '\'')
629                  && pattern.charAt(fmt_index + 1) == '\'')                {
630                    int index = pos.getIndex();
631                    if (fmt_index < fmt_max - 1
632                        && pattern.charAt(fmt_index + 1) == '\'')
633                      {
634                        if (! expect (dateStr, pos, ch))
635                          return null;
636                        ++fmt_index;
637                      }
638                    else
639                      quote_start = quote_start < 0 ? fmt_index : -1;
640                    continue;
641                  }
642                
643                if (quote_start != -1
644                    || ((ch < 'a' || ch > 'z')
645                        && (ch < 'A' || ch > 'Z')))
646                {                {
647                  if (! expect (dateStr, pos, ch))                  if (! expect (dateStr, pos, ch))
648                    return null;                    return null;
649                  ++fmt_index;                  continue;
650                }                }
651              else              
652                quote_start = quote_start < 0 ? fmt_index : -1;              // We've arrived at a potential pattern character in the
653              continue;              // pattern.
654            }              int fmt_count = 1;
655                while (++fmt_index < fmt_max && pattern.charAt(fmt_index) == ch)
         if (quote_start != -1  
             || ((ch < 'a' || ch > 'z')  
                 && (ch < 'A' || ch > 'Z')))  
           {  
             if (! expect (dateStr, pos, ch))  
               return null;  
             continue;  
           }  
   
         // We've arrived at a potential pattern character in the  
         // pattern.  
         int first = fmt_index;  
         while (++fmt_index < fmt_max && pattern.charAt(fmt_index) == ch)  
           ;  
         int fmt_count = fmt_index - first;  
   
         // We might need to limit the number of digits to parse in  
         // some cases.  We look to the next pattern character to  
         // decide.  
         boolean limit_digits = false;  
         if (fmt_index < fmt_max  
             && standardChars.indexOf(pattern.charAt(fmt_index)) >= 0)  
           limit_digits = true;  
         --fmt_index;  
   
         // We can handle most fields automatically: most either are  
         // numeric or are looked up in a string vector.  In some cases  
         // we need an offset.  When numeric, `offset' is added to the  
         // resulting value.  When doing a string lookup, offset is the  
         // initial index into the string array.  
         int calendar_field;  
         boolean is_numeric = true;  
         String[] match = null;  
         int offset = 0;  
         boolean maybe2DigitYear = false;  
         switch (ch)  
           {  
           case 'd':  
             calendar_field = Calendar.DATE;  
             break;  
           case 'D':  
             calendar_field = Calendar.DAY_OF_YEAR;  
             break;  
           case 'F':  
             calendar_field = Calendar.DAY_OF_WEEK_IN_MONTH;  
             break;  
           case 'E':  
             is_numeric = false;  
             offset = 1;  
             calendar_field = Calendar.DAY_OF_WEEK;  
             match = (fmt_count <= 3  
                      ? formatData.getShortWeekdays()  
                      : formatData.getWeekdays());  
             break;  
           case 'w':  
             calendar_field = Calendar.WEEK_OF_YEAR;  
             break;  
           case 'W':  
             calendar_field = Calendar.WEEK_OF_MONTH;  
             break;  
           case 'M':  
             calendar_field = Calendar.MONTH;  
             if (fmt_count <= 2)  
               offset = -1;  
             else  
656                {                {
657                  is_numeric = false;                  ++fmt_count;
                 match = (fmt_count <= 3  
                          ? formatData.getShortMonths()  
                          : formatData.getMonths());  
658                }                }
659              break;              
660            case 'y':              // We might need to limit the number of digits to parse in
661              calendar_field = Calendar.YEAR;              // some cases.  We look to the next pattern character to
662              if (fmt_count <= 2)              // decide.
663                maybe2DigitYear = true;              boolean limit_digits = false;
664              break;              if (fmt_index < fmt_max
665            case 'K':                  && standardChars.indexOf(pattern.charAt(fmt_index)) >= 0)
666              calendar_field = Calendar.HOUR;                limit_digits = true;
667              break;              --fmt_index;
668            case 'h':              
669              calendar_field = Calendar.HOUR;              // We can handle most fields automatically: most either are
670              break;              // numeric or are looked up in a string vector.  In some cases
671            case 'H':              // we need an offset.  When numeric, `offset' is added to the
672              calendar_field = Calendar.HOUR_OF_DAY;              // resulting value.  When doing a string lookup, offset is the
673              break;              // initial index into the string array.
674            case 'k':              int calendar_field;
675              calendar_field = Calendar.HOUR_OF_DAY;              boolean is_numeric = true;
676              break;              String[] match = null;
677            case 'm':              int offset = 0;
678              calendar_field = Calendar.MINUTE;              boolean maybe2DigitYear = false;
679              break;              switch (ch)
           case 's':  
             calendar_field = Calendar.SECOND;  
             break;  
           case 'S':  
             calendar_field = Calendar.MILLISECOND;  
             break;  
           case 'a':  
             is_numeric = false;  
             calendar_field = Calendar.AM_PM;  
             match = formatData.getAmPmStrings();  
             break;  
           case 'z':  
             // We need a special case for the timezone, because it  
             // uses a different data structure than the other cases.  
             is_numeric = false;  
             calendar_field = Calendar.DST_OFFSET;  
             String[][] zoneStrings = formatData.getZoneStrings();  
             int zoneCount = zoneStrings.length;  
             int index = pos.getIndex();  
             boolean found_zone = false;  
             for (int j = 0;  j < zoneCount;  j++)  
680                {                {
681                  String[] strings = zoneStrings[j];                case 'd':
682                  int k;                  calendar_field = Calendar.DATE;
683                  for (k = 1; k < strings.length; ++k)                  break;
684                  case 'D':
685                    calendar_field = Calendar.DAY_OF_YEAR;
686                    break;
687                  case 'F':
688                    calendar_field = Calendar.DAY_OF_WEEK_IN_MONTH;
689                    break;
690                  case 'E':
691                    is_numeric = false;
692                    offset = 1;
693                    calendar_field = Calendar.DAY_OF_WEEK;
694                    match = (fmt_count <= 3
695                             ? formatData.getShortWeekdays()
696                             : formatData.getWeekdays());
697                    break;
698                  case 'w':
699                    calendar_field = Calendar.WEEK_OF_YEAR;
700                    break;
701                  case 'W':
702                    calendar_field = Calendar.WEEK_OF_MONTH;
703                    break;
704                  case 'M':
705                    calendar_field = Calendar.MONTH;
706                    if (fmt_count <= 2)
707                      offset = -1;
708                    else
709                    {                    {
710                      if (dateStr.startsWith(strings[k], index))                      is_numeric = false;
711                        break;                      match = (fmt_count == 3
712                                 ? formatData.getShortMonths()
713                                 : formatData.getMonths());
714                    }                    }
715                  if (k != strings.length)                  break;
716                  case 'y':
717                    calendar_field = Calendar.YEAR;
718                    if (fmt_count <= 2)
719                      maybe2DigitYear = true;
720                    break;
721                  case 'K':
722                    calendar_field = Calendar.HOUR;
723                    break;
724                  case 'h':
725                    calendar_field = Calendar.HOUR;
726                    break;
727                  case 'H':
728                    calendar_field = Calendar.HOUR_OF_DAY;
729                    break;
730                  case 'k':
731                    calendar_field = Calendar.HOUR_OF_DAY;
732                    break;
733                  case 'm':
734                    calendar_field = Calendar.MINUTE;
735                    break;
736                  case 's':
737                    calendar_field = Calendar.SECOND;
738                    break;
739                  case 'S':
740                    calendar_field = Calendar.MILLISECOND;
741                    break;
742                  case 'a':
743                    is_numeric = false;
744                    calendar_field = Calendar.AM_PM;
745                    match = formatData.getAmPmStrings();
746                    break;
747                  case 'z':
748                    // We need a special case for the timezone, because it
749                    // uses a different data structure than the other cases.
750                    is_numeric = false;
751                    calendar_field = Calendar.DST_OFFSET;
752                    String[][] zoneStrings = formatData.getZoneStrings();
753                    int zoneCount = zoneStrings.length;
754                    int index = pos.getIndex();
755                    boolean found_zone = false;
756                    for (int j = 0;  j < zoneCount;  j++)
757                    {                    {
758                      found_zone = true;                      String[] strings = zoneStrings[j];
759                      saw_timezone = true;                      int k;
760                      TimeZone tz = TimeZone.getTimeZone (strings[0]);                      for (k = 1; k < strings.length; ++k)
                     calendar.set (Calendar.ZONE_OFFSET, tz.getRawOffset ());  
                     offset = 0;  
                     if (k > 2 && tz instanceof SimpleTimeZone)  
761                        {                        {
762                          SimpleTimeZone stz = (SimpleTimeZone) tz;                          if (dateStr.startsWith(strings[k], index))
763                          offset = stz.getDSTSavings ();                            break;
764                          }
765                        if (k != strings.length)
766                          {
767                            found_zone = true;
768                            saw_timezone = true;
769                            TimeZone tz = TimeZone.getTimeZone (strings[0]);
770                            calendar.set (Calendar.ZONE_OFFSET, tz.getRawOffset ());
771                            offset = 0;
772                            if (k > 2 && tz instanceof SimpleTimeZone)
773                              {
774                                SimpleTimeZone stz = (SimpleTimeZone) tz;
775                                offset = stz.getDSTSavings ();
776                              }
777                            pos.setIndex(index + strings[k].length());
778                            break;
779                        }                        }
                     pos.setIndex(index + strings[k].length());  
                     break;  
780                    }                    }
781                }                  if (! found_zone)
782              if (! found_zone)                    {
783                {                      pos.setErrorIndex(pos.getIndex());
784                        return null;
785                      }
786                    break;
787                  default:
788                  pos.setErrorIndex(pos.getIndex());                  pos.setErrorIndex(pos.getIndex());
789                  return null;                  return null;
790                }                }
791              break;              
792            default:              // Compute the value we should assign to the field.
793              pos.setErrorIndex(pos.getIndex());              int value;
794              return null;              int index = -1;
795            }              if (is_numeric)
   
         // Compute the value we should assign to the field.  
         int value;  
         int index = -1;  
         if (is_numeric)  
           {  
             numberFormat.setMinimumIntegerDigits(fmt_count);  
             if (limit_digits)  
               numberFormat.setMaximumIntegerDigits(fmt_count);  
             if (maybe2DigitYear)  
               index = pos.getIndex();  
             Number n = numberFormat.parse(dateStr, pos);  
             if (pos == null || ! (n instanceof Long))  
               return null;  
             value = n.intValue() + offset;  
           }  
         else if (match != null)  
           {  
             index = pos.getIndex();  
             int i;  
             for (i = offset; i < match.length; ++i)  
796                {                {
797                  if (dateStr.startsWith(match[i], index))                  numberFormat.setMinimumIntegerDigits(fmt_count);
798                    break;                  if (limit_digits)
799                      numberFormat.setMaximumIntegerDigits(fmt_count);
800                    if (maybe2DigitYear)
801                      index = pos.getIndex();
802                    Number n = numberFormat.parse(dateStr, pos);
803                    if (pos == null || ! (n instanceof Long))
804                      return null;
805                    value = n.intValue() + offset;
806                }                }
807              if (i == match.length)              else if (match != null)
808                {                {
809                  pos.setErrorIndex(index);                  index = pos.getIndex();
810                  return null;                  int i;
811                    for (i = offset; i < match.length; ++i)
812                      {
813                        if (match[i] != null)
814                          if (dateStr.toUpperCase().startsWith(match[i].toUpperCase(),
815                                                               index))
816                            break;
817                      }
818                    if (i == match.length)
819                      {
820                        pos.setErrorIndex(index);
821                        return null;
822                      }
823                    pos.setIndex(index + match[i].length());
824                    value = i;
825                }                }
826              pos.setIndex(index + match[i].length());              else
827              value = i;                value = offset;
           }  
         else  
           value = offset;  
828                        
829          if (maybe2DigitYear)              if (maybe2DigitYear)
830            {                {
831              // Parse into default century if the numeric year string has                  // Parse into default century if the numeric year string has
832              // exactly 2 digits.                  // exactly 2 digits.
833              int digit_count = pos.getIndex() - index;                  int digit_count = pos.getIndex() - index;
834              if (digit_count == 2)                  if (digit_count == 2)
835                is2DigitYear = true;                    is2DigitYear = true;
836                  }
837                
838                // Assign the value and move on.
839                calendar.set(calendar_field, value);
840            }            }
   
         // Assign the value and move on.  
         calendar.set(calendar_field, value);  
       }  
841            
842      if (is2DigitYear)          if (is2DigitYear)
843        {            {
844          // Apply the 80-20 heuristic to dermine the full year based on              // Apply the 80-20 heuristic to dermine the full year based on
845          // defaultCenturyStart.              // defaultCenturyStart.
846          int year = defaultCentury + calendar.get(Calendar.YEAR);              int year = defaultCentury + calendar.get(Calendar.YEAR);
847          calendar.set(Calendar.YEAR, year);              calendar.set(Calendar.YEAR, year);
848          if (calendar.getTime().compareTo(defaultCenturyStart) < 0)              if (calendar.getTime().compareTo(defaultCenturyStart) < 0)
849            calendar.set(Calendar.YEAR, year + 100);                      calendar.set(Calendar.YEAR, year + 100);      
850        }            }
   
     try  
       {  
851          if (! saw_timezone)          if (! saw_timezone)
852            {            {
853              // Use the real rules to determine whether or not this              // Use the real rules to determine whether or not this
# Line 864  public class SimpleDateFormat extends Da Line 872  public class SimpleDateFormat extends Da
872      calendar.set(Calendar.YEAR, year - 80);      calendar.set(Calendar.YEAR, year - 80);
873      set2DigitYearStart(calendar.getTime());      set2DigitYearStart(calendar.getTime());
874    }    }
875    
876      /**
877       * Returns a copy of this instance of
878       * <code>SimpleDateFormat</code>.  The copy contains
879       * clones of the formatting symbols and the 2-digit
880       * year century start date.
881       */
882      public Object clone()
883      {
884        SimpleDateFormat clone = (SimpleDateFormat) super.clone();
885        clone.setDateFormatSymbols((DateFormatSymbols) formatData.clone());
886        clone.set2DigitYearStart((Date) defaultCenturyStart.clone());
887        return clone;
888      }
889    
890  }  }

Legend:
Removed from v.1.28.2.1  
changed lines
  Added in v.1.28.2.2

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