Class: CocinaDisplay::Dates::DateRange

Inherits:
Date
  • Object
show all
Defined in:
lib/cocina_display/dates/date_range.rb

Overview

A date range parsed from Cocina structuredValues.

Constant Summary

Constants inherited from Date

CocinaDisplay::Dates::Date::BCE_CHAR_SORT_MAP, CocinaDisplay::Dates::Date::UNPARSABLE_VALUES

Instance Attribute Summary collapse

Attributes inherited from Date

#cocina, #date, #type

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Date

#<=>, #approximate?, #as_range, #encoding?, #end?, format_date, #inferred?, #label, normalize_to_edtf, notifier, parse_date, #precision, #questionable?, #start?, #to_a, #to_s

Constructor Details

#initialize(cocina, start: nil, stop: nil) ⇒ CocinaDisplay::DateRange

Create a new date range using two CocinaDisplay::Date objects.

Parameters:

  • cocina (Hash)

    Cocina date data containing structuredValue

  • start (CocinaDisplay::Date, nil) (defaults to: nil)

    The start date of the range.

  • stop (CocinaDisplay::Date, nil) (defaults to: nil)

    The end date of the range.



36
37
38
39
40
41
# File 'lib/cocina_display/dates/date_range.rb', line 36

def initialize(cocina, start: nil, stop: nil)
  @cocina = cocina
  @start = start
  @stop = stop
  @type = cocina["type"]
end

Instance Attribute Details

#startObject (readonly)

Returns the value of attribute start.



5
6
7
# File 'lib/cocina_display/dates/date_range.rb', line 5

def start
  @start
end

#stopObject (readonly)

Returns the value of attribute stop.



5
6
7
# File 'lib/cocina_display/dates/date_range.rb', line 5

def stop
  @stop
end

Class Method Details

.from_cocina(cocina) ⇒ CocinaDisplay::DateRange?

Construct a DateRange from Cocina hash with structuredValue.

Parameters:

  • cocina (Hash)

    Cocina date data containing structuredValue

Returns:

  • (CocinaDisplay::DateRange)
  • (nil)

    if no parsable start or stop dates are found



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/cocina_display/dates/date_range.rb', line 11

def self.from_cocina(cocina)
  return unless cocina["structuredValue"].present?

  # Create the individual dates; if no encoding/type declared give them
  # top-level encoding/type
  dates = cocina["structuredValue"].map do |sv|
    date = Date.from_cocina(sv)
    date.encoding ||= cocina.dig("encoding", "code")
    date.type ||= cocina["type"]
    date
  end

  # Ensure we have at least a start or a stop
  start = dates.find(&:start?)
  stop = dates.find(&:end?)
  return unless start || stop

  DateRange.new(cocina, start: start, stop: stop)
end

Instance Method Details

#as_intervalEDTF::Interval

Express the range as an EDTF::Interval between the start and stop dates.

Returns:

  • (EDTF::Interval)


142
143
144
145
146
# File 'lib/cocina_display/dates/date_range.rb', line 142

def as_interval
  interval_start = start&.date&.edtf || "open"
  interval_stop = stop&.date&.edtf || "open"
  ::Date.edtf("#{interval_start}/#{interval_stop}")
end

#base_valueString

Note:

This is important for uniqueness checks in Imprint display.

Base values of start/end as single string. Used for comparison/deduping.

Returns:

  • (String)


61
62
63
# File 'lib/cocina_display/dates/date_range.rb', line 61

def base_value
  "#{@start&.base_value}-#{@stop&.base_value}"
end

#decoded_value(**kwargs) ⇒ String

Decoded version of the range, if it was encoded. Strips leading zeroes.

Returns:

  • (String)

See Also:

  • CocinaDisplay::Date#decoded_value


115
116
117
118
119
120
# File 'lib/cocina_display/dates/date_range.rb', line 115

def decoded_value(**kwargs)
  [
    start&.decoded_value(**kwargs),
    stop&.decoded_value(**kwargs)
  ].uniq.join(" - ")
end

#encodingString?

The encoding value for the range. Uses the start encoding, stop encoding, or top-level encoding in that order.

Returns:

  • (String, nil)

See Also:

  • CocinaDisplay::Date#encoding


69
70
71
# File 'lib/cocina_display/dates/date_range.rb', line 69

def encoding
  start&.encoding || stop&.encoding || super
end

#parsable?Boolean

False if both dates in the range have a known unparsable value like “9999”.

Returns:

  • (Boolean)

See Also:

  • CocinaDisplay::Date#parsable?


108
109
110
# File 'lib/cocina_display/dates/date_range.rb', line 108

def parsable?
  start&.parsable? || stop&.parsable? || false
end

#parsed_date?Boolean

Was either date in the range successfully parsed?

Returns:

  • (Boolean)

See Also:

  • CocinaDisplay::Date#parsed_date?


101
102
103
# File 'lib/cocina_display/dates/date_range.rb', line 101

def parsed_date?
  start&.parsed_date? || stop&.parsed_date? || false
end

#primary?Boolean

Is either date in the range marked as primary?

Returns:

  • (Boolean)

See Also:

  • CocinaDisplay::Date#primary?


94
95
96
# File 'lib/cocina_display/dates/date_range.rb', line 94

def primary?
  start&.primary? || stop&.primary? || super
end

#qualified?Boolean

Is either date in the range, or the range itself, qualified?

Returns:

  • (Boolean)

See Also:

  • CocinaDisplay::Date#qualified?


87
88
89
# File 'lib/cocina_display/dates/date_range.rb', line 87

def qualified?
  start&.qualified? || stop&.qualified? || super
end

#qualified_valueString

Decoded range with “BCE” or “CE” and qualifier markers applied.

Returns:

  • (String)

See Also:

  • CocinaDisplay::Date#qualified_value


125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/cocina_display/dates/date_range.rb', line 125

def qualified_value
  if qualifier
    case qualifier
    when "approximate"
      "[ca. #{decoded_value}]"
    when "questionable"
      "[#{decoded_value}?]"
    when "inferred"
      "[#{decoded_value}]"
    end
  else
    "#{start&.qualified_value} - #{stop&.qualified_value}"
  end
end

#qualifierString?

The qualifier for the entire range. If both qualifiers match, uses that qualifier. If both are empty, falls back to the top level qualifier, if any.

Returns:

  • (String, nil)

See Also:

  • CocinaDisplay::Date#qualifier


78
79
80
81
82
# File 'lib/cocina_display/dates/date_range.rb', line 78

def qualifier
  if start&.qualifier == stop&.qualifier
    start&.qualifier || stop&.qualifier || super
  end
end

#sort_keyString

Key used to sort this date range. Respects BCE/CE ordering and precision. Ranges are sorted first by their start date, then by their stop date.

Returns:

  • (String)

See Also:

  • CocinaDisplay::Date#sort_key


54
55
56
# File 'lib/cocina_display/dates/date_range.rb', line 54

def sort_key
  [start&.sort_key, stop&.sort_key].join(" - ")
end

#valueArray<String>

The values of the start and stop dates as an array.

Returns:

  • (Array<String>)

See Also:

  • CocinaDisplay::Date#value


46
47
48
# File 'lib/cocina_display/dates/date_range.rb', line 46

def value
  [start&.value, stop&.value]
end