Class: SwedishPIN::Personnummer
- Inherits:
-
Object
- Object
- SwedishPIN::Personnummer
- Includes:
- Comparable
- Defined in:
- lib/swedish_pin/personnummer.rb
Overview
Represents a parsed and valid Personnummer or Samordningsnummer for a particular individual.
Determine if this is a Personnummer or a Samordningsnummer using #coordination_number?.
Instance Attribute Summary collapse
-
#control_digit ⇒ Integer
readonly
The last digit of the personnummer.
-
#day ⇒ Integer
readonly
The day of the month of the personnummer.
-
#month ⇒ Integer
readonly
The month digit of the personnummer.
-
#sequence_number ⇒ Integer
readonly
The number after the separator.
-
#year ⇒ Integer
readonly
The full year of the personnummer.
Instance Method Summary collapse
- #<=>(other) ⇒ Object
- #==(other) ⇒ Object (also: #eql?)
-
#age(now = Time.now) ⇒ Integer
Returns the age of the person this personnummer represents, as an integer of years since birth.
-
#birthday ⇒ Date
Return the birthday for the person that is represented by this Personnummer.
-
#coordination_number? ⇒ Boolean
Returns
true
if this number is a Samordningsnummer (coordination number). -
#female? ⇒ true, false
Returns
true
if the personnummer represents a person that is legally identified asfemale
. -
#format_long ⇒ Object
Formats the personnummer in the unofficial “12-digit” format that includes the century and doesn’t change separator depending on when the number is supposed to be shown.
-
#format_short(now = Time.now) ⇒ String
Formats the PIN in the official “10-digit” format.
- #hash ⇒ Object
-
#initialize(year:, month:, day:, sequence_number:, control_digit:) ⇒ Personnummer
constructor
private
Initializes a new instance from specific values.
-
#male? ⇒ true, false
Returns
true
if the personnummer represents a person that is legally identified asmale
. -
#to_s(length = 10, now = Time.now) ⇒ String
Formats the PIN into a
String
.
Constructor Details
#initialize(year:, month:, day:, sequence_number:, control_digit:) ⇒ Personnummer
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Initializes a new instance from specific values. Please consider using SwedishPIN.generate instead of you want custom instances.
43 44 45 46 47 48 49 50 |
# File 'lib/swedish_pin/personnummer.rb', line 43 def initialize(year:, month:, day:, sequence_number:, control_digit:) @year = year @month = month @coordination_number = day > 60 @day = (day > 60 ? day - 60 : day) @sequence_number = sequence_number @control_digit = control_digit end |
Instance Attribute Details
#control_digit ⇒ Integer (readonly)
The last digit of the personnummer. It acts as a checksum of the previous numbers.
14 15 16 |
# File 'lib/swedish_pin/personnummer.rb', line 14 def control_digit @control_digit end |
#day ⇒ Integer (readonly)
The day of the month of the personnummer. This will be for the real day, even for coordination numbers.
14 15 16 |
# File 'lib/swedish_pin/personnummer.rb', line 14 def day @day end |
#month ⇒ Integer (readonly)
The month digit of the personnummer. 1 for January up until 12 for December.
14 15 16 |
# File 'lib/swedish_pin/personnummer.rb', line 14 def month @month end |
#sequence_number ⇒ Integer (readonly)
This attribute returns an Integer
, but this sequence needs to be zero-padded up to three characters if you intend to display it (i.e. 3
is “003”).
The number after the separator. A common reason to access this is to check the sex of the person. You might want to look at #male? and #female? instead.
14 15 16 |
# File 'lib/swedish_pin/personnummer.rb', line 14 def sequence_number @sequence_number end |
#year ⇒ Integer (readonly)
The full year of the personnummer. For example 1989
.
14 15 16 |
# File 'lib/swedish_pin/personnummer.rb', line 14 def year @year end |
Instance Method Details
#<=>(other) ⇒ Object
188 189 190 191 192 193 194 |
# File 'lib/swedish_pin/personnummer.rb', line 188 def <=>(other) if other.is_a?(self.class) format_long <=> other.format_long else super end end |
#==(other) ⇒ Object Also known as: eql?
180 181 182 183 184 185 186 |
# File 'lib/swedish_pin/personnummer.rb', line 180 def ==(other) if other.is_a?(self.class) format_long == other.format_long else super end end |
#age(now = Time.now) ⇒ Integer
Returns the age of the person this personnummer represents, as an integer of years since birth.
Swedish age could be defined as such: A person will be 0
years old when born, and 1
12 months after that, on the same day or the day after in the case of leap years. This is the same way most western countries count age.
If the #birthday is in the future, then 0
will be returned.
161 162 163 164 |
# File 'lib/swedish_pin/personnummer.rb', line 161 def age(now = Time.now) age = now.year - year - (birthday_passed_this_year?(now) ? 0 : 1) [0, age].max end |
#birthday ⇒ Date
Return the birthday for the person that is represented by this Personnummer.
56 57 58 |
# File 'lib/swedish_pin/personnummer.rb', line 56 def birthday Date.civil(year, month, day) end |
#coordination_number? ⇒ Boolean
The #day attribute will still return a valid date day, even for coordination numbers.
Returns true
if this number is a Samordningsnummer (coordination number). This is a number that is granted to non-Swedish citizens until the time that they become citizens.
Coordination numbers are identical to a PIN, except that the “day” component has 60
added to it (i.e. 28+60=88
).
69 70 71 |
# File 'lib/swedish_pin/personnummer.rb', line 69 def coordination_number? @coordination_number end |
#female? ⇒ true, false
Returns true
if the personnummer represents a person that is legally identified as female
.
176 177 178 |
# File 'lib/swedish_pin/personnummer.rb', line 176 def female? sequence_number.even? end |
#format_long ⇒ Object
Formats the personnummer in the unofficial “12-digit” format that includes the century and doesn’t change separator depending on when the number is supposed to be shown.
This format is being adopted in a lot of places in favor of the “10-digit” format (#format_short), but as of 2020 it remains an unofficial format.
Format: yyyymmdd-nnnn
114 115 116 117 118 119 120 121 |
# File 'lib/swedish_pin/personnummer.rb', line 114 def format_long [ format_date(true), "-", "%03d" % sequence_number, control_digit ].join("") end |
#format_short(now = Time.now) ⇒ String
Formats the PIN in the official “10-digit” format. This is the “real” Personnummer string.
Format: yymmdd-nnnn
or yymmdd+nnnn
The Personnummer specification says that starting from the year of a person’s 100th birthday, the separator in their personnummer will change from a -
into a +
.
That means that every time you display a personnummer you also must consider the time of this action. Something that was read on date A and outputted on date B might not use the same string representation.
For this reason, the real personnummer is usually not what you want to store, only what you want to display in some cases.
This library recommends that you use #format_long for storage.
94 95 96 97 98 99 100 101 |
# File 'lib/swedish_pin/personnummer.rb', line 94 def format_short(now = Time.now) [ format_date(false), short_separator(now), "%03d" % sequence_number, control_digit ].join("") end |
#hash ⇒ Object
196 197 198 |
# File 'lib/swedish_pin/personnummer.rb', line 196 def hash [self.class, format_long].hash end |
#male? ⇒ true, false
Returns true
if the personnummer represents a person that is legally identified as male
.
169 170 171 |
# File 'lib/swedish_pin/personnummer.rb', line 169 def male? sequence_number.odd? end |
#to_s(length = 10, now = Time.now) ⇒ String
The length isn’t how long the resulting string will be as the resulting string will also have a separator included. The formats are colloquially called “10-digit” and “12-digit”, which is why they are referred to as “length” here.
Formats the PIN into a String
.
You can provide the desired length to get different formats.
10
ornil
12
141 142 143 144 145 146 147 |
# File 'lib/swedish_pin/personnummer.rb', line 141 def to_s(length = 10, now = Time.now) case length when 10 then format_short(now) when 12 then format_long else raise ArgumentError, "The only supported lengths are 10 or 12." end end |