rdf 3.2.4 → 3.2.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fac2b932398cb302e6b2ecf300e6508879ed43314c52822d7a7ae9482127ea05
4
- data.tar.gz: 6f78f54676b45f1bfd4767b30b545ec3016de440fcb8d5803ead213eed0e799d
3
+ metadata.gz: acd1a596fac04633e2c78342c0d8ec7b6e8b6763160627987df59f9011863ac3
4
+ data.tar.gz: cd0b61a753cafe097b3c77de95dc457968661545db2a27482cd68d19facfd068
5
5
  SHA512:
6
- metadata.gz: fa02358aa8f3362695cd433767c966a5c47fc3ba4c4bc8b95952e207dbf1e693a3468ea75735c34461d012b9efcd8f72e842d007e4dd1239b26d480d9e4f3f4c
7
- data.tar.gz: e524ebef2e88903b3c8b0a48aa7b15b843924a8f6bc97fe06f524378d101409b1d88c07756b6a1be8002a38648b03d4ab362b6033f53bd810d05cc6dee141194
6
+ metadata.gz: 7a1f7d6d0fd7ee8b70c6ccdcf31468b856008f2f3c7d19203ef8b3fd0a5bf86db6a63b876492b78ce521675d88563f59ce58cda96e5f6ca38b547d14d5ca7e7a
7
+ data.tar.gz: 6b3fe1371aca25a13f44aabdfc94bc9d9914c076ad760056dc57f0b89bf3bfa06aaad5c53cf2ea0ea5f0da164e23e7033f73c2d0e503674e7b7f818c16cac1a0
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.2.4
1
+ 3.2.5
@@ -4,67 +4,41 @@ module RDF; class Literal
4
4
  #
5
5
  # @see http://www.w3.org/TR/xmlschema11-2/#date
6
6
  # @since 0.2.1
7
- class Date < Literal
7
+ class Date < Temporal
8
8
  DATATYPE = RDF::URI("http://www.w3.org/2001/XMLSchema#date")
9
9
  GRAMMAR = %r(\A(-?\d{4}-\d{2}-\d{2})((?:[\+\-]\d{2}:\d{2})|UTC|GMT|Z)?\Z).freeze
10
10
  FORMAT = '%Y-%m-%d'.freeze
11
11
 
12
12
  ##
13
- # @param [String, Date, #to_date] value
13
+ # Internally, a `Date` is represented using a native `::DateTime` object at midnight. If initialized from a `::Date`, there is no timezone component, If initialized from a `::DateTime`, the timezone is taken from that native object, otherwise, a timezone (or no timezone) is taken from the string representation having a matching `zzzzzz` component.
14
+ #
15
+ # @note If initialized using the `#to_datetime` method, time component is unchanged. Otherewise, it is set to 00:00 (midnight).
16
+ #
17
+ # @param [String, Date, #to_datetime] value
14
18
  # @param (see Literal#initialize)
15
19
  def initialize(value, datatype: nil, lexical: nil, **options)
16
20
  @datatype = RDF::URI(datatype || self.class.const_get(:DATATYPE))
17
21
  @string = lexical || (value if value.is_a?(String))
18
22
  @object = case
19
- when value.is_a?(::Date) then value
20
- when value.respond_to?(:to_date) then value.to_date
21
- else ::Date.parse(value.to_s)
22
- end rescue ::Date.new
23
- end
24
-
25
- ##
26
- # Converts this literal into its canonical lexical representation.
27
- #
28
- # Note that the timezone is recoverable for xsd:date, where it is not for xsd:dateTime and xsd:time, which are both transformed relative to Z, if a timezone is provided.
29
- #
30
- # @return [RDF::Literal] `self`
31
- # @see http://www.w3.org/TR/xmlschema11-2/#date
32
- def canonicalize!
33
- @string = @object.strftime(FORMAT) + self.tz.to_s if self.valid?
34
- self
35
- end
36
-
37
- ##
38
- # Returns `true` if the value adheres to the defined grammar of the
39
- # datatype.
40
- #
41
- # Special case for date and dateTime, for which '0000' is not a valid year
42
- #
43
- # @return [Boolean]
44
- # @since 0.2.1
45
- def valid?
46
- super && object && value !~ %r(\A0000)
47
- end
48
-
49
- ##
50
- # Does the literal representation include a timezone? Note that this is only possible if initialized using a string, or `:lexical` option.
51
- #
52
- # @return [Boolean]
53
- # @since 1.1.6
54
- def timezone?
55
- md = self.to_s.match(GRAMMAR)
56
- md && !!md[2]
57
- end
58
- alias_method :tz?, :timezone?
59
- alias_method :has_tz?, :timezone?
60
- alias_method :has_timezone?, :timezone?
61
-
62
- ##
63
- # Returns the value as a string.
64
- #
65
- # @return [String]
66
- def to_s
67
- @string || @object.strftime(FORMAT)
23
+ when value.class == ::Date
24
+ @zone = nil
25
+ # Use midnight as midpoint of the interval
26
+ ::DateTime.parse(value.strftime('%FT00:00:00'))
27
+ when value.respond_to?(:to_datetime)
28
+ dt = value.to_datetime
29
+ @zone = dt.zone
30
+ dt
31
+ else
32
+ md = value.to_s.match(GRAMMAR)
33
+ _, dt, tz = Array(md)
34
+ if tz
35
+ @zone = tz == 'Z' ? '+00:00' : tz
36
+ else
37
+ @zone = nil # No timezone
38
+ end
39
+ # Use midnight as midpoint of the interval
40
+ ::DateTime.parse("#{dt}T00:00:00#{@zone}")
41
+ end rescue ::DateTime.new
68
42
  end
69
43
 
70
44
  ##
@@ -75,42 +49,13 @@ module RDF; class Literal
75
49
  def humanize(lang = :en)
76
50
  d = object.strftime("%A, %d %B %Y")
77
51
  if timezone?
78
- d += if self.tz == 'Z'
52
+ d += if @zone == '+00:00'
79
53
  " UTC"
80
54
  else
81
- " #{self.tz}"
55
+ " #{@zone}"
82
56
  end
83
57
  end
84
58
  d
85
59
  end
86
-
87
- ##
88
- # Returns the timezone part of arg as a simple literal. Returns the empty string if there is no timezone.
89
- #
90
- # @return [RDF::Literal]
91
- # @since 1.1.6
92
- def tz
93
- md = self.to_s.match(GRAMMAR)
94
- zone = md[2].to_s
95
- zone = "Z" if zone == "+00:00"
96
- RDF::Literal(zone)
97
- end
98
-
99
- ##
100
- # Equal compares as Date objects
101
- def ==(other)
102
- # If lexically invalid, use regular literal testing
103
- return super unless self.valid?
104
-
105
- case other
106
- when Literal::Date
107
- return super unless other.valid?
108
- self.object == other.object
109
- when Literal::Time, Literal::DateTime
110
- false
111
- else
112
- super
113
- end
114
- end
115
60
  end # Date
116
61
  end; end # RDF::Literal
@@ -2,117 +2,38 @@ module RDF; class Literal
2
2
  ##
3
3
  # A date/time literal.
4
4
  #
5
- # @see http://www.w3.org/TR/xmlschema11-2/#dateTime#boolean
5
+ # @see http://www.w3.org/TR/xmlschema11-2/#dateTime
6
6
  # @since 0.2.1
7
- class DateTime < Literal
7
+ class DateTime < Temporal
8
8
  DATATYPE = RDF::URI("http://www.w3.org/2001/XMLSchema#dateTime")
9
9
  GRAMMAR = %r(\A(-?(?:\d{4}|[1-9]\d{4,})-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?)((?:[\+\-]\d{2}:\d{2})|UTC|GMT|Z)?\Z).freeze
10
- FORMAT = '%Y-%m-%dT%H:%M:%S.%L%:z'.freeze
10
+ FORMAT = '%Y-%m-%dT%H:%M:%S.%L'.freeze
11
11
 
12
12
  ##
13
+ # Internally, a `DateTime` is represented using a native `::DateTime`. If initialized from a `::Date`, there is no timezone component, If initialized from a `::DateTime`, the timezone is taken from that native object, otherwise, a timezone (or no timezone) is taken from the string representation having a matching `zzzzzz` component.
14
+ #
13
15
  # @param [DateTime] value
14
16
  # @option options [String] :lexical (nil)
15
17
  def initialize(value, datatype: nil, lexical: nil, **options)
16
18
  @datatype = RDF::URI(datatype || self.class.const_get(:DATATYPE))
17
19
  @string = lexical || (value if value.is_a?(String))
18
20
  @object = case
19
- when value.is_a?(::DateTime) then value
20
- when value.respond_to?(:to_datetime) then value.to_datetime
21
- else ::DateTime.parse(value.to_s)
22
- end rescue ::DateTime.new
23
- end
24
-
25
- ##
26
- # Converts this literal into its canonical lexical representation.
27
- # with date and time normalized to UTC.
28
- #
29
- # @return [RDF::Literal] `self`
30
- # @see http://www.w3.org/TR/xmlschema11-2/#dateTime
31
- def canonicalize!
32
- if self.valid?
33
- @string = if timezone?
34
- @object.new_offset.new_offset.strftime(FORMAT[0..-4] + 'Z').sub('.000', '')
21
+ when value.is_a?(::DateTime)
22
+ @zone = value.zone
23
+ value
24
+ when value.respond_to?(:to_datetime)
25
+ @zone = value.to_datetime.zone
26
+ value.to_datetime
35
27
  else
36
- @object.strftime(FORMAT[0..-4]).sub('.000', '')
37
- end
38
- end
39
- self
40
- end
41
-
42
- ##
43
- # Returns the timezone part of arg as a simple literal. Returns the empty string if there is no timezone.
44
- #
45
- # @return [RDF::Literal]
46
- # @see http://www.w3.org/TR/sparql11-query/#func-tz
47
- def tz
48
- zone = timezone? ? object.zone : ""
49
- zone = "Z" if zone == "+00:00"
50
- RDF::Literal(zone)
51
- end
52
-
53
- ##
54
- # Returns the timezone part of arg as an xsd:dayTimeDuration, or `nil`
55
- # if lexical form of literal does not include a timezone.
56
- #
57
- # @return [RDF::Literal]
58
- def timezone
59
- if tz == 'Z'
60
- RDF::Literal("PT0S", datatype: RDF::URI("http://www.w3.org/2001/XMLSchema#dayTimeDuration"))
61
- elsif md = tz.to_s.match(/^([+-])?(\d+):(\d+)?$/)
62
- plus_minus, hour, min = md[1,3]
63
- plus_minus = nil unless plus_minus == "-"
64
- hour = hour.to_i
65
- min = min.to_i
66
- res = "#{plus_minus}PT#{hour}H#{"#{min}M" if min > 0}"
67
- RDF::Literal(res, datatype: RDF::URI("http://www.w3.org/2001/XMLSchema#dayTimeDuration"))
68
- end
69
- end
70
-
71
- ##
72
- # Returns `true` if the value adheres to the defined grammar of the
73
- # datatype.
74
- #
75
- # Special case for date and dateTime, for which '0000' is not a valid year
76
- #
77
- # @return [Boolean]
78
- # @since 0.2.1
79
- def valid?
80
- super && object && value !~ %r(\A0000)
81
- end
82
-
83
- ##
84
- # Does the literal representation include millisectonds?
85
- #
86
- # @return [Boolean]
87
- # @since 1.1.6
88
- def milliseconds?
89
- self.format("%L").to_i > 0
90
- end
91
- alias_method :has_milliseconds?, :milliseconds?
92
- alias_method :has_ms?, :milliseconds?
93
- alias_method :ms?, :milliseconds?
94
-
95
- ##
96
- # Does the literal representation include a timezone? Note that this is only possible if initialized using a string, or `:lexical` option.
97
- #
98
- # @return [Boolean]
99
- # @since 1.1.6
100
- def timezone?
101
- md = self.to_s.match(GRAMMAR)
102
- md && !!md[2]
103
- end
104
- alias_method :tz?, :timezone?
105
- alias_method :has_tz?, :timezone?
106
- alias_method :has_timezone?, :timezone?
107
-
108
- ##
109
- # Returns the `timezone` of the literal. If the
110
- ##
111
- # Returns the value as a string.
112
- #
113
- # @return [String]
114
- def to_s
115
- @string || @object.strftime(FORMAT).sub("+00:00", 'Z').sub('.000', '')
28
+ md = value.to_s.match(GRAMMAR)
29
+ _, _, tz = Array(md)
30
+ if tz
31
+ @zone = tz == 'Z' ? '+00:00' : tz
32
+ else
33
+ @zone = nil # No timezone
34
+ end
35
+ ::DateTime.parse(value.to_s)
36
+ end rescue ::DateTime.new
116
37
  end
117
38
 
118
39
  ##
@@ -123,31 +44,10 @@ module RDF; class Literal
123
44
  def humanize(lang = :en)
124
45
  d = object.strftime("%r on %A, %d %B %Y")
125
46
  if timezone?
126
- zone = if self.tz == 'Z'
127
- "UTC"
128
- else
129
- self.tz
130
- end
131
- d.sub!(" on ", " #{zone} on ")
47
+ z = @zone == '+00:00' ? "UTC" : @zone
48
+ d.sub!(" on ", " #{z} on ")
132
49
  end
133
50
  d
134
51
  end
135
-
136
- ##
137
- # Equal compares as DateTime objects
138
- def ==(other)
139
- # If lexically invalid, use regular literal testing
140
- return super unless self.valid?
141
-
142
- case other
143
- when Literal::DateTime
144
- return super unless other.valid?
145
- self.object == other.object
146
- when Literal::Time, Literal::Date
147
- false
148
- else
149
- super
150
- end
151
- end
152
52
  end # DateTime
153
53
  end; end # RDF::Literal
@@ -54,7 +54,10 @@ module RDF; class Literal
54
54
  ##
55
55
  # Returns the absolute value of `self`.
56
56
  #
57
+ # From the XQuery function [fn:abs](https://www.w3.org/TR/xpath-functions/#func-abs).
58
+ #
57
59
  # @return [RDF::Literal]
60
+ # @see https://www.w3.org/TR/xpath-functions/#func-abs
58
61
  # @since 0.2.3
59
62
  def abs
60
63
  (d = to_d) && d > 0 ? self : RDF::Literal(d.abs)
@@ -63,7 +66,10 @@ module RDF; class Literal
63
66
  ##
64
67
  # Returns the number with no fractional part that is closest to the argument. If there are two such numbers, then the one that is closest to positive infinity is returned. An error is raised if arg is not a numeric value.
65
68
  #
69
+ # From the XQuery function [fn:round](https://www.w3.org/TR/xpath-functions/#func-round).
70
+ #
66
71
  # @return [RDF::Literal::Decimal]
72
+ # @see https://www.w3.org/TR/xpath-functions/#func-round
67
73
  def round
68
74
  rounded = to_d.round(half: (to_d < 0 ? :down : :up))
69
75
  if rounded == -0.0
@@ -77,10 +83,13 @@ module RDF; class Literal
77
83
  ##
78
84
  # Returns the smallest integer greater than or equal to `self`.
79
85
  #
86
+ # From the XQuery function [fn:ceil](https://www.w3.org/TR/xpath-functions/#func-ceil).
87
+ #
80
88
  # @example
81
89
  # RDF::Literal(1).ceil #=> RDF::Literal(1)
82
90
  #
83
91
  # @return [RDF::Literal::Integer]
92
+ # @see https://www.w3.org/TR/xpath-functions/#func-ceil
84
93
  def ceil
85
94
  RDF::Literal::Integer.new(to_d.ceil)
86
95
  end
@@ -88,10 +97,13 @@ module RDF; class Literal
88
97
  ##
89
98
  # Returns the largest integer less than or equal to `self`.
90
99
  #
100
+ # From the XQuery function [fn:floor](https://www.w3.org/TR/xpath-functions/#func-floor).
101
+ #
91
102
  # @example
92
103
  # RDF::Literal(1).floor #=> RDF::Literal(1)
93
104
  #
94
105
  # @return [RDF::Literal::Integer]
106
+ # @see https://www.w3.org/TR/xpath-functions/#func-floor
95
107
  def floor
96
108
  RDF::Literal::Integer.new(to_d.floor)
97
109
  end
@@ -34,6 +34,14 @@ module RDF; class Literal
34
34
  end
35
35
  end
36
36
 
37
+ # Approximation of the mathematical constant π
38
+ #
39
+ # From the XQuery function [math:pi](https://www.w3.org/TR/xpath-functions/#func-math-pi).
40
+ #
41
+ # @return [Double]
42
+ # @see https://www.w3.org/TR/xpath-functions/#func-math-pi
43
+ PI = Double.new(Math::PI)
44
+
37
45
  ##
38
46
  # Converts this literal into its canonical lexical representation.
39
47
  #
@@ -145,6 +153,8 @@ module RDF; class Literal
145
153
  ##
146
154
  # Returns the smallest integer greater than or equal to `self`.
147
155
  #
156
+ # From the XQuery function [fn:ceil](https://www.w3.org/TR/xpath-functions/#func-ceil).
157
+ #
148
158
  # @example
149
159
  # RDF::Literal(1.2).ceil #=> RDF::Literal(2)
150
160
  # RDF::Literal(-1.2).ceil #=> RDF::Literal(-1)
@@ -152,6 +162,7 @@ module RDF; class Literal
152
162
  # RDF::Literal(-2.0).ceil #=> RDF::Literal(-2)
153
163
  #
154
164
  # @return [RDF::Literal::Integer]
165
+ # @see https://www.w3.org/TR/xpath-functions/#func-ceil
155
166
  # @since 0.2.3
156
167
  def ceil
157
168
  RDF::Literal::Integer.new(to_f.ceil)
@@ -160,6 +171,8 @@ module RDF; class Literal
160
171
  ##
161
172
  # Returns the largest integer less than or equal to `self`.
162
173
  #
174
+ # From the XQuery function [fn:floor](https://www.w3.org/TR/xpath-functions/#func-floor).
175
+ #
163
176
  # @example
164
177
  # RDF::Literal(1.2).floor #=> RDF::Literal(1)
165
178
  # RDF::Literal(-1.2).floor #=> RDF::Literal(-2)
@@ -167,6 +180,7 @@ module RDF; class Literal
167
180
  # RDF::Literal(-2.0).floor #=> RDF::Literal(-2)
168
181
  #
169
182
  # @return [RDF::Literal::Integer]
183
+ # @see https://www.w3.org/TR/xpath-functions/#func-floor
170
184
  # @since 0.2.3
171
185
  def floor
172
186
  RDF::Literal::Integer.new(to_f.floor)
@@ -175,7 +189,10 @@ module RDF; class Literal
175
189
  ##
176
190
  # Returns the absolute value of `self`.
177
191
  #
192
+ # From the XQuery function [fn:abs](https://www.w3.org/TR/xpath-functions/#func-abs).
193
+ #
178
194
  # @return [RDF::Literal]
195
+ # @see https://www.w3.org/TR/xpath-functions/#func-abs
179
196
  # @since 0.2.3
180
197
  def abs
181
198
  (f = to_f) && f > 0 ? self : self.class.new(f.abs)
@@ -184,7 +201,10 @@ module RDF; class Literal
184
201
  ##
185
202
  # Returns the number with no fractional part that is closest to the argument. If there are two such numbers, then the one that is closest to positive infinity is returned. An error is raised if arg is not a numeric value.
186
203
  #
204
+ # From the XQuery function [fn:round](https://www.w3.org/TR/xpath-functions/#func-round).
205
+ #
187
206
  # @return [RDF::Literal::Double]
207
+ # @see https://www.w3.org/TR/xpath-functions/#func-round
188
208
  def round
189
209
  self.class.new(to_d.round(half: (to_d < 0 ? :down : :up)))
190
210
  end
@@ -78,7 +78,10 @@ module RDF; class Literal
78
78
  ##
79
79
  # Returns the absolute value of `self`.
80
80
  #
81
+ # From the XQuery function [fn:abs](https://www.w3.org/TR/xpath-functions/#func-abs).
82
+ #
81
83
  # @return [RDF::Literal]
84
+ # @see https://www.w3.org/TR/xpath-functions/#func-abs
82
85
  # @since 0.2.3
83
86
  def abs
84
87
  (n = to_i) && n > 0 ? self : self.class.new(n.abs)
@@ -87,7 +90,10 @@ module RDF; class Literal
87
90
  ##
88
91
  # Returns `self`.
89
92
  #
93
+ # From the XQuery function [fn:round](https://www.w3.org/TR/xpath-functions/#func-round).
94
+ #
90
95
  # @return [RDF::Literal]
96
+ # @see https://www.w3.org/TR/xpath-functions/#func-round
91
97
  def round
92
98
  self
93
99
  end