package org.bouncycastle.asn1;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.SimpleTimeZone;

UTC time object.
/** * UTC time object. */
public class DERUTCTime extends ASN1Object { String time;
return an UTC Time from the passed in object.
Throws:
  • IllegalArgumentException – if the object cannot be converted.
/** * return an UTC Time from the passed in object. * * @exception IllegalArgumentException if the object cannot be converted. */
public static DERUTCTime getInstance( Object obj) { if (obj == null || obj instanceof DERUTCTime) { return (DERUTCTime)obj; } throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); }
return an UTC Time from a tagged object.
Params:
  • obj – the tagged object holding the object we want
  • explicit – true if the object is meant to be explicitly tagged false otherwise.
Throws:
/** * return an UTC Time from a tagged object. * * @param obj the tagged object holding the object we want * @param explicit true if the object is meant to be explicitly * tagged false otherwise. * @exception IllegalArgumentException if the tagged object cannot * be converted. */
public static DERUTCTime getInstance( ASN1TaggedObject obj, boolean explicit) { DERObject o = obj.getObject(); if (explicit || o instanceof DERUTCTime) { return getInstance(o); } else { return new DERUTCTime(((ASN1OctetString)o).getOctets()); } }
The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were never encoded. When you're creating one of these objects from scratch, that's what you want to use, otherwise we'll try to deal with whatever gets read from the input stream... (this is why the input format is different from the getTime() method output).

Params:
  • time – the time string.
/** * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were * never encoded. When you're creating one of these objects from scratch, that's * what you want to use, otherwise we'll try to deal with whatever gets read from * the input stream... (this is why the input format is different from the getTime() * method output). * <p> * * @param time the time string. */
public DERUTCTime( String time) { this.time = time; try { this.getDate(); } catch (ParseException e) { throw new IllegalArgumentException("invalid date string: " + e.getMessage()); } }
base constructer from a java.util.date object
/** * base constructer from a java.util.date object */
public DERUTCTime( Date time) { SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'"); dateF.setTimeZone(new SimpleTimeZone(0,"Z")); this.time = dateF.format(time); } DERUTCTime( byte[] bytes) { // // explicitly convert to characters // char[] dateC = new char[bytes.length]; for (int i = 0; i != dateC.length; i++) { dateC[i] = (char)(bytes[i] & 0xff); } this.time = new String(dateC); }
return the time as a date based on whatever a 2 digit year will return. For standardised processing use getAdjustedDate().
Throws:
Returns:the resulting date
/** * return the time as a date based on whatever a 2 digit year will return. For * standardised processing use getAdjustedDate(). * * @return the resulting date * @exception ParseException if the date string cannot be parsed. */
public Date getDate() throws ParseException { SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz"); return dateF.parse(getTime()); }
return the time as an adjusted date in the range of 1950 - 2049.
Throws:
Returns:a date in the range of 1950 to 2049.
/** * return the time as an adjusted date * in the range of 1950 - 2049. * * @return a date in the range of 1950 to 2049. * @exception ParseException if the date string cannot be parsed. */
public Date getAdjustedDate() throws ParseException { SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz"); dateF.setTimeZone(new SimpleTimeZone(0, "Z")); return dateF.parse(getAdjustedTime()); }
return the time - always in the form of YYMMDDhhmmssGMT(+hh:mm|-hh:mm).

Normally in a certificate we would expect "Z" rather than "GMT", however adding the "GMT" means we can just use:

    dateF = new SimpleDateFormat("yyMMddHHmmssz");
To read in the time and get a date which is compatible with our local time zone.

Note: In some cases, due to the local date processing, this may lead to unexpected results. If you want to stick the normal convention of 1950 to 2049 use the getAdjustedTime() method.

/** * return the time - always in the form of * YYMMDDhhmmssGMT(+hh:mm|-hh:mm). * <p> * Normally in a certificate we would expect "Z" rather than "GMT", * however adding the "GMT" means we can just use: * <pre> * dateF = new SimpleDateFormat("yyMMddHHmmssz"); * </pre> * To read in the time and get a date which is compatible with our local * time zone. * <p> * <b>Note:</b> In some cases, due to the local date processing, this * may lead to unexpected results. If you want to stick the normal * convention of 1950 to 2049 use the getAdjustedTime() method. */
public String getTime() { // // standardise the format. // if (time.indexOf('-') < 0 && time.indexOf('+') < 0) { if (time.length() == 11) { return time.substring(0, 10) + "00GMT+00:00"; } else { return time.substring(0, 12) + "GMT+00:00"; } } else { int index = time.indexOf('-'); if (index < 0) { index = time.indexOf('+'); } String d = time; if (index == time.length() - 3) { d += "00"; } if (index == 10) { return d.substring(0, 10) + "00GMT" + d.substring(10, 13) + ":" + d.substring(13, 15); } else { return d.substring(0, 12) + "GMT" + d.substring(12, 15) + ":" + d.substring(15, 17); } } }
return a time string as an adjusted date with a 4 digit year. This goes in the range of 1950 - 2049.
/** * return a time string as an adjusted date with a 4 digit year. This goes * in the range of 1950 - 2049. */
public String getAdjustedTime() { String d = this.getTime(); if (d.charAt(0) < '5') { return "20" + d; } else { return "19" + d; } } private byte[] getOctets() { char[] cs = time.toCharArray(); byte[] bs = new byte[cs.length]; for (int i = 0; i != cs.length; i++) { bs[i] = (byte)cs[i]; } return bs; } void encode( DEROutputStream out) throws IOException { out.writeEncoded(UTC_TIME, this.getOctets()); } boolean asn1Equals( DERObject o) { if (!(o instanceof DERUTCTime)) { return false; } return time.equals(((DERUTCTime)o).time); } public int hashCode() { return time.hashCode(); } public String toString() { return time; } }