Home > OS >  How to check if date is valid (Ruby on Rails)
How to check if date is valid (Ruby on Rails)

Time:04-30

I have this before_save function:

def set_birth_date
    return unless pesel_changed?

    day = pesel[4..5]
    case pesel[2..3].to_i
    when 0..19
      month = pesel[2..3]
      year = pesel[0..1].prepend('19')
    when 20..39
      month = (pesel[2..3].to_i - 20).to_s
      year = pesel[0..1].prepend('20')
    when 40..59
      month = (pesel[2..3].to_i - 40).to_s
      year = pesel[0..1].prepend('21')
    when 60..79
      month = (pesel[2..3].to_i - 60).to_s
      year = pesel[0..1].prepend('22')
    end
      birth_date = Time.strptime("#{day}/#{month}/#{year}", '%d/%m/%Y')
    if birth_date.valid?
      self.birth_date = birth_date
    else
      errors.add(:pesel, I18n.t('activerecord.errors.models.profile.attributes.pesel.invalid'))
    end
  end

(Little explanation: Last if condition is not yet included in function. All I want to do is save birth_date if valid, but if it's not valid, I want to add error.) But sometimes it gives me error like this:

`strptime': invalid date or strptime format - `12/14/2022' `%d/%m/%Y' (ArgumentError)

How can I check if Time.strptime("#{day}/#{month}/#{year}", '%d/%m/%Y') is valid? "valid?" and "valid_date?" don't work. For months I can do something like this

if month / 12 > 0
  <Handling error>
else
  <update>
end

But for days... This won't be that easy. Any ideas?

EDIT: pesel is a string. This function extract birth date from pesel number. Pesel number is 11 digit number, for example:

50112014574
50 - year of birth
11 - month of birth
20 - day of birth
14574 - Control number
Those "magic numbers' defines which year someone was born
If someone was born in 19XX, then month number is 1-12.
If someone was born in 20XX, then month number is 21-32 (month number   20. Example pesel number: '50312014574', which means this person was born 20th November 2050
If someone was born 21XX, then month number is 41-52 (month nubmer   40) Example pesel number: '50512014574', which means this person was born 20th November 2150 etc.

I'm working on existing database and I can't just validate pesel number

CodePudding user response:

If you cannot validate the pesel numbers in the database first then I would just catch the error and handle it in an rescue block.

To do so change

birth_date = Time.strptime("#{day}/#{month}/#{year}", '%d/%m/%Y')

if birth_date.valid?
  self.birth_date = birth_date
else
  errors.add(:pesel, I18n.t('activerecord.errors.models.profile.attributes.pesel.invalid'))
end

to

begin
  birth_date = Time.strptime("#{day}/#{month}/#{year}", '%d/%m/%Y')
  self.birth_date = birth_date
rescue ArgumentError => e
  errors.add(:pesel, I18n.t('activerecord.errors.models.profile.attributes.pesel.invalid'))
end

CodePudding user response:

Once you have the year and month, you might want to check if the day is greater than

n_days =  Time.days_in_month(month, year) 
  • Related