HermannBjorgvin / Kennitala

Icelandic national ID (kennitölur) utilities for servers and clients.
MIT License
36 stars 10 forks source link

Aldurs útreikningur getur skeikað einum degi #14

Closed saevarom closed 3 years ago

saevarom commented 3 years ago

Lenti í því þegar ég var að athuga hvort einhver væri orðinn 18 ára að kóðinn sem skilar aldri getur gefið nýjan aldur degi fyrir afmælisdag. Dæmi:

var kennitala = require("kennitala")
var today = new Date()
var kt = kennitala.generatePerson(new Date(today.getFullYear()-18, today.getMonth(), today.getDate()+1))
var info = kennitala.info(kt)
info.age

console.log(today)
console.log(kt)
console.log(info)

Þessi aðili ætti að vera 17 ára, en kennitala skilar 18

Úr þessu kemur:

>>> Thu Feb 18 2021 10:31:35 GMT+0000 (Greenwich Mean Time)
>>> "1902037780"
>>> Object
age: 18
birthday: Wed Feb 19 2003 00:00:00 GMT+0000 (Greenwich Mean Time)
birthdayReadable: "Wed Feb 19 2003"
kt: "1902037780"
type: "person"
valid: true
HermannBjorgvin commented 3 years ago

Takk fyrir þetta.

Ég skal skrifa patch og gefa út bráðum

Ég sé ekki nákvæmlega hvað ætti að valda þessu en lítur út eins og mögulega er lína 89 í kennitala.js röng aðferð til að finna aldur

https://github.com/HermannBjorgvin/Kennitala/blob/master/kennitala.js#L89

saevarom commented 3 years ago

Já mér finnst líklegt að þarna sé verið að nota meðaltalslengd árs og það sé að rugla. Stutt leit á Google skilaði mér þessu svari sem ég prófaði stuttlega: https://stackoverflow.com/a/10008299/291505

Prófun gerð 24. febrúar. Einstaklingur sem á afmæli 25. febrúar 2003 (eða síðar) ætti að vera 17 ára (eða yngri), einstaklingur sem á afmæli 24. febrúar 2003 eða fyrr ætti að vera 18 ára.

Mögulega er þetta ekki besta lausnin en þetta skilar a.m.k. réttu svari fyrir þetta tilfelli.

function getAge(birthday) {
    var today = new Date();
    var thisYear = 0;
    if (today.getMonth() < birthday.getMonth()) {
        thisYear = 1;
    } else if ((today.getMonth() == birthday.getMonth()) && today.getDate() < birthday.getDate()) {
        thisYear = 1;
    }
    var age = today.getFullYear() - birthday.getFullYear() - thisYear;
    return age;
}

getAge(new Date(2003, 1, 23))
>>> 18
getAge(new Date(2003, 1, 24))
>>> 18
getAge(new Date(2003, 1, 25))
>>> 17
HermannBjorgvin commented 3 years ago

Takk fyrir þennan kóðabút ég var einmitt að hugsa það sama væri í gangi með stærðfræðina bakvið aldursútreikningana.

Tryggingarmiðstöðinn er með þennan kóðabút hjá sér í þeirra TypeScript pakka, held það sé vel í anda open source að herma bara eftir hjá þeim.

export function getAge(kt: string | number, referenceDate?: Date): number {
  referenceDate = referenceDate || new Date()
  const ktDate = getBirthdate(kt)
  const refYear = referenceDate.getFullYear()
  const calcDate = new Date(ktDate)
  calcDate.setFullYear(refYear)
  let age = refYear - ktDate.getFullYear()
  if (calcDate > referenceDate) {
    age--
  }
  if (age < 0) {
    // þjóðskrá some times registers kennitölur with temporary last digits... add 100 to correct negative age outcome
    return age + 100
  }
  return age < 1
    ? (referenceDate.getTime() - ktDate.getTime()) /
        1000 /
        60 /
        60 /
        24 /
        365.2422
    : age
}

Og mjög sniðugur optional parameter þarna, maður getur fengið aldur á ákveðnum degi í framtíðinni. Það væri vert að bæta því við til að einfalda t.d. skráningar í prófkjör þarsem aðili verður að hafa náð tilskyldum aldri á ákveðnum degi í framtíðinni

HermannBjorgvin commented 3 years ago

Kóðinn frá Tryggingarmiðstöðinni er réttur og virkar, þarf að gera hann snyrtilegan og breyta í ES5 og get svo gefið út patch