View Javadoc
1   /*
2   Copyright (c) 2017 James Ahlborn
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  
17  package com.healthmarketscience.jackcess.expr;
18  
19  import java.text.DateFormatSymbols;
20  import java.util.Locale;
21  
22  /**
23   * A TemporalConfig encapsulates date/time formatting options for expression
24   * evaluation.  The default {@link #US_TEMPORAL_CONFIG} instance provides US
25   * specific locale configuration.  Databases which have been built for other
26   * locales can utilize custom implementations of TemporalConfig in order to
27   * evaluate expressions correctly.
28   *
29   * @author James Ahlborn
30   */
31  public class TemporalConfig
32  {
33    public static final String US_DATE_FORMAT = "M/d[/uuuu]";
34    public static final String US_TIME_FORMAT_12_FORMAT = "h:mm:ss a";
35    public static final String US_TIME_FORMAT_24_FORMAT = "H:mm:ss";
36    public static final String US_LONG_DATE_FORMAT = "EEEE, MMMM dd, uuuu";
37  
38    public static final String MEDIUM_DATE_FORMAT = "dd-MMM-uu";
39    public static final String MEDIUM_TIME_FORMAT = "hh:mm a";
40    public static final String SHORT_TIME_FORMAT = "HH:mm";
41  
42    /** default implementation which is configured for the US locale */
43    public static final TemporalConfignfig.html#TemporalConfig">TemporalConfig US_TEMPORAL_CONFIG = new TemporalConfig(
44        US_DATE_FORMAT, US_LONG_DATE_FORMAT,
45        US_TIME_FORMAT_12_FORMAT, US_TIME_FORMAT_24_FORMAT, '/', ':', Locale.US);
46  
47    public enum Type {
48      DATE, TIME, DATE_TIME, TIME_12, TIME_24, DATE_TIME_12, DATE_TIME_24,
49      GENERAL_DATE, LONG_DATE, MEDIUM_DATE, SHORT_DATE,
50      LONG_TIME, MEDIUM_TIME, SHORT_TIME;
51  
52      public Type getDefaultType() {
53        switch(this) {
54        case DATE:
55        case LONG_DATE:
56        case MEDIUM_DATE:
57        case SHORT_DATE:
58          return DATE;
59        case TIME:
60        case TIME_12:
61        case TIME_24:
62        case LONG_TIME:
63        case MEDIUM_TIME:
64        case SHORT_TIME:
65          return TIME;
66        case DATE_TIME:
67        case DATE_TIME_12:
68        case DATE_TIME_24:
69        case GENERAL_DATE:
70          return DATE_TIME;
71        default:
72          throw new RuntimeException("invalid type " + this);
73        }
74      }
75  
76      public Value.Type getValueType() {
77        switch(this) {
78        case DATE:
79        case LONG_DATE:
80        case MEDIUM_DATE:
81        case SHORT_DATE:
82          return Value.Type.DATE;
83        case TIME:
84        case TIME_12:
85        case TIME_24:
86        case LONG_TIME:
87        case MEDIUM_TIME:
88        case SHORT_TIME:
89          return Value.Type.TIME;
90        case DATE_TIME:
91        case DATE_TIME_12:
92        case DATE_TIME_24:
93        case GENERAL_DATE:
94          return Value.Type.DATE_TIME;
95        default:
96          throw new RuntimeException("invalid type " + this);
97        }
98      }
99  
100     public boolean includesTime() {
101       return !isDateOnly();
102     }
103 
104     public boolean includesDate() {
105       return !isTimeOnly();
106     }
107 
108     public boolean isDateOnly() {
109       switch(this) {
110       case DATE:
111       case LONG_DATE:
112       case MEDIUM_DATE:
113       case SHORT_DATE:
114         return true;
115       default:
116         return false;
117       }
118     }
119 
120     public boolean isTimeOnly() {
121       switch(this) {
122       case TIME:
123       case TIME_12:
124       case TIME_24:
125       case LONG_TIME:
126       case MEDIUM_TIME:
127       case SHORT_TIME:
128         return true;
129       default:
130         return false;
131       }
132     }
133   }
134 
135   private final Locale _locale;
136   private final String _dateFormat;
137   private final String _longDateFormat;
138   private final String _timeFormat12;
139   private final String _timeFormat24;
140   private final char _dateSeparator;
141   private final char _timeSeparator;
142   private final String _dateTimeFormat12;
143   private final String _dateTimeFormat24;
144   private final String[] _amPmStrings;
145 
146   /**
147    * Instantiates a new TemporalConfig with the given configuration.  Note
148    * that the date/time format variants will be created by concatenating the
149    * relevant date and time formats, separated by a single space,
150    * e.g. "<date> <time>".
151    *
152    * @param dateFormat the date (no time) format
153    * @param timeFormat12 the 12 hour time format
154    * @param timeFormat24 the 24 hour time format
155    * @param dateSeparator the primary separator used to separate elements in
156    *                      the date format.  this is used to identify the
157    *                      components of date/time string.
158    * @param timeSeparator the primary separator used to separate elements in
159    *                      the time format (both 12 hour and 24 hour).  this is
160    *                      used to identify the components of a date/time
161    *                      string.  This value should differ from the
162    *                      dateSeparator.
163    */
164   public TemporalConfig(String dateFormat, String longDateFormat,
165                         String timeFormat12, String timeFormat24,
166                         char dateSeparator, char timeSeparator, Locale locale)
167   {
168     _locale = locale;
169     _dateFormat = dateFormat;
170     _longDateFormat = longDateFormat;
171     _timeFormat12 = timeFormat12;
172     _timeFormat24 = timeFormat24;
173     _dateSeparator = dateSeparator;
174     _timeSeparator = timeSeparator;
175     _dateTimeFormat12 = toDateTimeFormat(_dateFormat, _timeFormat12);
176     _dateTimeFormat24 = toDateTimeFormat(_dateFormat, _timeFormat24);
177     // there doesn't seem to be a good/easy way to get this in new jave.time
178     // api, so just use old api
179     _amPmStrings = DateFormatSymbols.getInstance(locale).getAmPmStrings();
180   }
181 
182   public Locale getLocale() {
183     return _locale;
184   }
185 
186   public String getDateFormat() {
187     return _dateFormat;
188   }
189 
190   public String getTimeFormat12() {
191     return _timeFormat12;
192   }
193 
194   public String getTimeFormat24() {
195     return _timeFormat24;
196   }
197 
198   public String getDateTimeFormat12() {
199     return _dateTimeFormat12;
200   }
201 
202   public String getDateTimeFormat24() {
203     return _dateTimeFormat24;
204   }
205 
206   public String getDefaultDateFormat() {
207     return getDateFormat();
208   }
209 
210   public String getDefaultTimeFormat() {
211     return getTimeFormat12();
212   }
213 
214   public String getDefaultDateTimeFormat() {
215     return getDateTimeFormat12();
216   }
217 
218   public char getDateSeparator() {
219     return _dateSeparator;
220   }
221 
222   public char getTimeSeparator() {
223     return _timeSeparator;
224   }
225 
226   public String getDateTimeFormat(Type type) {
227     switch(type) {
228     case DATE:
229     case SHORT_DATE:
230       return getDefaultDateFormat();
231     case TIME:
232       return getDefaultTimeFormat();
233     case DATE_TIME:
234     case GENERAL_DATE:
235       return getDefaultDateTimeFormat();
236     case TIME_12:
237     case LONG_TIME:
238       return getTimeFormat12();
239     case TIME_24:
240       return getTimeFormat24();
241     case DATE_TIME_12:
242       return getDateTimeFormat12();
243     case DATE_TIME_24:
244       return getDateTimeFormat24();
245     case LONG_DATE:
246       return getLongDateFormat();
247     case MEDIUM_DATE:
248       return getMediumDateFormat();
249     case MEDIUM_TIME:
250       return getMediumTimeFormat();
251     case SHORT_TIME:
252       return getShortTimeFormat();
253     default:
254       throw new IllegalArgumentException("unknown date/time type " + type);
255     }
256   }
257 
258   public String[] getAmPmStrings() {
259     return _amPmStrings;
260   }
261 
262   private static String toDateTimeFormat(String dateFormat, String timeFormat) {
263     return dateFormat + " " + timeFormat;
264   }
265 
266   protected String getLongDateFormat() {
267     return _longDateFormat;
268   }
269 
270   protected String getMediumDateFormat() {
271     return MEDIUM_DATE_FORMAT;
272   }
273 
274   protected String getMediumTimeFormat() {
275     return MEDIUM_TIME_FORMAT;
276   }
277 
278   protected String getShortTimeFormat() {
279     return SHORT_TIME_FORMAT;
280   }
281 }