Class: CarbonDate::Date

Inherits:
Object
  • Object
show all
Defined in:
lib/carbon_date/date.rb

Overview

A date with a precision

Constant Summary collapse

PRECISION =

The precisions available

TODO: Consider refactoring into a simple array of symbols, since level could be replaced by the index in the array

[
  {symbol: :second, level: 14},
  {symbol: :minute, level: 13},
  {symbol: :hour, level: 12},
  {symbol: :day, level: 11},
  {symbol: :month, level: 10},
  {symbol: :year, level: 9,},
  {symbol: :decade, level: 8,},
  {symbol: :century, level: 7,},
  {symbol: :millennium, level: 6,},
  {symbol: :ten_thousand_years, level: 5,},
  {symbol: :hundred_thousand_years, level: 4},
  {symbol: :million_years, level: 3},
  {symbol: :ten_million_years, level: 2},
  {symbol: :hundred_million_years, level: 1},
  {symbol: :billion_years, level: 0}
]

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(year = 1970, month = 1, day = 1, hour = 0, minute = 0, second = 0, precision: :second) ⇒ Date

Returns a new instance of Date.



40
41
42
43
44
45
46
47
48
# File 'lib/carbon_date/date.rb', line 40

def initialize(year = 1970, month = 1, day = 1, hour = 0, minute = 0, second = 0, precision: :second)
  month = 1 if month == 0
  day = 1 if day == 0
  self.precision = precision
  self.set_date(year, month, day)
  self.hour = hour
  self.minute = minute
  self.second = second
end

Class Attribute Details

.formatterObject

Returns the value of attribute formatter.



13
14
15
# File 'lib/carbon_date/date.rb', line 13

def formatter
  @formatter
end

Instance Attribute Details

#dayObject

Returns the value of attribute day.



38
39
40
# File 'lib/carbon_date/date.rb', line 38

def day
  @day
end

#hourObject

Returns the value of attribute hour.



38
39
40
# File 'lib/carbon_date/date.rb', line 38

def hour
  @hour
end

#minuteObject

Returns the value of attribute minute.



38
39
40
# File 'lib/carbon_date/date.rb', line 38

def minute
  @minute
end

#monthObject

Returns the value of attribute month.



38
39
40
# File 'lib/carbon_date/date.rb', line 38

def month
  @month
end

#precisionObject

Returns the value of attribute precision.



38
39
40
# File 'lib/carbon_date/date.rb', line 38

def precision
  @precision
end

#secondObject

Returns the value of attribute second.



38
39
40
# File 'lib/carbon_date/date.rb', line 38

def second
  @second
end

#yearObject

Returns the value of attribute year.



38
39
40
# File 'lib/carbon_date/date.rb', line 38

def year
  @year
end

Class Method Details

.iso8601(string, precision_level) ⇒ Object

Converts from an iso8601 datetime format, with precision

Dates like these are found on Wikidata (www.wikidata.org)

string -> the iso8601 datetime in the form +1989-03-23T23:11:08Z precision_level -> an integer between 0 and 14 (see CarbonDate::Date::PRECISION)

Raises:

  • (ArgumentError)


139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/carbon_date/date.rb', line 139

def self.iso8601(string, precision_level)
  p = PRECISION.find { |p| p[:level] == precision_level}
  raise ArgumentError.new("Invalid precision level #{precision_level}") unless p
  # If there is an initial '-' symbol on the year, it needs to be treateded differenty than the other '-'.
  # Example: -0500-01-01 is the 1st January 500 BCE
  if string[0] == '-'
    string = string[1..(string.length - 1)] # Drop the initial '-'
    bce = true
  else
    bce = false
  end
  d = string.split('T').map { |x| x.split /[-:]/ }.flatten.map(&:to_i)
  year = bce ? -d[0] : d[0]
  CarbonDate::Date.new(year, d[1], d[2], d[3], d[4], d[5], precision: p[:symbol])
end

Instance Method Details

#<=(another_date) ⇒ Object



178
179
180
# File 'lib/carbon_date/date.rb', line 178

def <=(another_date)
  self.to_datetime <= another_date.to_datetime
end

#==(another_date) ⇒ Object



173
174
175
176
# File 'lib/carbon_date/date.rb', line 173

def ==(another_date)
  return false if self.precision != another_date.precision
  self.to_datetime == another_date.to_datetime
end

#>=(another_date) ⇒ Object



182
183
184
# File 'lib/carbon_date/date.rb', line 182

def >=(another_date)
  self.to_datetime >= another_date.to_datetime
end

#set_date(year, month, day) ⇒ Object

An atomic function to set the date component.

Raises ArgumentError if invalid date

Raises:

  • (ArgumentError)


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/carbon_date/date.rb', line 64

def set_date(year, month, day)

  raise ArgumentError.new("Invalid date #{year}-#{month}-#{day}") unless (1..12).include? month
  raise ArgumentError.new("Invalid date #{year}-#{month}-#{day}") if (year.nil? || year == 0)

  begin
    ::Date.new(year, month, day)
  rescue ArgumentError
    raise ArgumentError.new("Invalid date #{year}-#{month}-#{day}")
  end

  @year = year.to_i
  @month = month
  @day = day

end

#to_dateObject

Convert to a standard Ruby Date object



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

def to_date
  ::Date.new(@year, @month, @day)
end

#to_datetimeObject

Convert into a standard Ruby DateTime object



169
170
171
# File 'lib/carbon_date/date.rb', line 169

def to_datetime
  ::DateTime.new(@year, @month, @day, @hour, @minute, @second)
end

#to_sObject

Prints a human-readable version of the date, using a Formatter



157
158
159
# File 'lib/carbon_date/date.rb', line 157

def to_s
  CarbonDate::Date.formatter.date_to_string(self)
end