OSDN Git Service

X.690 Amendment1 (10/2003)
[bm-asn1/bm-asn1.git] / jp / bitmeister / asn1 / type / useful / GeneralizedTime.java
1 /*
2  * Copyright 2011-2012 BitMeister Inc.
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 jp.bitmeister.asn1.type.useful;
17
18 import java.text.DateFormat;
19 import java.text.ParseException;
20 import java.text.SimpleDateFormat;
21 import java.util.Date;
22 import java.util.regex.Pattern;
23
24 import jp.bitmeister.asn1.annotation.ASN1BuiltIn;
25 import jp.bitmeister.asn1.annotation.ASN1Tag;
26 import jp.bitmeister.asn1.exception.ASN1RuntimeException;
27 import jp.bitmeister.asn1.type.ASN1TagClass;
28 import jp.bitmeister.asn1.type.ASN1TagMode;
29 import jp.bitmeister.asn1.type.TimeType;
30
31 /**
32  * Represents ASN.1 "GeneralizedTime" type.
33  * 
34  * <p>
35  * An instance of this class represents a 'GeneralizedTime' type data, and
36  * contains an array of {@code byte} value. The value represents a character
37  * sequence of a calendar date with 4-digits year, a time of day with
38  * millisecond precision and a time differential from GMT.
39  * </p>
40  * <p>
41  * Time differential is represented with a 4 digits number that follows plus(+)
42  * or minus(-) sign, or a character 'Z' means GMT. If time differential is
43  * omitted, the time zone is local time.
44  * </p>
45  * 
46  * @author WATANABE, Jun. <jwat at bitmeister.jp>
47  */
48 @ASN1BuiltIn
49 @ASN1Tag(tagClass = ASN1TagClass.UNIVERSAL, value = 24, tagMode = ASN1TagMode.IMPLICIT)
50 public class GeneralizedTime extends TimeType {
51
52         private static final Pattern pattern = Pattern.compile("\\d{10}(\\d{2}(\\d{2}((\\.|\\,)\\d*)?)?)?(Z|(\\+|\\-)\\d{4})?");
53
54         /**
55          * The date format for {@code GeneralizedTime}.
56          */
57         private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() {
58
59                 @Override
60                 protected SimpleDateFormat initialValue() {
61                         return new SimpleDateFormat("yyyyMMddHHmmss.SSSZ");
62                 }
63
64         };
65
66         /**
67          * Instantiates an empty {@code GeneralizedTime}.
68          */
69         public GeneralizedTime() {
70         }
71
72         /**
73          * Instantiates a {@code GeneralizedTime} and initialize it with the
74          * {@code String} value.
75          * 
76          * @param value
77          *            The value assigned to the instance.
78          */
79         public GeneralizedTime(String value) {
80                 set(value);
81         }
82
83         /**
84          * Instantiate a {@code GeneralizedTime} and initialize it with the
85          * {@code Date} value.
86          * 
87          * @param value
88          *            The value assigned to the instance.
89          */
90         public GeneralizedTime(Date value) {
91                 set(value);
92         }
93
94         /*
95          * (non-Javadoc)
96          * 
97          * @see jp.bitmeister.asn1.type.TimeType#form()
98          */
99         @Override
100         public DateFormat form() {
101                 return DATE_FORMAT.get();
102         }
103         
104         /*
105          * (non-Javadoc)
106          * 
107          * @see jp.bitmeister.asn1.type.StringType#pattern()
108          */
109         @Override
110         protected Pattern pattern() {
111                 return pattern;
112         }
113         
114         /*
115          * (non-Javadoc)
116          * 
117          * @see jp.bitmeister.asn1.type.TimeType#parseDate(java.lang.String,
118          * java.lang.String)
119          */
120         @Override
121         protected Date parseDate(String time, String differential) {
122                 StringBuilder builder = new StringBuilder(time);
123                 if (builder.length() == 10) {
124                         builder.append("00");
125                 }
126                 if (builder.length() == 12) {
127                         builder.append("00");
128                 }
129                 if (builder.length() > 14) {
130                         if (builder.charAt(14) == ',') {
131                                 builder.setCharAt(14, '.');
132                         }
133                         if (builder.length() > 18) {
134                                 builder.setLength(18);
135                         }
136                         else {
137                                 while (builder.length() < 18) {
138                                         builder.append('0');
139                                 }
140                         }
141                 }
142                 else {
143                         builder.append(".000");
144                 }
145                 builder.append(differential);
146                 try {
147                         return DATE_FORMAT.get().parse(builder.toString());
148                 } catch (ParseException e) {
149                         ASN1RuntimeException ex = new ASN1RuntimeException();
150                         ex.setMessage("Failed to parse the argument string '" + builder
151                                         + "'.", e, getClass(), null, null);
152                         throw ex;
153                 }
154         }
155
156 }