it
February 10, 2023
Задача: Текст в дату
Написать функцию, переводящую строку вида
'1991 years 1 month 8 days' в дату.
1) в единственном/множественном числе.
3) не все компоненты обязательны, например '1975 year 14 days'
4) порядок компонентов может меняться, например '10 day 4 month 2000 year'
require 'byebug'
require 'date'
require 'rspec/autorun'
def text_to_date(text)
return Date.new(0,1,1) unless text.is_a? String
setup = {
# 0 год существует
year: {regex: /\s*(\s*(?'year'\d+)\s+(?i)(years?))\s*/, default: 0},
# 0 месяц не существует
month: {regex: /\s*(?'month'\b([1-9]|1[0-2])\b)\s+(?i)(months?)\s*/, default: 1},
# 0 день не существует
day: {regex: /\s*(?'day'\b[1-9]|[12][0-9]|3[01]\b)\s+(?i)days?\s*/, default: 1}
}
date_parts = {}
find_date_parts = lambda { |group_name, regex, default| (regex.match(text)&.[](group_name) || default).to_i }
setup.each { |key, value| date_parts[key] = find_date_parts.call(key, value[:regex], value[:default]) }
return Date.new(date_parts[:year], date_parts[:month], date_parts[:day])
end
puts text_to_date('2020 years 1 month 4 days')
describe 'text_to_date' do
it 'normal' do
expect(text_to_date('2020 years 1 month 4 days')).to eq(Date.new(2020,1,4))
end
it 'case sensitive' do
expect(text_to_date('2025 YeArS 1 MoNthS 15 DaYs')).to eq(Date.new(2025,1,15))
end
it 'only year' do
expect(text_to_date('5 years')).to eq(Date.new(5,1,1))
end
it 'only month' do
expect(text_to_date('5 month')).to eq(Date.new(0,5,1))
end
it 'only day' do
expect(text_to_date('7 days')).to eq(Date.new(0,1,7))
end
it 'year and days' do
expect(text_to_date('50 years 7 days')).to eq(Date.new(50,1,7))
end
it 'year and month' do
expect(text_to_date('50 years 7 months')).to eq(Date.new(50,7,1))
end
it 'month and day' do
expect(text_to_date('7 months 7 days')).to eq(Date.new(0,7,7))
end
it 'mix dates' do
expect(text_to_date('7 months 7 years 5 days')).to eq(Date.new(7,7,5))
expect(text_to_date('7 days 7 years 5 month')).to eq(Date.new(7,5,7))
end
it 'plural year' do
expect(text_to_date('7 year')).to eq(Date.new(7,1,1))
expect(text_to_date('7 years')).to eq(Date.new(7,1,1))
end
it 'plural month' do
expect(text_to_date('7 month')).to eq(Date.new(0,7,1))
expect(text_to_date('7 months')).to eq(Date.new(0,7,1))
end
it 'plural day' do
expect(text_to_date('7 day')).to eq(Date.new(0,1,7))
expect(text_to_date('7 days')).to eq(Date.new(0,1,7))
end
it 'more whitespaces' do
expect(text_to_date(' 2020 years 1 month 4 days ')).to eq(Date.new(2020,1,4))
expect(text_to_date(' 2020 years ')).to eq(Date.new(2020,1,1))
expect(text_to_date(' 5 month ')).to eq(Date.new(0,5,1))
expect(text_to_date(' 1 day ')).to eq(Date.new(0,1,1))
end
it '1-31 days' do
(1..31).each do |day|
expect(text_to_date("2020 years 1 month #{day} days")).to eq(Date.new(2020,1,day))
end
end
it '1-12 month' do
(1..12).each do |month|
expect(text_to_date("2020 years #{month} months 2 days")).to eq(Date.new(2020,month,2))
end
end
it '0-2023 years' do
(0..2050).each do |year|
expect(text_to_date("#{year} years 2 months 2 days")).to eq(Date.new(year,2,2))
end
end
it '32 days not exist' do
expect(text_to_date('2020 years 1 month 32 days')).to eq(Date.new(2020,1,1))
end
it '13 month not exist' do
expect(text_to_date('2020 years 13 month 4 days')).to eq(Date.new(2020,1,4))
end
it 'nothing found' do
expect(text_to_date('nothing')).to eq(Date.new(0,1,1))
expect(text_to_date(nil)).to eq(Date.new(0,1,1))
end
end
February 10, 2023, 09:09
0 views
4 reactions
2 replies
0 reposts