001package org.apache.commons.ssl.org.bouncycastle.asn1.x509; 002 003import java.text.ParseException; 004import java.text.SimpleDateFormat; 005import java.util.Date; 006import java.util.Locale; 007import java.util.SimpleTimeZone; 008 009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Choice; 010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1GeneralizedTime; 011import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object; 012import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive; 013import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject; 014import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1UTCTime; 015import org.apache.commons.ssl.org.bouncycastle.asn1.DERGeneralizedTime; 016import org.apache.commons.ssl.org.bouncycastle.asn1.DERUTCTime; 017 018public class Time 019 extends ASN1Object 020 implements ASN1Choice 021{ 022 ASN1Primitive time; 023 024 public static Time getInstance( 025 ASN1TaggedObject obj, 026 boolean explicit) 027 { 028 return getInstance(obj.getObject()); // must be explicitly tagged 029 } 030 031 public Time( 032 ASN1Primitive time) 033 { 034 if (!(time instanceof ASN1UTCTime) 035 && !(time instanceof ASN1GeneralizedTime)) 036 { 037 throw new IllegalArgumentException("unknown object passed to Time"); 038 } 039 040 this.time = time; 041 } 042 043 /** 044 * Creates a time object from a given date - if the date is between 1950 045 * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime 046 * is used. 047 * 048 * @param time a date object representing the time of interest. 049 */ 050 public Time( 051 Date time) 052 { 053 SimpleTimeZone tz = new SimpleTimeZone(0, "Z"); 054 SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss"); 055 056 dateF.setTimeZone(tz); 057 058 String d = dateF.format(time) + "Z"; 059 int year = Integer.parseInt(d.substring(0, 4)); 060 061 if (year < 1950 || year > 2049) 062 { 063 this.time = new DERGeneralizedTime(d); 064 } 065 else 066 { 067 this.time = new DERUTCTime(d.substring(2)); 068 } 069 } 070 071 /** 072 * Creates a time object from a given date and locale - if the date is between 1950 073 * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime 074 * is used. You may need to use this constructor if the default locale 075 * doesn't use a Gregorian calender so that the GeneralizedTime produced is compatible with other ASN.1 implementations. 076 * 077 * @param time a date object representing the time of interest. 078 * @param locale an appropriate Locale for producing an ASN.1 GeneralizedTime value. 079 */ 080 public Time( 081 Date time, 082 Locale locale) 083 { 084 SimpleTimeZone tz = new SimpleTimeZone(0, "Z"); 085 SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss", locale); 086 087 dateF.setTimeZone(tz); 088 089 String d = dateF.format(time) + "Z"; 090 int year = Integer.parseInt(d.substring(0, 4)); 091 092 if (year < 1950 || year > 2049) 093 { 094 this.time = new DERGeneralizedTime(d); 095 } 096 else 097 { 098 this.time = new DERUTCTime(d.substring(2)); 099 } 100 } 101 102 public static Time getInstance( 103 Object obj) 104 { 105 if (obj == null || obj instanceof Time) 106 { 107 return (Time)obj; 108 } 109 else if (obj instanceof ASN1UTCTime) 110 { 111 return new Time((ASN1UTCTime)obj); 112 } 113 else if (obj instanceof ASN1GeneralizedTime) 114 { 115 return new Time((ASN1GeneralizedTime)obj); 116 } 117 118 throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); 119 } 120 121 public String getTime() 122 { 123 if (time instanceof ASN1UTCTime) 124 { 125 return ((ASN1UTCTime)time).getAdjustedTime(); 126 } 127 else 128 { 129 return ((ASN1GeneralizedTime)time).getTime(); 130 } 131 } 132 133 public Date getDate() 134 { 135 try 136 { 137 if (time instanceof ASN1UTCTime) 138 { 139 return ((ASN1UTCTime)time).getAdjustedDate(); 140 } 141 else 142 { 143 return ((ASN1GeneralizedTime)time).getDate(); 144 } 145 } 146 catch (ParseException e) 147 { // this should never happen 148 throw new IllegalStateException("invalid date string: " + e.getMessage()); 149 } 150 } 151 152 /** 153 * Produce an object suitable for an ASN1OutputStream. 154 * <pre> 155 * Time ::= CHOICE { 156 * utcTime UTCTime, 157 * generalTime GeneralizedTime } 158 * </pre> 159 */ 160 public ASN1Primitive toASN1Primitive() 161 { 162 return time; 163 } 164 165 public String toString() 166 { 167 return getTime(); 168 } 169}