Home | History | Annotate | Download | only in x509
      1 package org.bouncycastle.asn1.x509;
      2 
      3 import java.text.ParseException;
      4 import java.text.SimpleDateFormat;
      5 // Android-added: Localization support
      6 import java.util.Calendar;
      7 import java.util.Date;
      8 import java.util.Locale;
      9 import java.util.SimpleTimeZone;
     10 
     11 import org.bouncycastle.asn1.ASN1Choice;
     12 import org.bouncycastle.asn1.ASN1GeneralizedTime;
     13 import org.bouncycastle.asn1.ASN1Object;
     14 import org.bouncycastle.asn1.ASN1Primitive;
     15 import org.bouncycastle.asn1.ASN1TaggedObject;
     16 import org.bouncycastle.asn1.ASN1UTCTime;
     17 import org.bouncycastle.asn1.DERGeneralizedTime;
     18 import org.bouncycastle.asn1.DERUTCTime;
     19 
     20 public class Time
     21     extends ASN1Object
     22     implements ASN1Choice
     23 {
     24     ASN1Primitive time;
     25 
     26     public static Time getInstance(
     27         ASN1TaggedObject obj,
     28         boolean          explicit)
     29     {
     30         return getInstance(obj.getObject()); // must be explicitly tagged
     31     }
     32 
     33     public Time(
     34         ASN1Primitive   time)
     35     {
     36         if (!(time instanceof ASN1UTCTime)
     37             && !(time instanceof ASN1GeneralizedTime))
     38         {
     39             throw new IllegalArgumentException("unknown object passed to Time");
     40         }
     41 
     42         this.time = time;
     43     }
     44 
     45     /**
     46      * Creates a time object from a given date - if the date is between 1950
     47      * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime
     48      * is used.
     49      *
     50      * @param time a date object representing the time of interest.
     51      */
     52     public Time(
     53         Date    time)
     54     {
     55         SimpleTimeZone      tz = new SimpleTimeZone(0, "Z");
     56         // Android-changed: Use localized version
     57         // SimpleDateFormat    dateF = new SimpleDateFormat("yyyyMMddHHmmss");
     58         SimpleDateFormat    dateF = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
     59 
     60         dateF.setTimeZone(tz);
     61 
     62         String  d = dateF.format(time) + "Z";
     63         int     year = Integer.parseInt(d.substring(0, 4));
     64 
     65         if (year < 1950 || year > 2049)
     66         {
     67             this.time = new DERGeneralizedTime(d);
     68         }
     69         else
     70         {
     71             this.time = new DERUTCTime(d.substring(2));
     72         }
     73     }
     74 
     75     /**
     76      * Creates a time object from a given date and locale - if the date is between 1950
     77      * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime
     78      * is used. You may need to use this constructor if the default locale
     79      * doesn't use a Gregorian calender so that the GeneralizedTime produced is compatible with other ASN.1 implementations.
     80      *
     81      * @param time a date object representing the time of interest.
     82      * @param locale an appropriate Locale for producing an ASN.1 GeneralizedTime value.
     83      */
     84     public Time(
     85         Date    time,
     86         Locale locale)
     87     {
     88         SimpleTimeZone      tz = new SimpleTimeZone(0, "Z");
     89         // BEGIN Android-changed: Use localized version
     90         // SimpleDateFormat    dateF = new SimpleDateFormat("yyyyMMddHHmmss", locale);
     91         SimpleDateFormat    dateF = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
     92         dateF.setCalendar(Calendar.getInstance(locale));
     93         // END android-changed
     94 
     95         dateF.setTimeZone(tz);
     96 
     97         String  d = dateF.format(time) + "Z";
     98         int     year = Integer.parseInt(d.substring(0, 4));
     99 
    100         if (year < 1950 || year > 2049)
    101         {
    102             this.time = new DERGeneralizedTime(d);
    103         }
    104         else
    105         {
    106             this.time = new DERUTCTime(d.substring(2));
    107         }
    108     }
    109 
    110     public static Time getInstance(
    111         Object  obj)
    112     {
    113         if (obj == null || obj instanceof Time)
    114         {
    115             return (Time)obj;
    116         }
    117         else if (obj instanceof ASN1UTCTime)
    118         {
    119             return new Time((ASN1UTCTime)obj);
    120         }
    121         else if (obj instanceof ASN1GeneralizedTime)
    122         {
    123             return new Time((ASN1GeneralizedTime)obj);
    124         }
    125 
    126         throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
    127     }
    128 
    129     public String getTime()
    130     {
    131         if (time instanceof ASN1UTCTime)
    132         {
    133             return ((ASN1UTCTime)time).getAdjustedTime();
    134         }
    135         else
    136         {
    137             return ((ASN1GeneralizedTime)time).getTime();
    138         }
    139     }
    140 
    141     public Date getDate()
    142     {
    143         try
    144         {
    145             if (time instanceof ASN1UTCTime)
    146             {
    147                 return ((ASN1UTCTime)time).getAdjustedDate();
    148             }
    149             else
    150             {
    151                 return ((ASN1GeneralizedTime)time).getDate();
    152             }
    153         }
    154         catch (ParseException e)
    155         {         // this should never happen
    156             throw new IllegalStateException("invalid date string: " + e.getMessage());
    157         }
    158     }
    159 
    160     /**
    161      * Produce an object suitable for an ASN1OutputStream.
    162      * <pre>
    163      * Time ::= CHOICE {
    164      *             utcTime        UTCTime,
    165      *             generalTime    GeneralizedTime }
    166      * </pre>
    167      */
    168     public ASN1Primitive toASN1Primitive()
    169     {
    170         return time;
    171     }
    172 
    173     public String toString()
    174     {
    175         return getTime();
    176     }
    177 }
    178