2 * Copyright 2011-2012 BitMeister Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package jp.bitmeister.asn1.type.useful;
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;
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;
32 * Represents ASN.1 "GeneralizedTime" type.
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.
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.
46 * @author WATANABE, Jun. <jwat at bitmeister.jp>
49 @ASN1Tag(tagClass = ASN1TagClass.UNIVERSAL, value = 24, tagMode = ASN1TagMode.IMPLICIT)
50 public class GeneralizedTime extends TimeType {
52 private static final Pattern pattern = Pattern.compile("\\d{10}(\\d{2}(\\d{2}((\\.|\\,)\\d*)?)?)?(Z|(\\+|\\-)\\d{4})?");
55 * The date format for {@code GeneralizedTime}.
57 private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() {
60 protected SimpleDateFormat initialValue() {
61 return new SimpleDateFormat("yyyyMMddHHmmss.SSSZ");
67 * Instantiates an empty {@code GeneralizedTime}.
69 public GeneralizedTime() {
73 * Instantiates a {@code GeneralizedTime} and initialize it with the
74 * {@code String} value.
77 * The value assigned to the instance.
79 public GeneralizedTime(String value) {
84 * Instantiate a {@code GeneralizedTime} and initialize it with the
88 * The value assigned to the instance.
90 public GeneralizedTime(Date value) {
97 * @see jp.bitmeister.asn1.type.TimeType#form()
100 public DateFormat form() {
101 return DATE_FORMAT.get();
107 * @see jp.bitmeister.asn1.type.StringType#pattern()
110 protected Pattern pattern() {
117 * @see jp.bitmeister.asn1.type.TimeType#parseDate(java.lang.String,
121 protected Date parseDate(String time, String differential) {
122 StringBuilder builder = new StringBuilder(time);
123 if (builder.length() == 10) {
124 builder.append("00");
126 if (builder.length() == 12) {
127 builder.append("00");
129 if (builder.length() > 14) {
130 if (builder.charAt(14) == ',') {
131 builder.setCharAt(14, '.');
133 if (builder.length() > 18) {
134 builder.setLength(18);
137 while (builder.length() < 18) {
143 builder.append(".000");
145 builder.append(differential);
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);