Time.java revision 5db505e1f6a68c8d5dfdb0fed0b8607dea7bed96
1package org.bouncycastle.asn1.cms;
2
3import java.text.ParseException;
4import java.text.SimpleDateFormat;
5import java.util.Date;
6import java.util.SimpleTimeZone;
7
8import org.bouncycastle.asn1.ASN1Choice;
9import org.bouncycastle.asn1.ASN1Object;
10import org.bouncycastle.asn1.ASN1Primitive;
11import org.bouncycastle.asn1.ASN1TaggedObject;
12import org.bouncycastle.asn1.DERGeneralizedTime;
13import org.bouncycastle.asn1.DERUTCTime;
14
15/**
16 * <a href="http://tools.ietf.org/html/rfc5652#section-11.3">RFC 5652</a>:
17 * Dual-mode timestamp format producing either UTCTIme or GeneralizedTime.
18 * <p>
19 * <pre>
20 * Time ::= CHOICE {
21 *     utcTime        UTCTime,
22 *     generalTime    GeneralizedTime }
23 * </pre>
24 * <p>
25 * This has a constructor using java.util.Date for input which generates
26 * a {@link org.bouncycastle.asn1.DERUTCTime DERUTCTime} object if the
27 * supplied datetime is in range 1950-01-01-00:00:00 UTC until 2049-12-31-23:59:60 UTC.
28 * If the datetime value is outside that range, the generated object will be
29 * {@link org.bouncycastle.asn1.DERGeneralizedTime DERGeneralizedTime}.
30 */
31public class Time
32    extends ASN1Object
33    implements ASN1Choice
34{
35    ASN1Primitive time;
36
37    public static Time getInstance(
38        ASN1TaggedObject obj,
39        boolean          explicit)
40    {
41        return getInstance(obj.getObject());
42    }
43
44    /**
45     * @deprecated use getInstance()
46     */
47    public Time(
48        ASN1Primitive   time)
49    {
50        if (!(time instanceof DERUTCTime)
51            && !(time instanceof DERGeneralizedTime))
52        {
53            throw new IllegalArgumentException("unknown object passed to Time");
54        }
55
56        this.time = time;
57    }
58
59    /**
60     * Create a time object from a given date - if the year is in between 1950
61     * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime
62     * is used.
63     */
64    public Time(
65        Date    date)
66    {
67        SimpleTimeZone      tz = new SimpleTimeZone(0, "Z");
68        SimpleDateFormat    dateF = new SimpleDateFormat("yyyyMMddHHmmss");
69
70        dateF.setTimeZone(tz);
71
72        String  d = dateF.format(date) + "Z";
73        int     year = Integer.parseInt(d.substring(0, 4));
74
75        if (year < 1950 || year > 2049)
76        {
77            time = new DERGeneralizedTime(d);
78        }
79        else
80        {
81            time = new DERUTCTime(d.substring(2));
82        }
83    }
84
85    /**
86     * Return a Time object from the given object.
87     * <p>
88     * Accepted inputs:
89     * <ul>
90     * <li> null &rarr; null
91     * <li> {@link Time} object
92     * <li> {@link org.bouncycastle.asn1.DERUTCTime DERUTCTime} object
93     * <li> {@link org.bouncycastle.asn1.DERGeneralizedTime DERGeneralizedTime} object
94     * </ul>
95     *
96     * @param obj the object we want converted.
97     * @exception IllegalArgumentException if the object cannot be converted.
98     */
99    public static Time getInstance(
100        Object  obj)
101    {
102        if (obj == null || obj instanceof Time)
103        {
104            return (Time)obj;
105        }
106        else if (obj instanceof DERUTCTime)
107        {
108            return new Time((DERUTCTime)obj);
109        }
110        else if (obj instanceof DERGeneralizedTime)
111        {
112            return new Time((DERGeneralizedTime)obj);
113        }
114
115        throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
116    }
117
118    /**
119     * Get the date+tine as a String in full form century format.
120     */
121    public String getTime()
122    {
123        if (time instanceof DERUTCTime)
124        {
125            return ((DERUTCTime)time).getAdjustedTime();
126        }
127        else
128        {
129            return ((DERGeneralizedTime)time).getTime();
130        }
131    }
132
133    /**
134     * Get java.util.Date version of date+time.
135     */
136    public Date getDate()
137    {
138        try
139        {
140            if (time instanceof DERUTCTime)
141            {
142                return ((DERUTCTime)time).getAdjustedDate();
143            }
144            else
145            {
146                return ((DERGeneralizedTime)time).getDate();
147            }
148        }
149        catch (ParseException e)
150        {         // this should never happen
151            throw new IllegalStateException("invalid date string: " + e.getMessage());
152        }
153    }
154
155    /**
156     * Produce an object suitable for an ASN1OutputStream.
157     */
158    public ASN1Primitive toASN1Primitive()
159    {
160        return time;
161    }
162}
163