Class: CiteProc::Date
- Includes:
- Attributes
- Defined in:
- lib/citeproc/date.rb
Overview
Represents a Variable wrapping a date value. A date value is a hybrid object in that it can represent either an atomic date or a date range, depending on whether or not the ‘date-parts’ attribute contains one or two lists of date parts.
Dates can be constructed from a wide range of input values, including Ruby date objects, integers, date ranges, ISO 8601 and CiteProc JSON strings or hashes, and - provided you have the respective gems installed - EDTF strings all strings supported by Chronic.
Date instances are typically manipulated by a cite processor. Therefore, the API is optimized for easy information extraction and formatting. Additionally, Dates can be serialized as CiteProc JSON data.
Defined Under Namespace
Classes: DateParts
Class Attribute Summary collapse
-
.parsers ⇒ Array
readonly
A list of available date parsers.
Instance Attribute Summary collapse
-
#day ⇒ Fixnum
The day (of the start date for ranges).
-
#month ⇒ Fixnum
The month (of the start date for ranges).
-
#year ⇒ Fixnum
The year (of the start date for ranges).
Attributes inherited from Variable
Class Method Summary collapse
-
.parse(date_string) ⇒ CiteProc::Date?
Parses the passed-in string with all available date parsers.
-
.parse!(date_string) ⇒ CiteProc::Date
Like #parse but raises a ParseError if the input failed to be parsed.
-
.today ⇒ CiteProc::Date
(also: now)
A date object for the current day.
Instance Method Summary collapse
-
#-@ ⇒ Date
A copy of the date with an inverted year.
- #<=>(other) ⇒ Object
-
#ad? ⇒ Boolean?
A date is said to be AD when it is in the first millennium, i.e., between 1 and 1000 AD.
-
#bc? ⇒ Boolean?
A date is said to be BC when the year is defined and less than zero.
-
#certain! ⇒ self
Marks the date as a certain date.
- #certain? ⇒ Boolean
-
#closed_range? ⇒ Boolean
(also: #closed?)
Whether or not this date is a closed range.
-
#date? ⇒ true
Dates are dates.
- #date_parts ⇒ Array<DateParts> (also: #parts)
-
#empty? ⇒ Boolean
Whether or not the date parts’ are empty and the date is neither literal nor a season.
-
#end_date ⇒ ::Date?
The range’s end date; or nil.
- #end_date=(date) ⇒ Object
-
#has_end_date? ⇒ Boolean
(also: #range?, #plural?)
Whether or not the date-parts contain an end date.
-
#initialize(value = {}) {|_self| ... } ⇒ Date
constructor
A new instance of Date.
- #initialize_copy(other) ⇒ Object
- #marshal_dump ⇒ Object
- #marshal_load(value) ⇒ Object
- #merge(other) ⇒ Object
-
#numeric? ⇒ Boolean
False.
-
#open_range? ⇒ Boolean
(also: #open?)
Whether or not this date is an open range.
-
#replace(value) ⇒ Object
Replaces the date’s value.
-
#start_date ⇒ ::Date?
The date (start date if this instance is a range); or nil.
- #start_date=(date) ⇒ Object
-
#to_citeproc ⇒ Hash
A hash representation of the date.
-
#to_ruby ⇒ Date, Range
The date as a Ruby date object or as a Range if this instance is closed range.
-
#to_s ⇒ String
The date as a string.
-
#uncertain! ⇒ self
Marks the date as uncertain.
Methods included from Attributes
#attribute?, #eql?, #hash, #read_attribute, #reverse_merge, #to_hash, #to_json, #write_attribute
Methods inherited from Variable
create, create!, #inspect, #romanize, #strip_markup, #strip_markup!, #to_f, #to_i, #to_json, #tokenize, #type
Constructor Details
#initialize(value = {}) {|_self| ... } ⇒ Date
Returns a new instance of Date.
286 287 288 289 |
# File 'lib/citeproc/date.rb', line 286 def initialize(value = {}) super yield self if block_given? end |
Class Attribute Details
.parsers ⇒ Array (readonly)
A list of available date parsers. Each parser must respond to a #parse method that converts a date string into a Ruby date object. By default, the list will include Ruby’s date parser from the standard library, as well as the parsers of the Chronic and EDTF gems if they are available; to install the latter on your system make sure to ‘gem install chronic edtf`.
237 238 239 |
# File 'lib/citeproc/date.rb', line 237 def parsers @parsers end |
Instance Attribute Details
#day ⇒ Fixnum
Returns the day (of the start date for ranges).
380 381 382 383 384 385 386 387 388 389 390 391 |
# File 'lib/citeproc/date.rb', line 380 [:year, :month, :day].each do |reader| writer = "#{reader}=" define_method(reader) do d = parts[0] and d.send(reader) end define_method(writer) do |v| parts[0] ||= DateParts.new parts[0].send(writer, v.to_i) end end |
#month ⇒ Fixnum
Returns the month (of the start date for ranges).
|
# File 'lib/citeproc/date.rb', line 375
|
#year ⇒ Fixnum
Returns the year (of the start date for ranges).
|
# File 'lib/citeproc/date.rb', line 372
|
Class Method Details
.parse(date_string) ⇒ CiteProc::Date?
Parses the passed-in string with all available date parsers. Creates a new CiteProc Date from the first valid date returned by a parser; returns nil if no parser was able to parse the string successfully.
For an equivalent method that raises an error on invalid input
248 249 250 251 252 |
# File 'lib/citeproc/date.rb', line 248 def parse(date_string) parse!(date_string) rescue ParseError nil end |
.parse!(date_string) ⇒ CiteProc::Date
Like #parse but raises a ParseError if the input failed to be parsed.
260 261 262 263 264 265 266 267 268 |
# File 'lib/citeproc/date.rb', line 260 def parse!(date_string) @parsers.each do |p| date = p.parse(date_string) rescue nil return new(date) unless date.nil? end # Subtle: if we get here it means all parsers failed to create a date raise ParseError, "failed to parse #{date_string.inspect}" end |
.today ⇒ CiteProc::Date Also known as: now
Returns a date object for the current day.
271 272 273 |
# File 'lib/citeproc/date.rb', line 271 def today new(::Date.today) end |
Instance Method Details
#-@ ⇒ Date
Returns a copy of the date with an inverted year.
394 395 396 397 398 |
# File 'lib/citeproc/date.rb', line 394 def -@ d = dup d.year = -1 * year d end |
#<=>(other) ⇒ Object
516 517 518 519 520 521 522 523 524 525 526 |
# File 'lib/citeproc/date.rb', line 516 def <=>(other) case other when CiteProc::Date return nil if season? || other.season? parts <=> other.parts when ::Date parts <=> [other] else nil end end |
#ad? ⇒ Boolean?
A date is said to be AD when it is in the first millennium, i.e., between 1 and 1000 AD
486 487 488 |
# File 'lib/citeproc/date.rb', line 486 def ad? date = parts[0] and date.ad? end |
#bc? ⇒ Boolean?
A date is said to be BC when the year is defined and less than zero.
478 479 480 |
# File 'lib/citeproc/date.rb', line 478 def bc? date = parts[0] and date.bc? end |
#certain! ⇒ self
Marks the date as a certain date
461 462 463 464 |
# File 'lib/citeproc/date.rb', line 461 def certain! value[:circa] = false self end |
#certain? ⇒ Boolean
466 467 468 |
# File 'lib/citeproc/date.rb', line 466 def certain? !uncertain? end |
#closed_range? ⇒ Boolean Also known as: closed?
Returns whether or not this date is a closed range.
444 445 446 |
# File 'lib/citeproc/date.rb', line 444 def closed_range? range? && !open_range? end |
#date? ⇒ true
Returns dates are dates.
368 369 370 |
# File 'lib/citeproc/date.rb', line 368 def date? true end |
#date_parts ⇒ Array<DateParts> Also known as: parts
354 355 356 |
# File 'lib/citeproc/date.rb', line 354 def date_parts value[:'date-parts'] ||= [] end |
#empty? ⇒ Boolean
Returns whether or not the date parts’ are empty and the date is neither literal nor a season.
363 364 365 |
# File 'lib/citeproc/date.rb', line 363 def empty? parts.all?(&:empty?) && !literal? && !season? end |
#end_date ⇒ ::Date?
Returns the range’s end date; or nil.
424 425 426 |
# File 'lib/citeproc/date.rb', line 424 def end_date d = parts[1] and d.to_date end |
#end_date=(date) ⇒ Object
409 410 411 |
# File 'lib/citeproc/date.rb', line 409 def end_date=(date) parts[1] = DateParts.new(date.nil? ? 0 : date.strftime('%Y-%m-%d').split(/-/)) end |
#has_end_date? ⇒ Boolean Also known as: range?, plural?
Returns whether or not the date-parts contain an end date.
429 430 431 |
# File 'lib/citeproc/date.rb', line 429 def has_end_date? parts[1] && !parts[1].empty? end |
#initialize_copy(other) ⇒ Object
291 292 293 |
# File 'lib/citeproc/date.rb', line 291 def initialize_copy(other) @value = other.value.deep_copy end |
#marshal_dump ⇒ Object
295 296 297 |
# File 'lib/citeproc/date.rb', line 295 def marshal_dump to_citeproc end |
#marshal_load(value) ⇒ Object
299 300 301 |
# File 'lib/citeproc/date.rb', line 299 def marshal_load(value) replace(value) end |
#merge(other) ⇒ Object
303 304 305 306 |
# File 'lib/citeproc/date.rb', line 303 def merge(other) super convert_parts! end |
#numeric? ⇒ Boolean
Returns false.
471 472 473 |
# File 'lib/citeproc/date.rb', line 471 def numeric? false end |
#open_range? ⇒ Boolean Also known as: open?
Returns whether or not this date is an open range.
437 438 439 |
# File 'lib/citeproc/date.rb', line 437 def open_range? range? && parts[1].open? end |
#replace(value) ⇒ Object
Replaces the date’s value. Typically called by the constructor, this method intelligently converts various input values.
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'lib/citeproc/date.rb', line 310 def replace(value) case when value.is_a?(CiteProc::Date) initialize_copy(value) when value.is_a?(::Date) && Object.const_defined?(:EDTF) @value = { :'date-parts' => [DateParts.new(*value.values)] } uncertain! if value.uncertain? when value.respond_to?(:strftime) @value = { :'date-parts' => [DateParts.new(*value.strftime('%Y-%m-%d').split(/-/))] } when value.is_a?(Numeric) @value = { :'date-parts' => [DateParts.new(value)] } when value.is_a?(Hash) attributes = value.symbolize_keys if attributes.has_key?(:raw) @value = Date.parse(attributes.delete(:raw)).value @value.merge!(attributes) else @value = attributes.deep_copy end convert_parts! when value.is_a?(Array) @value = { :'date-parts' => value[0].is_a?(Array) ? value : [value] } convert_parts! when !value.is_a?(String) && value.respond_to?(:min) && value.respond_to?(:max) @value = { :'date-parts' => [ DateParts.new(value.min), DateParts.new(value.max) ]} when value.is_a?(String) && /^\s*\{/ =~ value return replace(::JSON.parse(value, :symbolize_names => true)) when value.respond_to?(:to_s) @value = Date.parse!(value.to_s).value else raise TypeError, "failed to create date from #{value.inspect}" end self end |
#start_date ⇒ ::Date?
Returns the date (start date if this instance is a range); or nil.
401 402 403 |
# File 'lib/citeproc/date.rb', line 401 def start_date d = parts[0] and d.to_date end |
#start_date=(date) ⇒ Object
405 406 407 |
# File 'lib/citeproc/date.rb', line 405 def start_date=(date) parts[0] = DateParts.new(date.strftime('%Y-%m-%d').split(/-/)) end |
#to_citeproc ⇒ Hash
Returns a hash representation of the date.
491 492 493 494 495 496 497 498 499 500 501 502 |
# File 'lib/citeproc/date.rb', line 491 def to_citeproc cp = value.stringify_keys # Convert (or suppress empty) date-parts if parts.all?(&:empty?) cp.delete('date-parts') else cp['date-parts'] = cp['date-parts'].map(&:to_citeproc) end cp end |
#to_ruby ⇒ Date, Range
Returns the date as a Ruby date object or as a Range if this instance is closed range.
415 416 417 418 419 420 421 |
# File 'lib/citeproc/date.rb', line 415 def to_ruby if closed_range? start_date..end_date else start_date end end |
#to_s ⇒ String
Returns the date as a string.
505 506 507 508 509 510 511 512 513 514 |
# File 'lib/citeproc/date.rb', line 505 def to_s case when literal? literal when season? season else parts.map(&:to_citeproc).inspect end end |
#uncertain! ⇒ self
Marks the date as uncertain
454 455 456 457 |
# File 'lib/citeproc/date.rb', line 454 def uncertain! value[:circa] = true self end |