Reputation: 33
I have ISO 8601 compliant date strings like "2016" or "2016-09" representing year or months. How can I get start end dates from this.
for example:
2016 -> ["2016-01-01", "2016-12-31"]
2016-09 -> ["2016-09-01", "2016-09-30"]
Thank you
Upvotes: 3
Views: 78
Reputation: 4440
One more solution in according to @AndreyDeineko :)
require 'date'
def create_date date
date = date.split('-').map(&:to_i)
[Date.new(*date, 1, 1), Date.new(*date, -1, -1)].map(&:to_s)
end
Upvotes: 2
Reputation: 27813
Try this
require 'date'
def iso8601_range(str)
parts = str.scan(/\d+/).map(&:to_i)
date = Date.new(*parts)
case parts.size
when 1
date .. date.next_year - 1
when 2
date .. date.next_month - 1
else
date .. date
end
end
iso8601_range('2016') # => 2016-01-01..2016-12-31
iso8601_range('2016-09') # => 2016-09-01..2016-09-30
iso8601_range('2016-09-20') # => 2016-09-20..2016-09-20
If you are cool with using send
you can replace the case
statement with
date .. date.send([:next_year,:next_month,:next_day][parts.size - 1]) - 1
Upvotes: 4
Reputation: 52367
require 'date'
def create_start_end(string)
year, month = string.split('-').map(&:to_i)
if month && !month.zero?
[Date.new(year, month, 1).to_s, Date.new(year, month, -1).to_s]
else
[Date.new(year, 1, 1).to_s, Date.new(year, 12, -1).to_s]
end
end
create_start_end('2016')
#=> ["2016-01-01", "2016-12-31"]
create_start_end('2016-01')
#=> ["2016-01-01", "2016-01-31"]
create_start_end('2016-09')
#=> ["2016-09-01", "2016-09-30"]
Upvotes: 2