Module: HexaPDF::DictionaryFields::DateConverter

Defined in:
lib/hexapdf/dictionary_fields.rb

Overview

Converter module for handling PDF date fields since they are stored as strings.

The ISO PDF specification differs from Adobe’s specification in respect to the supported date format. When converting from a date string to a Time object, this is taken into account.

See: PDF2.0 s7.9.4, ADB1.7 3.8.3

Constant Summary collapse

DATE_RE =

:nodoc:

/\AD:(\d{4})(\d\d)?(\d\d)?(\d\d)?(\d\d)?(\d\d)?([Z+-])?(?:(\d+)(?:'|'(\d+)'?|\z)?)?\z/n

Class Method Summary collapse

Class Method Details

.additional_typesObject

A date field may contain a string in PDF format, or a Time, Date or DateTime object.



312
313
314
# File 'lib/hexapdf/dictionary_fields.rb', line 312

def self.additional_types
  [String, Time, Date, DateTime]
end

.convert(str, _type, _document) ⇒ Object

Checks if the given object is a string and converts into a Time object if possible. Otherwise returns nil.

This method takes some forms of mangled date strings into account that were found in the wild.



322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
# File 'lib/hexapdf/dictionary_fields.rb', line 322

def self.convert(str, _type, _document)
  return unless str.kind_of?(String) && (m = str.match(DATE_RE))

  utc_offset = if m[7].nil? || m[7] == 'Z'
                 0
               else
                 (m[7] == '-' ? -1 : 1) * (m[8].to_i * 3600 + m[9].to_i * 60).clamp(0, 86399)
               end
  begin
    Time.new(m[1].to_i, (m[2] ? m[2].to_i : 1), (m[3] ? m[3].to_i : 1),
             m[4].to_i, m[5].to_i, m[6].to_i, utc_offset)
  rescue ArgumentError
    Time.new(m[1].to_i, m[2].to_i.clamp(1, 12), m[3].to_i.clamp(1, 31),
             m[4].to_i.clamp(0, 23), m[5].to_i.clamp(0, 59), m[6].to_i.clamp(0, 59), utc_offset)
  end
end

.usable_for?(type) ⇒ Boolean

This converter is usable if the type is PDFDate.

Returns:



307
308
309
# File 'lib/hexapdf/dictionary_fields.rb', line 307

def self.usable_for?(type)
  type == PDFDate
end