解析和验证瑞典个人身份号码,瑞典语称为“personnummer”,本库中简称为 PNR。
瑞典税务局(瑞典语为“Skatteverket”)提供了一份格式描述,但基本上可以归结为以下几点:
PNR 包含 10 位数字和一个分隔符,格式为 yyMMdd-nnnc
,其中 yyMMdd
表示出生日期,nnn
是一个序列号,称为“出生号码”,c
是前九位数字的校验和。
PNR 的出生日期缺少世纪!因此,实际出生日期必须相对于参考日期推断。 在所有正常使用中,该参考日期都是今天。就是现在。
临时 PNR,称为协调号码(瑞典语为“sammordningsnummer”),可以颁发给未在瑞典人口登记册中列出的人。 已登记的人员在瑞典语中被称为“folkbokförd”;未登记的人员则…没有 “folkbokförd”…嗯,我们继续。 这些号码遵循与普通 PNR 相同的规则,但在日期数字(上面格式中的 dd
)上加 60。
当一个人达到 100 岁高龄时,PNR 中会使用加号 (+
) 作为分隔符,即 yyMMdd+nnnc
。
出生号码的最后一位数字(即倒数第二位数字,你知道,校验和前面的那位)揭示了该人的性别。 偶数和奇数分别表示女性和男性。
虽然 PNR 的标准形式是迄今为止描述的十一位字符版本,但其他形式也很常用。 该库处理以下形式的 PNR。 请注意,最后两种形式包含世纪,因此无需推断,也不允许使用加号分隔符; 毫不奇怪,这些形式在当今的许多应用程序和网站中都很受欢迎,即使不是必需的。
yyMMddnnnc
(标准形式,但缺少分隔符)yyMMdd-nnnc
(“标准”形式)yyMMdd+nnnc
(百岁老人)yyyyMMddnnnc
yyyyMMdd-nnnc
其他奇闻异事
由于给定日期只有 999 个不同的出生号码可用1,Skatteverket 可能会用完号码! 如果是这种情况,身份号码显然将从相邻日期中选择。 因此,有些人 PNR 的出生日期不是他们的实际出生日期。
由于世纪不是 PNR 的一部分,因此它也不包含在校验和计算中。 仅相差一个世纪(或其倍数)的较长形式的两个 PNR 具有相同的校验和。 不要跳过年龄检查!
说到年龄,短格式 PNR 不能用于非常、非常老的人。 对不起,两百岁人。
要使用此库,请在你的 Package.swift 中声明依赖项
// 🇸🇪 Swedish personal identity number validation
.package(url: "https://github.com/Oops-AB/swedish-pnr.git", from: "1.0.0"),
并添加到你的目标
.executableTarget(name: "Smorgasbord", dependencies: [
.product(name: "SwedishPNR", package: "swedish-pnr")
],
让我们开始吧
let pnr = try! SwedishPNR.parse(input: " 20171210-0005\t")
print("\(pnr.normalized)")
输出
20171210-0005
parse()
函数要么返回 PNR,要么抛出 Parser.ParseError
。
成功的解析返回一个 SwedishPNR
。 此类型有一些属性
input
是原始字符串,包括前导或尾随空格,normalized
是 PNR 的完整 13 个字符的版本,birthDateComponents
是一个 DateComponents
实例,包含 year
、month
和 day
,birthDate
是一个 Date
实例,表示出生日期的第一时间 *在瑞典时区*。SwedishPNR
还有一个方法 age(at:) -> Int
,用于计算相对于参考日期的年龄(默认为现在)。
请注意,所有日期计算(年龄和推断世纪)都在瑞典时区执行。
可能只有更少的出生号码可用,因为某些号码可能被保留或排除。 我没有找到明确的列表。 Skatteverket 可能知道。 ↩