Class: RDF::Literal::Temporal

Inherits:
RDF::Literal show all
Defined in:
lib/rdf/model/literal/temporal.rb

Overview

Shared methods and class ancestry for date, time, and dateTime literal classes.

Since:

  • 3.1

Direct Known Subclasses

Date, DateTime, Time

Constant Summary collapse

ZONE_GRAMMAR =

Matches either -10:00 or -P1H0M forms

Since:

  • 3.1

%r(\A
   (?:(?<si>[+-])(?<hr>\d{2}):(?:(?<mi>\d{2}))?)
  |(?:(?<si>-)?PT(?<hr>\d{1,2})H(?:(?<mi>\d{1,2})M)?)
\z)x.freeze
YEARFRAG =

Since:

  • 3.1

%r(-?(?:(?:[1-9]\d{3,})|(?:0\d{3})))
MONTHFRAG =

Since:

  • 3.1

%r((?:(?:0[1-9])|(?:1[0-2])))
DAYFRAG =

Since:

  • 3.1

%r((?:(?:0[1-9])|(?:[12]\d)|(?:3[01])))
HOURFRAG =

Since:

  • 3.1

%r((?:[01]\d)|(?:2[0-3]))
MINUTEFRAG =

Since:

  • 3.1

%r([0-5]\d)
SECONDFRAG =

Since:

  • 3.1

%r([0-5]\d(?:\.\d+)?)
EODFRAG =

Since:

  • 3.1

%r(24:00:00(?:\.0+)?)
TZFRAG =

Since:

  • 3.1

%r((?:[\+\-]\d{2}:\d{2})|UTC|GMT|Z)

Constants inherited from RDF::Literal

FALSE, TRUE, XSD_STRING, ZERO

Instance Attribute Summary

Attributes inherited from RDF::Literal

#datatype, #direction, #language

Instance Method Summary collapse

Methods inherited from RDF::Literal

#compatible?, #comperable_datatype2?, #comperable_datatype?, #datatype?, #direction?, #eql?, #escape, #hash, #humanize, #initialize, #inspect, #language?, #literal?, #method_missing, #object, #plain?, #respond_to_missing?, #simple?, #squish, #squish!, #validate!, #value, #value_hash

Methods included from Term

#compatible?, #eql?, #escape, #term?, #terms, #to_base, #to_term

Methods included from Value

#anonymous?, #canonicalize, #constant?, #graph?, #inspect, #inspect!, #invalid?, #iri?, #list?, #literal?, #node?, #resource?, #start_with?, #statement?, #term?, #to_nquads, #to_ntriples, #to_rdf, #to_term, #type_error, #uri?, #validate!, #variable?

Constructor Details

This class inherits a constructor from RDF::Literal

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class RDF::Literal

Instance Method Details

#+(other) ⇒ Temporal

Note:

This depends on the parameter responding to #to_i or #to_r, which for Duration types, is implemented in the rdf-xsd gem.

Add a Duration to a Temporal.

For YearMonthDuration, turns duration into months and adds to internal DateTime object.

For DayTimeDuration, turns duration into rational days, and adds to internal DateTime object.



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/rdf/model/literal/temporal.rb', line 217

def +(other)
  new_dt = case other
  when YearMonthDuration
    @object >> other.to_i
  when DayTimeDuration
    @object + other.to_r
  else
    return super
  end

  dt = new_dt.strftime(self.class.const_get(:FORMAT)) + tz
  self.class.new(dt)
rescue NoMethodError => e
  raise "Consider including the rdf-xsd class for method implementaions: #{e.message}"
end

#+(other) ⇒ Temporal, DayTimeDuration

Subtract times or durations from a temporal.

Note:

This depends on the parameter responding to #to_i or #to_r, which for Duration types, is implemented in the rdf-xsd gem.

For YearMonthDuration, turns duration into months and subtracts from internal DateTime object resulting in a new RDF::Literal::Temporal object.

For DayTimeDuration, turns duration into rational days, and subtracts from internal DateTime object resulting in a new RDF::Literal::Temporal object.

For Temporal, subtracts the two moments resulting in a xsd:dayTimeDuration.

Since:

  • 3.1



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/rdf/model/literal/temporal.rb', line 249

def -(other)
  new_dt = case other
  when YearMonthDuration
    @object << other.to_i
  when DayTimeDuration
    @object - other.to_r
  when Temporal
    @object - other.object
  else
    return super
  end

  if new_dt.is_a?(Rational)
    RDF::Literal(new_dt, datatype: RDF::XSD.dayTimeDuration)
  else
    dt = new_dt.strftime(self.class.const_get(:FORMAT)) + tz
    self.class.new(dt)
  end
rescue NoMethodError => e
  raise "Consider including the rdf-xsd class for method implementaions: #{e.message}"
end

#<=>(other) ⇒ Integer

Compares this literal to other for sorting purposes.

Parameters:

  • other (Object)

Returns:

Since:

  • 3.1



27
28
29
30
31
32
# File 'lib/rdf/model/literal/temporal.rb', line 27

def <=>(other)
  # If lexically invalid, use regular literal testing
  return super unless self.valid? && (!other.respond_to?(:valid?) || other.valid?)
  return super unless other.is_a?(self.class)
  @object <=> other.object
end

#==(other) ⇒ Boolean

Returns true if this literal is equal to other.

Parameters:

  • other (Object)

Returns:

Since:

  • 0.3.0



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rdf/model/literal/temporal.rb', line 40

def ==(other)
  # If lexically invalid, use regular literal testing
  return super unless self.valid? && (!other.respond_to?(:valid?) || other.valid?)

  case other
  when self.class
    self.object == other.object
  when Literal::Temporal
    false
  else
    super
  end
end

#adjust_to_timezoneDateTime #adjust_to_timezone(zone) ⇒ DateTime

Functional version of #adjust_to_timezone!.

Overloads:

Since:

  • 3.1



200
201
202
# File 'lib/rdf/model/literal/temporal.rb', line 200

def adjust_to_timezone(*args)
  self.dup.adjust_to_timezone!(*args)
end

#adjust_to_timezone!Temporal #adjust_to_timezone!(zone) ⇒ Temporal

Adjust the timezone.

From fn:adjust-dateTime-to-timezone

Overloads:

  • #adjust_to_timezone!Temporal

    Adjusts the timezone to UTC.

    Returns:

    Raises:

    • (RangeError)

      if zone < -14*60 or zone > 14*60

  • #adjust_to_timezone!(zone) ⇒ Temporal

    If zone is nil, then the timzeone component is removed.

    Otherwise, the timezone is set based on the difference between the current timezone offset (if any) and zone.

    Parameters:

    • zone (DayTimeDuration, String)

      (nil) In the form of ZONE_GRAMMAR.

    Returns:

    Raises:

    • (RangeError)

      if zone < -14*60 or zone > 14*60

See Also:

Since:

  • 3.1



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/rdf/model/literal/temporal.rb', line 162

def adjust_to_timezone!(*args)
  zone = args.empty? ? '+00:00' : args.first
  if zone.to_s.empty?
    # Remove timezone component
    @object = self.class.new(@object.strftime(self.class.const_get(:FORMAT))).object
    @zone = nil
  else
    md = zone.to_s.match(ZONE_GRAMMAR)
    raise ArgumentError,
          "expected #{zone.inspect} to be a xsd:dayTimeDuration or +/-HH:MM" unless md

    # Adjust to zone
    si, hr, mi = md[:si], md[:hr], md[:mi]
    si ||= '+'
    offset = hr.to_i * 60 + mi.to_i
    raise ArgumentError,
          "Zone adjustment of #{zone} out of range" if
          md.nil? || offset > 14*60

    new_zone = "%s%.2d:%.2d" % [si, hr.to_i, mi.to_i]
    dt = @zone.nil? ? @object : @object.new_offset(new_zone)
    @object = self.class.new(dt.strftime(self.class.const_get(:FORMAT) + new_zone)).object
    @zone = new_zone
  end
  @string = nil
  self
end

#canonicalize!RDF::Literal

Converts this literal into its canonical lexical representation. with date and time normalized to UTC.

Returns:

See Also:

Since:

  • 3.1



60
61
62
63
64
65
66
67
# File 'lib/rdf/model/literal/temporal.rb', line 60

def canonicalize!
  if self.valid? && @zone && @zone != '+00:00'
    adjust_to_timezone!
  else
    @string = nil
  end
  self
end

#dayInteger

Days

From the XQuery function fn:day-from-dateTime.



293
# File 'lib/rdf/model/literal/temporal.rb', line 293

def day; Integer.new(object.day); end

#hoursInteger

Hours

From the XQuery function fn:hours-from-dateTime.



301
# File 'lib/rdf/model/literal/temporal.rb', line 301

def hours; Integer.new(object.hour); end

#milliseconds?Boolean Also known as: has_milliseconds?, has_ms?, ms?

Does the literal representation include millisectonds?

Returns:

Since:

  • 1.1.6



126
127
128
# File 'lib/rdf/model/literal/temporal.rb', line 126

def milliseconds?
  object.strftime("%L").to_i > 0
end

#minutesInteger

Minutes

From the XQuery function fn:minutes-from-dateTime.



309
# File 'lib/rdf/model/literal/temporal.rb', line 309

def minutes; Integer.new(object.min); end

#monthInteger

Months

From the XQuery function fn:month-from-dateTime.



285
# File 'lib/rdf/model/literal/temporal.rb', line 285

def month; Integer.new(object.month); end

#secondsDecimal

Seconds

From the XQuery function fn:seconds-from-dateTime.



317
# File 'lib/rdf/model/literal/temporal.rb', line 317

def seconds; Decimal.new(object.strftime("%S.%L")); end

#timezoneRDF::Literal

Returns the timezone part of arg as an xsd:dayTimeDuration, or nil if lexical form of literal does not include a timezone.

From fn:timezone-from-date.



99
100
101
102
103
104
105
106
107
# File 'lib/rdf/model/literal/temporal.rb', line 99

def timezone
  if @zone
    md = @zone.match(ZONE_GRAMMAR)
    si, hr, mi = md[:si], md[:hr].to_i, md[:mi].to_i
    si = nil unless si == "-"
    res = "#{si}PT#{hr}H#{"#{mi}M" if mi > 0}"
    RDF::Literal(res, datatype: RDF::URI("http://www.w3.org/2001/XMLSchema#dayTimeDuration"))
  end
end

#timezone?Boolean Also known as: tz?, has_tz?, has_timezone?

Does the literal representation include a timezone? Note that this is only possible if initialized using a string, or :lexical option.

Returns:

Since:

  • 1.1.6



82
83
84
85
86
# File 'lib/rdf/model/literal/temporal.rb', line 82

def timezone?
  # Can only know there's a timezone from the string represntation
  md = to_s.match(self.class.const_get(:GRAMMAR))
  md && !!md[2]
end

#to_sString

Returns the timezone of the literal. If the

Returns the value as a string.

Returns:

  • (String)

Since:

  • 3.1



139
140
141
# File 'lib/rdf/model/literal/temporal.rb', line 139

def to_s
  @string ||= (@object.strftime(self.class.const_get(:FORMAT)).sub('.000', '') + self.tz)
end

#tzRDF::Literal

Returns the timezone part of arg as a simple literal. Returns the empty string if there is no timezone.

Returns:

Since:

  • 3.1



73
74
75
# File 'lib/rdf/model/literal/temporal.rb', line 73

def tz
  RDF::Literal(@zone == "+00:00" ? 'Z' : @zone)
end

#valid?Boolean

Returns true if the value adheres to the defined grammar of the datatype.

Special case for date and dateTime, for which '0000' is not a valid year

Returns:

Since:

  • 0.2.1



117
118
119
# File 'lib/rdf/model/literal/temporal.rb', line 117

def valid?
  super && object && value !~ %r(\A0000)
end

#yearInteger

Years

From the XQuery function fn:year-from-dateTime.



277
# File 'lib/rdf/model/literal/temporal.rb', line 277

def year; Integer.new(object.year); end