Class: Henkilotunnus::Hetu
- Inherits:
-
Object
- Object
- Henkilotunnus::Hetu
- Defined in:
- lib/henkilotunnus/hetu.rb
Constant Summary collapse
- GENDERS =
['female', 'male']
- CENTURIES =
{ '+' => 1800, '-YXWVU' => 1900, 'ABCDEF' => 2000 }
- NEW_CENTURY_SIGNS =
'YXWVUBCDEF'
- PERSON_NUMBER_RANGE =
0..999
- CHECKSUM_CHARS =
'0123456789ABCDEFHJKLMNPRSTUVWXY'
Instance Attribute Summary collapse
-
#pin ⇒ Object
readonly
Returns the value of attribute pin.
Class Method Summary collapse
- .compute_checksum(raw_dob, person_number) ⇒ Object
- .generate(opts = {}) ⇒ Object
- .valid?(pin) ⇒ Boolean
Instance Method Summary collapse
- #age ⇒ Object
- #century ⇒ Object
- #century_sign ⇒ Object
- #checksum ⇒ Object
- #date_of_birth ⇒ Object
- #female? ⇒ Boolean
- #gender ⇒ Object
- #gender_neutral? ⇒ Boolean
-
#initialize(pin) ⇒ Hetu
constructor
A new instance of Hetu.
- #male? ⇒ Boolean
- #person_number ⇒ Object
- #to_s ⇒ Object
- #valid? ⇒ Boolean
Constructor Details
#initialize(pin) ⇒ Hetu
Returns a new instance of Hetu.
30 31 32 |
# File 'lib/henkilotunnus/hetu.rb', line 30 def initialize(pin) @pin = format(pin || '') end |
Instance Attribute Details
#pin ⇒ Object (readonly)
Returns the value of attribute pin.
28 29 30 |
# File 'lib/henkilotunnus/hetu.rb', line 28 def pin @pin end |
Class Method Details
.compute_checksum(raw_dob, person_number) ⇒ Object
24 25 26 |
# File 'lib/henkilotunnus/hetu.rb', line 24 def self.compute_checksum(raw_dob, person_number) CHECKSUM_CHARS[ (raw_dob + person_number).to_i % 31 ] end |
.generate(opts = {}) ⇒ Object
13 14 15 16 17 18 19 20 21 22 |
# File 'lib/henkilotunnus/hetu.rb', line 13 def self.generate(opts={}) dob = opts.fetch(:date, Time.at(rand(Date.new(1800, 1, 1).to_time.to_i...Date.today.to_time.to_i)).to_date) raw_dob = dob.strftime("%d%m%y") person_number = opts.fetch(:person_number, rand(PERSON_NUMBER_RANGE)).to_s.rjust(3, "0") century_str = CENTURIES.key(dob.year - (dob.year % 100)) sign_str_len = century_str.size - 1 century_sign = century_str[rand(0..sign_str_len)] new(raw_dob + century_sign + person_number + compute_checksum(raw_dob, person_number)) end |
.valid?(pin) ⇒ Boolean
9 10 11 |
# File 'lib/henkilotunnus/hetu.rb', line 9 def self.valid?(pin) new(pin).valid? end |
Instance Method Details
#age ⇒ Object
66 67 68 69 70 71 |
# File 'lib/henkilotunnus/hetu.rb', line 66 def age dob = date_of_birth # TODO: Should use EEST timezone for everything as Finland has only a single timezone (but with DST!). now = Time.now.utc.to_date now.year - dob.year - ((now.month > dob.month || (now.month == dob.month && now.day >= dob.day)) ? 0 : 1) end |
#century ⇒ Object
81 82 83 84 85 86 87 |
# File 'lib/henkilotunnus/hetu.rb', line 81 def century CENTURIES.keys.each do |string| if string.include? century_sign return CENTURIES[string] end end end |
#century_sign ⇒ Object
38 39 40 |
# File 'lib/henkilotunnus/hetu.rb', line 38 def century_sign pin[6] end |
#checksum ⇒ Object
89 90 91 |
# File 'lib/henkilotunnus/hetu.rb', line 89 def checksum pin[10] end |
#date_of_birth ⇒ Object
73 74 75 76 77 78 79 |
# File 'lib/henkilotunnus/hetu.rb', line 73 def date_of_birth dob = raw_dob day = dob[0..1].to_i month = dob[2..3].to_i year = century + dob[4..5].to_i Date.new(year, month, day) end |
#female? ⇒ Boolean
62 63 64 |
# File 'lib/henkilotunnus/hetu.rb', line 62 def female? gender == 'female' end |
#gender ⇒ Object
46 47 48 49 50 51 52 |
# File 'lib/henkilotunnus/hetu.rb', line 46 def gender if gender_neutral? raise 'gender methods cannot be used with gender neutral identity codes. Use gender_neutral? to check.' else GENDERS[person_number.to_i % 2] end end |
#gender_neutral? ⇒ Boolean
54 55 56 |
# File 'lib/henkilotunnus/hetu.rb', line 54 def gender_neutral? (NEW_CENTURY_SIGNS.include? century_sign) && (Time.now.year > 2026) end |
#male? ⇒ Boolean
58 59 60 |
# File 'lib/henkilotunnus/hetu.rb', line 58 def male? gender == 'male' end |
#person_number ⇒ Object
42 43 44 |
# File 'lib/henkilotunnus/hetu.rb', line 42 def person_number pin[7..9] end |
#to_s ⇒ Object
93 94 95 |
# File 'lib/henkilotunnus/hetu.rb', line 93 def to_s pin end |
#valid? ⇒ Boolean
34 35 36 |
# File 'lib/henkilotunnus/hetu.rb', line 34 def valid? valid_format? && valid_checksum? && valid_person_number? end |