View Javadoc

1   /*
2    *  Copyright 2001-2009 Stephen Colebourne
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.joda.time.convert;
17  
18  import java.util.Calendar;
19  import java.util.GregorianCalendar;
20  
21  import org.joda.time.Chronology;
22  import org.joda.time.DateTimeZone;
23  import org.joda.time.chrono.BuddhistChronology;
24  import org.joda.time.chrono.GJChronology;
25  import org.joda.time.chrono.GregorianChronology;
26  import org.joda.time.chrono.ISOChronology;
27  import org.joda.time.chrono.JulianChronology;
28  
29  /**
30   * CalendarConverter converts a java util Calendar to an instant or partial.
31   * The Calendar is converted to milliseconds and the chronology that best
32   * matches the calendar.
33   *
34   * @author Stephen Colebourne
35   * @since 1.0
36   */
37  final class CalendarConverter extends AbstractConverter
38          implements InstantConverter, PartialConverter {
39  
40      /**
41       * Singleton instance.
42       */
43      static final CalendarConverter INSTANCE = new CalendarConverter();
44  
45      /**
46       * Restricted constructor.
47       */
48      protected CalendarConverter() {
49          super();
50      }
51  
52      //-----------------------------------------------------------------------
53      /**
54       * Gets the chronology.
55       * <p>
56       * If a chronology is specified then it is used.
57       * Otherwise, it is the GJChronology if a GregorianCalendar is used,
58       * BuddhistChronology if a BuddhistCalendar is used or ISOChronology otherwise.
59       * The time zone is extracted from the calendar if possible, default used if not.
60       * 
61       * @param object  the Calendar to convert, must not be null
62       * @param chrono  the chronology to use, null means use Calendar
63       * @return the chronology, never null
64       * @throws NullPointerException if the object is null
65       * @throws ClassCastException if the object is an invalid type
66       */
67      public Chronology getChronology(Object object, Chronology chrono) {
68          if (chrono != null) {
69              return chrono;
70          }
71          Calendar cal = (Calendar) object;
72          DateTimeZone zone = null;
73          try {
74              zone = DateTimeZone.forTimeZone(cal.getTimeZone());
75              
76          } catch (IllegalArgumentException ex) {
77              zone = DateTimeZone.getDefault();
78          }
79          return getChronology(cal, zone);
80      }
81  
82      /**
83       * Gets the chronology, which is the GJChronology if a GregorianCalendar is used,
84       * BuddhistChronology if a BuddhistCalendar is used or ISOChronology otherwise.
85       * The time zone specified is used in preference to that on the calendar.
86       * 
87       * @param object  the Calendar to convert, must not be null
88       * @param zone  the specified zone to use, null means default zone
89       * @return the chronology, never null
90       * @throws NullPointerException if the object is null
91       * @throws ClassCastException if the object is an invalid type
92       */
93      public Chronology getChronology(Object object, DateTimeZone zone) {
94          if (object.getClass().getName().endsWith(".BuddhistCalendar")) {
95              return BuddhistChronology.getInstance(zone);
96          } else if (object instanceof GregorianCalendar) {
97              GregorianCalendar gc = (GregorianCalendar) object;
98              long cutover = gc.getGregorianChange().getTime();
99              if (cutover == Long.MIN_VALUE) {
100                 return GregorianChronology.getInstance(zone);
101             } else if (cutover == Long.MAX_VALUE) {
102                 return JulianChronology.getInstance(zone);
103             } else {
104                 return GJChronology.getInstance(zone, cutover, 4);
105             }
106         } else {
107             return ISOChronology.getInstance(zone);
108         }
109     }
110 
111     /**
112      * Gets the millis, which is the Calendar millis value.
113      * 
114      * @param object  the Calendar to convert, must not be null
115      * @param chrono  the chronology result from getChronology, non-null
116      * @return the millisecond value
117      * @throws NullPointerException if the object is null
118      * @throws ClassCastException if the object is an invalid type
119      */
120     public long getInstantMillis(Object object, Chronology chrono) {
121         Calendar calendar = (Calendar) object;
122         return calendar.getTime().getTime();
123     }
124 
125     //-----------------------------------------------------------------------
126     /**
127      * Returns Calendar.class.
128      * 
129      * @return Calendar.class
130      */
131     public Class<?> getSupportedType() {
132         return Calendar.class;
133     }
134 
135 }