class RASN1::Types::GeneralizedTime

ASN.1 GeneralizedTime

+{#value} of a {GeneralizedTime} should be a ruby Time.

Notes

When encoding, resulting string is always a UTC time, appended with Z. Minutes and seconds are always generated. Fractions of second are generated if value Time object have them.

On parsing, are supported:

These times may include minutes and seconds. Fractions of hour, minute and second are supported. @author Sylvain Daubert

Constants

ID

GeneralizedTime id value

Public Class Methods

type() click to toggle source

Get ASN.1 type @return [String]

# File lib/rasn1/types/generalized_time.rb, line 29
def self.type
  'GeneralizedTime'
end

Private Instance Methods

der_to_value(der, ber: false) click to toggle source
# File lib/rasn1/types/generalized_time.rb, line 44
def der_to_value(der, ber: false)
  date_hour, fraction = der.split('.')
  utc_offset_forced = false
  if fraction.nil?
    if (date_hour[-1] != 'Z') && (date_hour !~ /[+-]\d+$/)
      # If not UTC, have to add offset with UTC to force
      # DateTime#strptime to generate a local time. But this difference
      # may be errored because of DST.
      date_hour << Time.now.strftime('%z')
      utc_offset_forced = true
    end
  elsif fraction[-1] == 'Z'
    fraction = fraction[0...-1]
    date_hour << 'Z'
  else
    match = fraction.match(/(\d+)([+-]\d+)/)
    if match
      # fraction contains fraction and timezone info. Split them
      fraction = match[1]
      date_hour << match[2]
    else
      # fraction only contains fraction.
      # Have to add offset with UTC to force DateTime#strptime to
      # generate a local time. But this difference may be errored
      # because of DST.
      date_hour << Time.now.strftime('%z')
      utc_offset_forced = true
    end
  end
  format = case date_hour.size
           when 11
             frac_base = 60 * 60
             '%Y%m%d%HZ'
           when 13
             frac_base = 60
             '%Y%m%d%H%MZ'
           when 15
             if date_hour[-1] == 'Z'
               frac_base = 1
               '%Y%m%d%H%M%SZ'
             else
               frac_base = 60 * 60
               '%Y%m%d%H%z'
             end
           when 17
             frac_base = 60
             '%Y%m%d%H%M%z'
           when 19
             frac_base = 1
             '%Y%m%d%H%M%S%z'
           else
             prefix = @name.nil? ? type : "tag #{@name}"
             raise ASN1Error, "#{prefix}: unrecognized format: #{der}"
           end
  @value = DateTime.strptime(date_hour, format).to_time
  # local time format.
  # Check DST. There may be a shift of one hour...
  if utc_offset_forced
    compare_time = Time.new(*@value.to_a[0..5].reverse)
    @value = compare_time if compare_time.utc_offset != @value.utc_offset
  end
  @value += ".#{fraction}".to_r * frac_base unless fraction.nil?
end
value_to_der() click to toggle source
# File lib/rasn1/types/generalized_time.rb, line 35
def value_to_der
  if @value.nsec.positive?
    der = @value.getutc.strftime('%Y%m%d%H%M%S.%9NZ')
    der.sub(/0+Z/, 'Z')
  else
    @value.getutc.strftime('%Y%m%d%H%M%SZ')
  end
end