This project has retired. For details please refer to its Attic page.
CalendarHelper xref

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   *
19   * Authors:
20   *     Florent Guillaume, Nuxeo
21   */
22  package org.apache.chemistry.opencmis.server.support.query;
23  
24  import java.util.Calendar;
25  import java.util.GregorianCalendar;
26  import java.util.TimeZone;
27  import java.util.regex.Matcher;
28  import java.util.regex.Pattern;
29  
30  /**
31   * Helper dealing with conversion of {@link Calendar} to and from the string
32   * format specified by CMISQL.
33   */
34  public class CalendarHelper {
35  
36      private static final Pattern CMISQL_PATTERN = Pattern.compile( //
37              "(\\d{4})-(\\d{2})-(\\d{2})[Tt]" + "(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?"
38                      + "(?:[Zz]|([+-]\\d{2}:\\d{2}))?");
39  
40      private CalendarHelper() {
41          // utility class
42      }
43  
44      /**
45       * Converts a CMISQL date string representation to a
46       * {@link GregorianCalendar}.
47       * <p>
48       * Parses {@code YYYY-HH-MMThh:mm:ss.sss+hh:mm}, or a {@code Z} for the
49       * timezone, and with {@code .sss} being optional.
50       *
51       * @param datetime
52       *            the string representation in CMISQL format
53       * @return the created instance
54       */
55      public static GregorianCalendar fromString(String datetime) {
56          Matcher m = CMISQL_PATTERN.matcher(datetime);
57          if (!m.matches()) {
58              throw new IllegalArgumentException("Invalid datetime format: " + datetime);
59          }
60          String tz = m.group(8);
61          GregorianCalendar cal = (GregorianCalendar) GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT"
62                  + (tz == null ? "" : tz)));
63          cal.set(Calendar.YEAR, Integer.parseInt(m.group(1)));
64          cal.set(Calendar.MONTH, Integer.parseInt(m.group(2)) - 1);
65          cal.set(Calendar.DATE, Integer.parseInt(m.group(3)));
66          cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(m.group(4)));
67          cal.set(Calendar.MINUTE, Integer.parseInt(m.group(5)));
68          cal.set(Calendar.SECOND, Integer.parseInt(m.group(6)));
69          String decimals = m.group(7);
70          int ms = decimals == null ? 0 : Integer.parseInt((decimals + "00").substring(0, 3));
71          cal.set(Calendar.MILLISECOND, ms);
72          return cal;
73      }
74  
75      /**
76       * Converts a Calendar to its CMISQL string representation.
77       *
78       * @param cal
79       *            a {@link Calendar}
80       * @return the CMISQL string representation
81       */
82      public static String toString(Calendar cal) {
83          StringBuilder buf = new StringBuilder(28);
84          toString(cal, buf);
85          return buf.toString();
86      }
87  
88      /**
89       * Converts a Calendar to its CMISQL string representation.
90       *
91       * @param cal
92       *            a {@link Calendar}
93       * @param buf
94       *            a buffer in which to add the CMISQL string representation
95       */
96      public static void toString(Calendar cal, StringBuilder buf) {
97          buf.append(cal.get(Calendar.YEAR));
98          buf.append('-');
99          int f = cal.get(Calendar.MONTH);
100         if (f < 9) {
101             buf.append('0');
102         }
103         buf.append(f + 1);
104         buf.append('-');
105         f = cal.get(Calendar.DATE);
106         if (f < 10) {
107             buf.append('0');
108         }
109         buf.append(f);
110         buf.append('T');
111         f = cal.get(Calendar.HOUR_OF_DAY);
112         if (f < 10) {
113             buf.append('0');
114         }
115         buf.append(f);
116         buf.append(':');
117         f = cal.get(Calendar.MINUTE);
118         if (f < 10) {
119             buf.append('0');
120         }
121         buf.append(f);
122         buf.append(':');
123         f = cal.get(Calendar.SECOND);
124         if (f < 10) {
125             buf.append('0');
126         }
127         buf.append(f);
128         buf.append('.');
129         f = cal.get(Calendar.MILLISECOND);
130         if (f < 100) {
131             buf.append('0');
132         }
133         if (f < 10) {
134             buf.append('0');
135         }
136         buf.append(f);
137         int offset = cal.getTimeZone().getOffset(cal.getTimeInMillis()) / 60000;
138         if (offset == 0) {
139             buf.append('Z');
140         } else {
141             char sign;
142             if (offset < 0) {
143                 offset = -offset;
144                 sign = '-';
145             } else {
146                 sign = '+';
147             }
148             buf.append(sign);
149             f = offset / 60;
150             if (f < 10) {
151                 buf.append('0');
152             }
153             buf.append(f);
154             buf.append(':');
155             f = offset % 60;
156             if (f < 10) {
157                 buf.append('0');
158             }
159             buf.append(f);
160         }
161     }
162 
163 }