Class: CarbonDate::Date

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

Overview

Models a date with a precision. The conventions of the Gregorian Calendar are used to model dates.

Constant Summary collapse

PRECISION =

The precisions available

[
  :billion_years,
  :hundred_million_years,
  :ten_million_years,
  :million_years,
  :hundred_thousand_years,
  :ten_thousand_years,
  :millennium,
  :century,
  :decade,
  :year,
  :month,
  :day,
  :hour,
  :minute,
  :second
]

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

Creates a new CarbonDate::Date

Params: year - The date’s year, as an integer month - The date’s month, as an integer day - The date’s day, as an integer hour - The date’s hour, as an integer minute - The date’s minute, as an integer second - The date’s second, as an integer :precision - The date’s precision, as a symbol. For avaiable options, see CarbonDate::Date::PRECISION Raises: ArgumentError if validations fail Returns: CarbonDate::Date object



69
70
71
72
73
74
75
76
77
# File 'lib/carbon_date/date.rb', line 69

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

Used to get and set the CarbonDate::Date.formatter



16
17
18
# File 'lib/carbon_date/date.rb', line 16

def formatter
  @formatter
end

Instance Attribute Details

#dayObject

The date’s day counting from 1



47
48
49
# File 'lib/carbon_date/date.rb', line 47

def day
  @day
end

#hourObject

The date’s hour in range (0..23)



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

def hour
  @hour
end

#minuteObject

The date’s minute in range (0..59)



51
52
53
# File 'lib/carbon_date/date.rb', line 51

def minute
  @minute
end

#monthObject

The date’s month in range (1..12)



45
46
47
# File 'lib/carbon_date/date.rb', line 45

def month
  @month
end

#precisionObject

The date’s precision



41
42
43
# File 'lib/carbon_date/date.rb', line 41

def precision
  @precision
end

#secondObject

The date’s second in range (0..59)



53
54
55
# File 'lib/carbon_date/date.rb', line 53

def second
  @second
end

#yearObject

The date’s year. Cannot be 0 as there is no 0 year in the Gregorian Calendar.



43
44
45
# File 'lib/carbon_date/date.rb', line 43

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) Params: string -> the iso8601 datetime in the form +1989-03-23T23:11:08Z precision_level -> an integer between 0 and 14 (see CarbonDate::Date::PRECISION) Returns: CarbonDate::Date object

Raises:

  • (ArgumentError)


147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/carbon_date/date.rb', line 147

def self.iso8601(string, precision_level)
  p = PRECISION[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)
end

Instance Method Details

#<=(another_date) ⇒ Object

Tests if this CarbonDate::Date is in the past relative to the other CarbonDate::Date Defers to DateTime#<=



198
199
200
# File 'lib/carbon_date/date.rb', line 198

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

#==(another_date) ⇒ Object

Test equality of two CarbonDate::Dates For equality, the two dates have to have the same:

  • precision

  • year

  • month

  • day

  • hour

  • minute

  • second



191
192
193
194
# File 'lib/carbon_date/date.rb', line 191

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

#>=(another_date) ⇒ Object

Tests if this CarbonDate::Date is in the future relative to the other CarbonDate::Date Defers to DateTime#>=



204
205
206
# File 'lib/carbon_date/date.rb', line 204

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

#invalid_dateObject



208
209
210
# File 'lib/carbon_date/date.rb', line 208

def invalid_date
  ArgumentError.new("Invalid date #{year}-#{month}-#{day}")
end

#set_date(year, month, day) ⇒ Object

An atomic function to set the date component (year, month and day) Raises ArgumentError if invalid date



88
89
90
91
92
93
94
95
96
97
98
# File 'lib/carbon_date/date.rb', line 88

def set_date(year, month, day)
  raise invalid_date if (year.nil? || year == 0 || !((1..12).include? month))
  begin
    ::Date.new(year, month, day)
  rescue ArgumentError
    raise invalid_date
  end
  @year = year.to_i
  @month = month
  @day = day
end

#to_dateObject

Convert to a standard Ruby Date object Returns: ::Date object



171
172
173
# File 'lib/carbon_date/date.rb', line 171

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

#to_datetimeObject

Convert into a standard Ruby DateTime object Returns: ::DateTime object



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

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

#to_sObject

Prints a human-readable version of the date, using CarbonDate::Date.formatter



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

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