class ISO8601::DateTime

A DateTime representation

@example

dt = DateTime.new('2014-05-28T19:53Z')
dt.year #=> 2014

Attributes

second[R]

Public Class Methods

new(date_time) click to toggle source

@param [String] date_time The datetime pattern

# File lib/iso8601/date_time.rb, line 23
def initialize(date_time)
  @original = date_time
  @date_time = parse(date_time)
  @second = @date_time.second + @date_time.second_fraction.to_f.round(1)
end

Public Instance Methods

+(other) click to toggle source

Addition

@param [Numeric] other The seconds to add

# File lib/iso8601/date_time.rb, line 33
def +(other)
  moment = @date_time.to_time.localtime(zone) + other.to_f.round(1)

  self.class.new(moment.strftime('%Y-%m-%dT%H:%M:%S.%N%:z'))
end
-(other) click to toggle source

Substraction

@param [Numeric] other The seconds to substract

# File lib/iso8601/date_time.rb, line 43
def -(other)
  moment = @date_time.to_time.localtime(zone) - other.to_f.round(1)

  self.class.new(moment.strftime('%Y-%m-%dT%H:%M:%S.%N%:z'))
end
==(other) click to toggle source

@param [#hash] other The contrast to compare against

@return [Boolean]

# File lib/iso8601/date_time.rb, line 74
def ==(other)
  (hash == other.hash)
end
atoms()
Alias for: to_a
eql?(other) click to toggle source

@param [#hash] other The contrast to compare against

@return [Boolean]

# File lib/iso8601/date_time.rb, line 82
def eql?(other)
  (hash == other.hash)
end
hash() click to toggle source

@return [Fixnum]

# File lib/iso8601/date_time.rb, line 88
def hash
  [to_f, self.class].hash
end
to_a() click to toggle source

Converts DateTime to an array of atoms.

# File lib/iso8601/date_time.rb, line 59
def to_a
  [year, month, day, hour, minute, second, zone]
end
Also aliased as: atoms
to_f() click to toggle source

Converts DateTime to a floating point number of seconds since the Epoch.

# File lib/iso8601/date_time.rb, line 66
def to_f
  to_time.to_f
end
to_s() click to toggle source

Converts DateTime to a formated string

# File lib/iso8601/date_time.rb, line 51
def to_s
  second_format = (second % 1).zero? ? '%02d' : '%04.1f'

  format("%04d-%02d-%02dT%02d:%02d:#{second_format}%s", *atoms)
end

Private Instance Methods

parse(date_time) click to toggle source

Parses an ISO date time, where the date and the time components are optional.

It enhances the parsing capabilities of the native DateTime.

@param [String] date_time The ISO representation

rubocop:disable Metrics/AbcSize

# File lib/iso8601/date_time.rb, line 103
def parse(date_time)
  raise(ISO8601::Errors::UnknownPattern, date_time) if date_time.empty?

  date, time = date_time.split('T')

  date_atoms = parse_date(date)
  time_atoms = Array(time && parse_time(time))
  separators = [date_atoms.pop, time_atoms.pop]

  raise(ISO8601::Errors::UnknownPattern, @original) unless valid_representation?(date_atoms, time_atoms)
  raise(ISO8601::Errors::UnknownPattern, @original) unless valid_separators?(separators)

  ::DateTime.new(*(date_atoms + time_atoms).compact)
end
parse_date(input) click to toggle source

Validates the date has the right pattern.

Acceptable patterns: YYYY, YYYY-MM-DD, YYYYMMDD or YYYY-MM but not YYYYMM

@param [String] input A date component

@return [Array<String, nil>]

# File lib/iso8601/date_time.rb, line 127
def parse_date(input)
  today = ::Date.today
  return [today.year, today.month, today.day, :ignore] if input.empty?

  date = ISO8601::Date.new(input)

  date.atoms << date.separator
end
parse_time(input) click to toggle source

@return [Array<String, nil>]

# File lib/iso8601/date_time.rb, line 138
def parse_time(input)
  time = ISO8601::Time.new(input)

  time.atoms << time.separator
end
valid_representation?(date, time) click to toggle source

If time is provided date must use a complete representation

# File lib/iso8601/date_time.rb, line 158
def valid_representation?(date, time)
  year, month, day = date
  hour = time.first

  date.nil? || !(!year.nil? && (month.nil? || day.nil?) && !hour.nil?)
end
valid_separators?(separators) click to toggle source
# File lib/iso8601/date_time.rb, line 144
def valid_separators?(separators)
  separators = separators.compact

  return true if separators.length == 1 || separators[0] == :ignore

  unless separators.all?(&:empty?)
    return false if separators.first.length != separators.last.length
  end

  true
end