Class: Date

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/edtf/date.rb

Constant Summary collapse

PRECISION =
[:year, :month, :day].freeze
PRECISIONS =
Hash[*PRECISION.map { |p| [p, "#{p}s".to_sym] }.flatten].freeze
FORMATS =
%w{ %04d %02d %02d }.freeze
SYMBOLS =
{
	:uncertain   => '?',
	:approximate => '~',
	:calendar    => '^',
	:unspecified => 'u'
}.freeze
EXTENDED_ATTRIBUTES =
%w{ calendar precision uncertain approximate
unspecified }.map(&:to_sym).freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#approximateObject



94
95
96
# File 'lib/edtf/date.rb', line 94

def approximate
  @approximate ||= EDTF::Uncertainty.new(nil, nil, nil, 8)
end

#calendarObject

Returns the value of attribute calendar.



33
34
35
# File 'lib/edtf/date.rb', line 33

def calendar
  @calendar
end

#uncertainObject



90
91
92
# File 'lib/edtf/date.rb', line 90

def uncertain
  @uncertain ||= EDTF::Uncertainty.new
end

#unspecifiedObject



98
99
100
# File 'lib/edtf/date.rb', line 98

def unspecified
  @unspecified ||= EDTF::Unspecified.new
end

Class Method Details

.edtf(input, options = {}) ⇒ Object



22
23
24
25
26
# File 'lib/edtf/date.rb', line 22

def edtf(input, options = {})
  edtf!(input, options)
rescue
  nil
end

.edtf!(input, options = {}) ⇒ Object



28
29
30
# File 'lib/edtf/date.rb', line 28

def edtf!(input, options = {})
  ::EDTF::Parser.new(options).parse!(input)
end

Instance Method Details

#<=>(other) ⇒ Object



246
247
248
249
# File 'lib/edtf/date.rb', line 246

def <=>(other)
return nil unless other.is_a?(::Date)
values <=> other.values
end

#advance(options) ⇒ Object

Provides precise Date calculations for years, months, and days. The options parameter takes a hash with any of these keys: :years, :months, :weeks, :days.



60
61
62
# File 'lib/edtf/date.rb', line 60

def advance(options)
  original_advance(options).copy_extended_attributes(self)
end

#approximate!(arguments = precision_filter) ⇒ Object Also known as: approximately!



120
121
122
123
# File 'lib/edtf/date.rb', line 120

def approximate!(arguments = precision_filter)
  approximate.uncertain!(arguments)
  self
end

#approximate?(arguments = precision_filter) ⇒ Boolean Also known as: approximately?

Returns:

  • (Boolean)


114
115
116
# File 'lib/edtf/date.rb', line 114

def approximate?(arguments = precision_filter)
  approximate.uncertain?(arguments)
end

#calendar?Boolean

Returns true if the Date has an EDTF calendar string attached.

Returns:

  • (Boolean)


160
# File 'lib/edtf/date.rb', line 160

def calendar?; !!@calendar; end

#certain!(arguments = precision_filter) ⇒ Object



104
105
106
107
# File 'lib/edtf/date.rb', line 104

def certain!(arguments = precision_filter)
  uncertain.certain!(arguments)
  self
end

#change(options) ⇒ Object

Returns a new Date where one or more of the elements have been changed according to the options parameter.



68
69
70
71
72
73
74
# File 'lib/edtf/date.rb', line 68

def change(options)
  d = original_change(options)
  EXTENDED_ATTRIBUTES.each do |attribute|
    d.send("#{attribute}=", options[attribute] || send(attribute))
  end
  d
end

#edtfObject Also known as: to_edtf

Returns the Date’s EDTF string.



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/edtf/date.rb', line 168

def edtf
return "y#{year}" if long_year?

s = FORMATS.take(values.length).zip(values).map { |f,v| f % v }
s = unspecified.mask(s)

  unless (h = ua_hash).zero?
    #
    # To efficiently calculate the uncertain/approximate state we use
    # the bitmask. The primary flags are:
    #
    # Uncertain:    1 - year,  2 - month,  4 - day
    # Approximate:  8 - year, 16 - month, 32 - day
    #
    # Invariant: assumes that uncertain/approximate are not set for values
    # not covered by precision!
    #
    y, m, d = s
    
    # ?/~ if true-false or true-true and other false-true
    y << SYMBOLS[:uncertain]   if  3&h==1 || 27&h==19
    y << SYMBOLS[:approximate] if 24&h==8 || 27&h==26
    

    # combine if false-true-true and other m == d 
    if 7&h==6 && (48&h==48 || 48&h==0)  || 56&h==48 && (6&h==6 || 6&h==0)
      m[0,0] = '('
      d << ')'
    else
      case
      # false-true
      when 3&h==2 || 24&h==16
        m[0,0] = '('
        m << ')'
    
      # *-false-true
      when 6&h==4 || 48&h==32
        d[0,0] = '('
        d << ')'
      end
    
      # ?/~ if *-true-false or *-true-true and other m != d 
      m << SYMBOLS[:uncertain]   if h!=31 && (6&h==2  ||  6&h==6  && (48&h==16 || 48&h==32))
      m << SYMBOLS[:approximate] if h!=59 && (48&h==16 || 48&h==48 && (6&h==2 || 6&h==4))
    end
    
    # ?/~ if *-*-true
    d << SYMBOLS[:uncertain]   if  4&h==4
    d << SYMBOLS[:approximate] if 32&h==32      
  end

  s = s.join('-')
s << SYMBOLS[:calendar] << calendar if calendar?
s
end

#initialize_copy(other) ⇒ Object



49
50
51
52
# File 'lib/edtf/date.rb', line 49

def initialize_copy(other)
super
copy_extended_attributes(other)
end

#long_year?Boolean

Returns true if this Date/Time has year precision and the year exceeds four digits.

Returns:

  • (Boolean)


266
267
268
# File 'lib/edtf/date.rb', line 266

def long_year?
	year_precision? && year.abs > 9999
end

#negateObject Also known as: -@

Returns the same date but with negated year.



259
260
261
# File 'lib/edtf/date.rb', line 259

def negate
change(:year => year * -1)
end

#next(n = 1) ⇒ Object

Returns an array of the next n days, months, or years depending on the current Date/Time’s precision.



228
229
230
# File 'lib/edtf/date.rb', line 228

def next(n = 1)
	1.upto(n).map { |by| advance(PRECISIONS[precision] => by) }
end

#original_advanceObject

Alias advance method from Active Support.



56
# File 'lib/edtf/date.rb', line 56

alias original_advance advance

#original_changeObject

Alias change method from Active Support.



65
# File 'lib/edtf/date.rb', line 65

alias original_change change

#precise!(arguments = precision_filter) ⇒ Object Also known as: precisely!



133
134
135
136
# File 'lib/edtf/date.rb', line 133

def precise!(arguments = precision_filter)
  approximate.certain!(arguments)
  self
end

#precise?(arguments = precision_filter) ⇒ Boolean Also known as: precisely?

Returns:

  • (Boolean)


127
128
129
# File 'lib/edtf/date.rb', line 127

def precise?(arguments = precision_filter)
  !approximate?(arguments)
end

#precisionObject

Returns this Date’s precision.



78
79
80
# File 'lib/edtf/date.rb', line 78

def precision
  @precision ||= :day
end

#precision=(precision) ⇒ Object

Sets this Date/Time’s precision to the passed-in value.

Raises:

  • (ArgumentError)


83
84
85
86
87
88
# File 'lib/edtf/date.rb', line 83

def precision=(precision)
  precision = precision.to_sym
  raise ArgumentError, "invalid precision #{precision.inspect}" unless PRECISION.include?(precision)
  @precision = precision
  update_precision_filter[-1]
end

#prev(n = 1) ⇒ Object

Returns the Date of the previous day, month, or year depending on the current Date/Time’s precision.



238
239
240
241
242
243
244
# File 'lib/edtf/date.rb', line 238

def prev(n = 1)
  if n > 1
    1.upto(n).map { |by| advance(PRECISIONS[precision] => -by) }
  else
    advance(PRECISIONS[precision] => -1)
  end
end

#seasonObject

Converts the Date into a season.



163
164
165
# File 'lib/edtf/date.rb', line 163

def season
  Season.new(self)
end

#season?Boolean

Returns false for Dates.

Returns:

  • (Boolean)


157
# File 'lib/edtf/date.rb', line 157

def season?; false; end

#specified!(arguments = precision_filter) ⇒ Object Also known as: specific!



149
150
151
152
# File 'lib/edtf/date.rb', line 149

def specified!(arguments = precision_filter)
  unspecified.specified!(arguments)
  self
end

#succObject



232
233
234
# File 'lib/edtf/date.rb', line 232

def succ
	advance(PRECISIONS[precision] => 1)
end

#uncertain!(arguments = precision_filter) ⇒ Object



109
110
111
112
# File 'lib/edtf/date.rb', line 109

def uncertain!(arguments = precision_filter)
  uncertain.uncertain!(arguments)
  self
end

#unspecified!(arguments = precision_filter) ⇒ Object Also known as: unspecific!



142
143
144
145
# File 'lib/edtf/date.rb', line 142

def unspecified!(arguments = precision_filter)
  unspecified.unspecified!(arguments)
  self
end

#valuesObject

Returns an array of the current year, month, and day values filtered by the Date/Time’s precision.



254
255
256
# File 'lib/edtf/date.rb', line 254

def values
  precision_filter.map { |p| send(p) }
end