Publikované 26. 6. 2025

Štúdia: vylepšené rodné číslo (RČ2800)

Najprv si vyskúšajte demo - kliknite na kliknite na "Generovať rodné čísla", prípadne zadajte požadované parametre. Vygenerujú sa rodné čísla v súčasnom aj navrhovanom vylepšenom formáte s pracovným názvom "RČ2800":

Porovnanie vlastností oboch formátov

Súčasný formát Vylepšený formát
Príklad:
žena, 26.12.2000
muž, 31.12.1985
0062260022
8512316670
2006226AAV
1851231KRU
Maska 1) RRMMDDNNN[N] RRRMMDDAAA 2)
Dĺžka znakov 9-10 10
Validačný REGEX ^[\d]{9,10}$ ^[1-9][\d]{6}[A-Z]{3}$
Validácia modulo 11 áno áno 4)
Rozlíšenie pohlavia ženy
pripočítaním +50 v mesiaci
áno áno
Denná kapacita indexu
(pre jedno pohlavie)
999 do 1953
909 od 1954
1420
Ročná kapacita indexu
(pre obe pohlavia)
729270 do 1963
663570 od 1954
1036600
Max. počet rokov 100 999
Pokryté roky 1900 - 2045 3) 1900 - 2799

Poznámky:
1) R = rok, M = mesiac, D = deň, N = číslica 0-9, [N] = nepovinná číslica, A = písmeno A-Z
2) Relatívny rok RRR sa pripočíta ku základnému roku 1800. Na účel dema je pre konverziu indexu AAA použitá sada 25 písmen ABCDEFGHIJKLMNOPRSTUVWXYZ (vynechané Q), ktorá určuje jeho kapacitu. Kapacitu možno zvýšiť napr. pridaním ďalších znakov alebo predĺžením reťazca, príp. znížiť vylúčením obtiažne rozlíšiteľných znakov v niektorých fontoch (0-O-Q, l-1, U-V ..). Dĺžka znakovej sady vyjadruje základ číselnej sústavy. Napr. pri počte 8 písmen by číslo bolo vyjadrené v osmičkovej sústave, ktorej max. denná kapacita indexu je však len 511.
3) Nie je známe, kedy bolo pridelené prvé rodné číslo (asi koncom 40-tych rokov). Súčasný systém už síce presahuje kapacitu pokrytia 100 rokov (počítajúc od r. 1900) avšak predpokladá sa, že zatiaľ neexistuje človek, ktorý dosiahol vek viac ako 100 rokov od pridelenia prvého rodného čísla.
4) Pred overením cez modulo 11 sa indexová časť AAA prevedie do desiatkovej číselnej sústavy. Napríklad rodné číslo 2006226AAV bude najprv prevedené do desiatkovej sústavy na 20062260020 a následne overené cez modulo 11. Pre prevod pozrite v nižšie zobrazenom kóde metódy indexLetterToNumber() a indexNumberToLetter().

Trochu z histórie

Rodné čísla boli zavedené v bývalom Československu v polovici 50-rokov. Málokto v tom čase predpokladal, že ich praktická administratívna využiteľnosť presiahne hranicu tisícročia a že sa raz budú spracovávať v IT systémoch.

Prechodom cez tisícročie začali tradičné (súčasné) rodné čísla narážať na svoje obmedzenia - napr.

  • maximálny denný počet novorodencov (kapacita poradového čísla novorodenca) - do r. 1953 max. trojmiestne číslo (999), resp. od 01.01.1954 so zavedením kontroly modulo 11 max. štvormiestne číslo, resp. len 909 novorodencov denne (pre jedno pohlavie, tzn. 9999 / 11 = 909)
  • po prechode rokom 2000 ukladanie úvodných núl v IT systémoch a ich obtiažna (error prone) validácia z dôvodu, že úvodné nuly sú v mnohých v IT systémoch automaticky odstraňované napr. pri konverzii typu premennej na numerickú. Následne môže zlyhať niektoré validačné pravidlo - napr. kontrola dĺžky reťazca ..
  • maximálny počet rokov je 100 (prvé dve číslice)
  • snaha skrývať osobné údaje v dôsledku zavedenia GDPR od r. 2018

Čiastkovým pokusom o riešenie (kapacity denného poradového indexu) bolo napr. zavedenie prípočítania 70 ku mesiacu narodenia v Čechách od r. 2003.

Hrozí nám centralizované BIFO ?

Slovensko v súčasnosti (2025) naďalej používa pôvodný formát rodných čísel s kontrolou cez modulo 11. Ministerstvo vnútra SR však v r. 2019 avizovalo snahu prejsť na tzv. "BIFO" - tzn. bezvýznamový identifikátor fyzických osôb. Tento by mal pozostávať z 10 náhodne pridelených číslic bez súvislosti s dátumom narodenia (pravdepodobne dočasný "ošiaľ" z tesne predtým zavedeného GDPR v rámci EÚ).

Bola by škoda, či priam chyba, keby sa uvedený úmysel podarí zrealizovať - z dôvodu jeho nedomyslenosti. V prvom rade je veľmi užitočné pohľadom na rodné číslo zistiť dátum narodenia a pohlavie. V druhom rade je nutné aby rodné číslo malo zavedený nejaký samokontrolný mechanizmus validácie, ako napr. modulo 11. Modulo 11 zabezpečuje odstránenie 99% chýb už pri vkladaní rodného čísla do IT systému, vyhľadávaní apod.

Dôvodnenie, že rodné číslo odkrýva osobné údaje a porušuje GDPR je ťažko obhájiteľné, podobne ako skrývanie adries štatutárov, ktoré sa dajú dohľadať vo verejných databázach a dokumentoch :-) Okrem toho to nie je pravda - neumožňuje zistiť žiadne priame osobné údaje ako napr. meno alebo adresu - bez autorizovaného prístupu do nejakého IT systému.

Ďalším argumentom proti úmyslu zaviesť BIFO je nepraktickosť. Predstavte si, že namiesto zistenia dátumu narodenia priamo z rodného čísla bude musieť úradník aktivovať autorizovaný prístup ku nejakej centrálnej štátnej databáze, kde si vyhľadá osobu zodpovedajúcu zadanému "BIFO" identifikátoru. Koľko poisťovní, firiem a úradov potrebuje každú chvíľu overiť platnosť nejakého rodného čísla? Odhadom to môže byť denne stotisíce autorizovaných požiadaviek z tisícov IT systémov. Čo ak nastane výpadok služby, alebo databázu niekto hackne? Vyriešiť by sa museli tiež špecifické prípady - napr. hromadné validácie apod.

Treba tiež vidieť trend do budúcna, že časom bude potreba využitia služby, a teda náročnosť na záťaž a údržbu systémov a nákladovosť, len narastať. Ako príklad by som tiež uviedol, že aj Finančná správa SR si rýchlo uvedomila, že implementáciu eFormulárov musí realizovať na strane prehliadača a do centrálnej databázy odosielať už len validné dátové štruktúry. Zavedením BIFO by MV SR išlo presne opačným smerom.

Na základe skúseností som preto presvedčený, že podobný centralizovaný prístup by bol nesprávnym rozhodnutím.

Výhody nového formátu rodného čísla

  • pre rok sú určené 3 číslice namiesto 2 číslic v súčasnom formáte, čo umožňuje bezproblematický prechod medzi storočiami
  • rok sa počíta relatívne od vopred definovaného základného roku. Navrhnutý základný rok je 1800 z dôvodu, aby string nezačínal nulou. Z dôvodu spätnej kompatability sa predpokladá že prvé rodné číslo začne v roku 1900. Celkový rozsah pokrytých rokov je 1900 až 2799
  • jednoduchý rigidný formát RRRMMDDAAA - umožňuje dobrú validáciu cez REGEX napr. /^[\d]{7}[A-Z]{3}$/ ako aj validáciu cez modulo 11 podobne ako súčasný formát, tzn. odhalí ~99% chýb a preklepov, nevyžaduje žiadne pripojenia na externú centrálnu databázu
  • spätná kompatabilita - všetky rodné čísla v súčasnom (starom) formáte možno previesť na nový formát
  • väčšia a ľahko rozšíriteľná denná kapacita poradového indexu - takmer dvojnásobná v porovnaní so súčasným na jedno pohlavie pri počte 25 písmen. Možno ľahko navýšiť:

    • buď predĺžením poradového čísla z 3 písmen na 4-5 písmen (vyžadovalo by úpravu databáz v súčasných systémoch)
    • alebo rozšírením znakovej sady napr. pridaním číslic 1-9 (nárast dennej kapacity z 1420 na 3573), alebo podporou malých písmen (nie je odporúčané, ale už by asi postačilo aj Číne :-)


    V súčasnosti sa ročne narodí na Slovensku cca 50.000 detí (trend je dlhodobo klesajúci), čo znamená priemerne denne pridelených 130-140 poradových čísel. Nový formát RČ s dennou kapacitou cca 1420 pridelených čísel by pokryl narodenie približne 1.022.000 novorodencov ročne.

  • možnosť vypustiť obtiažne čitateľné alebo vizuálne kolízne znaky / písmená, napr. O-0 (nula versus veľké "0" - OTEC), l-1 (číslica jedna versus malé "L" - Lopta), prípadne Q (obtiažne čitateľné v niektorých fontoch, alebo kolízia so "O" - OTEC, resp. aj s nulou)
  • rovnaká dĺžka reťazca 10 znakov ako v súčasnom formáte - netreba meniť databázy v IT systémoch, možno použiť napr. VARCHAR(10)
  • ľahká implementácia v programovacích jazykoch a nenáročnosť prevodu indexu do desiatkovej číselnej sústavy - napr. javascript (vhodné pre elektronické eFormulare Finančnej správy SR - eDane) s ohľadom na výkonnosť - jednoduchý obojstranný (symetrický) prevod poradového indexu na písmená a späť
  • miernym vylepšením by mohlo byť aj prehodenie poradového indexu pred dátum, čiže RRRRMMDDAAA by sa zmenilo na AAARRRRMMDD - čo by umožnilo využiť aj ignorovaných 100 rokov medzi 1800 - 1900 pri povolení úvodných núl pre RRR.
  • zistenie dátumu narodenia a pohlavia - rovnaká informačná hodnota ako v súčasnom formáte. Napr. 3256231EAI sa dá prečítať ako žena narodená 31.12.2125 (1800+325). Nepovažoval by som to za únik kľúčových osobných údajov - nepoznáme meno ani adresu a samotné rodné číslo sa nedá ľahko zneužiť, alebo aspoň som o podobnom prípade zatiaľ nepočul. Konverzia indexu EAI do desiatkovej sústavy a následné overenie modulo 11 by bolo riešené programovo, podobne ako pri súčasných rodných číslach.

Nevýhody nového formátu rodného čísla

  • najväčšou nevýhodou je pevne definovaná sada znakov v konštante CHAR_MAP - na účel dema obsahuje hodnotu ABCDEFGHIJKLMNOPRSTUVWXYZ (bez Q - vylúčené z dôvodu obtiažnej odlíšiteľnosti v niektorých fontoch voči O/0 - Otec, nula). Akákoľvek zmena v danom reťazci by znamenala zmenu v kódovaní denného indexu a súčasne znehodnotenie existujúcich rodných čísel. Bolo by naivné predpokladať, že sa uvedený reťazec nezmení počas nasledujúcich storočí :-) Vhodným riešením by preto bolo zakomponovať do rodného čísla verziu napr. rozšírením masky RRRMMDDAAA (10 znakov) na RRRMMDDAAAV (11 znakov), kde posledné V by predstavovalo verziu 1-9. Prípadne predpokladať, že pokiaľ je dĺžka reťazca 10 znakov, jedná sa o prvú tzv. nultú verziu (predpoklady však nie sú osvedčeným prístupom). Pridanie verzie by znamenalo zvýšenie dĺžky reťazca z 10 na 11 znakov - a teda zmenu databáz v IT systémoch. Alternatívnym riešením by mohlo byť aj použitie štandardnej programovej funkcie napr. base_convert, avšak tento prístup by neumožňoval definíciu vlastnej sady a teda vylúčenie vizuálne kolíznych znakov.

  • pre niekoho môže byť ťažšie interpretovateľný 3-miestny rok narodenia RRR od základného roku, v ktorom napr. 185 znamená 1800 + 185 = 1985. Riešením by mohlo byť upustenie od relatívneho roku a vyjadrenie absolútneho roku v štandardnom 4-miestnom formáte. V prípade predĺženia masky rodného čísla na 12 znakov RRRRMMDDAAAV by sa vyriešil aj prvý problém s označením verzie formátu.

Záver

Cieľom tejto prípadovej štúdie bolo poukázať na možnosť nenáročného vylepšenia praktickej použiteľnosti súčasných rodných čísel v bežnej administratíve.

Nie je potrebné hneď zavádzať zložité centralizované administratívne systémy (BIFO) - prinajmenšom nie bez predchádzajúcej odbornej diskusie s vyhodnotením finančno - technickej náročnosti zmeny, ako aj legislatívnych dopadov na spoločnosť.

Navrhnutý model odstraňuje väčšinu existujúcich problémov, pričom má minimálny ekonomicko - technický dopad na spoločnosť pri zachovaní spätnej kompatability a väčšiny charakteristík súčasných rodných čísel.

Vhodnou úpravou parametrov možno prezentovaný model prispôsobiť konkrétnym potrebám a umožniť jeho využitie napr. aj v Českej republike, alebo špecifických informačných systémoch.


		
/**
* Štúdia: Vylepšený formát slovenských rodných čísel pre roky 1900 - 2799
*         a dennou kapacitou 2 x 1420 novorodencov
*         (na účel dema použitá sada 25 pismen, dĺžka indexu 3 písmená)
*
* https://synet.sk/blog/php/485-studia-vylepsene-rodne-cislo
* (c) 2024-2025 Lubos Dzurik - lubosdz@gmail.com
*/
class RodneCislo2800
{
	const
		// pohlavie
		GENDER_MALE = 'M',
		GENDER_FEMALE = 'F';

	// Character map for converting daily birth sequencial index 1, 2, .. to proper numeric base
	// Allowed are only capital letters for better legibility.
	// 26 pismen zredukovane na 25, kde A=0, B=1, C=2, ... Z=24 (max. capacity 15624)
	// - kvoli citatelnosti vypustene: Q (Q vs. O / OTEC vs. 0 / nula)
	// - tiez na zvazenie vypustit:
	//	 L - male pismeno l (lano) vs. 1 (cislica jedna)
	//	 U - vizualna kolizia U/V v niektorych fontoch
	// - rozsirenie .. moznost pridat cislice 1-9 do mapy (nulu nie kvoli kolizii s "O"-OTEC)
	//              .. zvysi kapacitu indexu z 15624 -> 39303 (pre kazde pohlavie), cize celkovo 39303 females a 39303 males
	//              .. tiez moznost pouzit 4- resp. 5- miestny index, namiesto 3-miestneho
	const CHAR_MAP = 'ABCDEFGHIJKLMNOPRSTUVWXYZ';
	//const MAP = 'ABCDEFGHIJKLMNOPRSTUVWXYZ987654321'; // na pokusovanie .. napr. pridanie 1-9: index max = 39303, indexPerGenderPerDay = 3537

	/** @var int Division remainder must be zero - check birth ID validity, moznost pouzit ine modulo pre lepsiu eliminaciu chyb, avsak poklese dennej kapacity */
	const MODULO = 11;

	const
		/** @var int The year base - from which we calculate following +999 years */
		BASE_YEAR = 1800,

		/** @var int Maximum allowed year */
		MAX_YEAR = 2799;

	/** @var string User inputs */
	protected $rc = null;

	/** @var bool runtime variable */
	protected $isValid = null;

	// basic auxiliary info about birth ID
	protected
		$month,
		$day,
		$year,
		$gender,
		$timestamp,
		$age,
		$indexNumeric,
		$indexLetter;

	/** @var string The reason why failed generating birth ID in old (current/legacy) format */
	protected $reasonFailOldFormat = '';

	/**
	* Constructor
	* @param string $rc Birth ID in new format e.g. 2010104AOA
	*/
	public function __construct($rc = null)
	{
		$this->rc = $rc;
		if ($rc) {
			$this->validate();
		}
	}

	/**
	* Return TRUE when birth ID is valid
	*/
	public function isValid()
	{
		if (null === $this->isValid) {
			$this->validate();
		}
		return $this->isValid;
	}

	/**
	* Return TRUE if birth ID in new format is valid
	*/
	protected function validate()
	{
		$this->rc = trim(strtoupper($this->rc));

		if (!preg_match('/^[1-9][0-9]{6}[A-Z]{3}$/', $this->rc)) {
			throw new \Exception('Neplatné rodné číslo - musí mať tvar RRRMMDDAAA.');
		}

		// convert to old format
		$this->year = self::BASE_YEAR + (int) substr($this->rc, 0, 3);
		$this->month = (int) substr($this->rc, 3, 2);
		$this->day = (int) substr($this->rc, 5, 2);
		$this->timestamp = null;
		$this->age = null;

		if ($this->month >= 51 && $this->month <= 62) {
			// zeny maju pripocitane 50 ku mesiacom 1-12
			$this->month -= 50;
			$this->gender = self::GENDER_FEMALE;
		} else {
			$this->gender = self::GENDER_MALE;
		}

		$this->isValid = checkdate($this->month, $this->day, $this->year);

		if ($this->isValid) {
			// index ie. CMT -> 1568
			$this->indexLetter = substr($this->rc, -3);
			$this->indexNumeric = self::indexLetterToNumber($this->indexLetter);
			$rcDecrypted = substr($this->rc, 0, 7).str_pad($this->indexNumeric, $this->year < 1954 ? 3 : 4, "0", STR_PAD_LEFT); // eg. 18159142551
			$check = $rcDecrypted / self::MODULO;
			$check2 = floor($rcDecrypted / self::MODULO);

			if ($check != $check2) {
				$this->isValid = false;
			} else {
				$this->timestamp = strtotime("{$this->year}-{$this->month}-{$this->day}");
				if ($this->timestamp < time()) {
					$this->age = date_diff(date_create("{$this->year}-{$this->month}-{$this->day}"), date_create('now'))->y;
				}
			}
		}

		return $this->isValid;
	}

	/**
	* Return maximum daily index capacity
	*/
	public static function getIndexMax()
	{
		$base = strlen(self::CHAR_MAP);
		//$max = ($base - 1) * $base**2 + ($base - 1) * $base**1 + ($base - 1) * $base ** 0;
		$max = ($base - 1) * $base**2 + ($base - 1) * $base + ($base - 1); // same as above, optimized
		return $max;
	}

	/**
	* Prevedie denny poradovy index z N-ciselnej sustavy do desiatkovej sustavy, napr. LLA => 7150
	* @param string $new napr. LLA
	* @return int Old format e.g. 7150
	*/
	public static function indexLetterToNumber($indexLetters)
	{
		$len = strlen($indexLetters);
		if ($len != 3) {
			// na ucel demo - pouzivame striktne 3-ciferny konvertovany index
			throw new \Exception("Nesprávna dĺžka indexu [{$len}] - musí byť presne 3 znaky.");
		}

		$out = 0;
		$base = strlen(self::CHAR_MAP); // 25 - the number of used letters, may be reduced to avoid vizual ambiguities

		for ($i = 0; $i < $len; ++$i) {
			$chr = substr($indexLetters, -($i + 1), 1); // od posledneho pismena ku prvemu
			$pos = strpos(self::CHAR_MAP, $chr); // pozicia v mape, case sensitive
			if (false === $pos) { // neexistuje?
				throw new \Exception("Neplatný formát indexu - písmeno [{$chr}] nie je povolené.");
			}
			$out += $base**$i*$pos; // e.g. (25*25*12)+(25*3)+(17) => pismena v poradi 12-3-17 = MDS
		}

		return $out;
	}

	/**
	* Prevedie denny poradovy index z desiatkovej sustavy do cielovej podla poctu znakov v character map, napr. 7150 -> LLA
	* See also javascript sample implementation:
	*   - https://stackoverflow.com/questions/1337419/how-do-you-convert-numbers-between-different-bases-in-javascript
	*
	* @param int Numericky tradicny poradovy index napr. 7150
	* @return string Cislo v novej ciselnej sustave podla ciselneho zakladu - dlzky aktualnej CHAR_MAP napr. LLA
	*/
	public static function indexNumberToLetter($indexNum)
	{
		if (!is_numeric($indexNum)) {
			throw new \Exception("Index ({$indexNum}) musí pozostávať z číslic 0-9.");
		}

		// preverime dlzku indexu - nepovinne, len specificky pre demo, prip. sa moze automaticky doplnit zlava padding nulami
		$len = strlen("{$indexNum}");
		if ($len < 3 || $len > 5) {
			// overenie pre ucel dema:
			//  3 = stary/sucasny 0-999 format do 31.12.1953 (bez modulo 11)
			//  4 = stary/sucasny 0-9999 format od 01.01.1954 (s modulo 11)
			//  5 = vylepseny format 0-99999 po konverzii do desiatkovej sustavy (s modulo 11), mozno upravit ..
			throw new \Exception("Nesprávna dĺžka indexu [{$indexNum}] - musí byť 3 až 5 znakov, nájdené {$len} znakov.");
		}

		$base = strlen(self::CHAR_MAP);
		$tmp = $base ** 2;
		$one = intval($indexNum / $tmp);
		$rem = $indexNum - ($tmp * $one);
		$two = intval($rem / $base);
		$three = $indexNum - ($tmp * $one) - ($base * $two);
		$out = self::CHAR_MAP[$one].self::CHAR_MAP[$two].self::CHAR_MAP[$three];

		return $out;
	}

	/**
	* Podporna funkcia - zakladne informacie o rodnom cisle, napr. vek, dennu kapacitu indexu ..
	*/
	public function getInfo()
	{
		$max = self::getIndexMax();
		$oldFormat = $this->convertNewToOld($this->rc);
		return [
			'rc' => $this->rc,
			'isValid' => $this->isValid,
			'gender' => $this->gender,
			'year' => $this->year,
			'month' => $this->month,
			'day' => $this->day,
			'age' => $this->age ?? '',
			'indexNumeric' => $this->indexNumeric,
			'indexLetter' => $this->indexLetter,
			'indexNumericMax' => $max, // max. kapacita indexu, should be 15624 for 25 letters
			'indexLetterMax' => $this->indexNumberToLetter($max), // should be ie. ZZZ
			'mapCharsCount' => strlen(self::CHAR_MAP), // urcuje kapacitu denneho indexu, zaklad cielovej ciselnej sustavy
			'indexPerGenderPerDay' => intval($max / 11), // denna kapacita poradoveho indexu
			'indexPerGenderPerYear' => intval($max / 11) * 365, // rocna kapacita poradoveho indexu
			'baseYear' => self::BASE_YEAR,
			'maxYear' => self::MAX_YEAR,
			'timestamp' => $this->timestamp,
			'oldFormatRC' => $oldFormat ?? '',
			'oldFormatFailReason' => $oldFormat ? '' : $this->reasonFailOldFormat,
		];
	}

	/**
	* Prevedie novy format RC na stary - POZOR - heuristicky prevod indexu na ucel DEMO, nakolko modulo v starom a novom formate budu vzdy odlisne
	* Set also the reason why conversion failed, ie. index in old format out of range
	* @param string $newRc e.g. 2120807OKS
	* @param bool $validate Check if the day exists
	* @return string e.g. 1208079017
	*/
	public function convertNewToOld($newRc, $validate = true)
	{
		$newRc = trim(strtoupper($newRc));
		// note: pri rozsireni napr. o cislice upravit REGEX napr. na "/^[\d]{7}[A-Z1-9]{3}$/"
		if (!preg_match('/^[\d]{7}[A-Z]{3}$/', $newRc)) {
			throw new \Exception('Rodné číslo musí pozostávať zo 7x číslic 0-9 a 3x písmen A-Z.');
		}

		$this->reasonFailOldFormat = '';
		$year = (int) substr($newRc, 0, 3);
		$year += self::BASE_YEAR;
		$month = substr($newRc, 3, 2); // dont typecast to retain padding
		$day = substr($newRc, 5, 2); // dont typecast to retain padding
		$monthReal = $month > 12 ? $month - 50 : $month;

		if($validate && !checkdate(intval($monthReal), intval($day), $year)){
			throw new \Exception('Neplatné rodné číslo.');
		}

		$indexLetter = substr($newRc, -3);
		$indexNum = self::indexLetterToNumber($indexLetter);
		$rc = "";

		// check - can be converted to old format?
		if ($year > date('Y') || $year < 1900) {
			// year out of range - old format possible only for 1900 .. current year
			$this->reasonFailOldFormat = "Year out of range 1900-".date("Y")." (found {$year})";
			$rc = "";
		} elseif ($indexNum > 9999) {
			// index out of range 1954 - index v novom RC presahuje kapacity stareho formatu
			$this->reasonFailOldFormat = "Index out of range 1-9999 (found {$indexNum})";
			$indexNum = "????";
		} elseif ($indexNum > 999 && $year < 1954) {
			// index out of range 1953 - conversion not possible - v starom formate sa pouzivali 3-miestne indexy do 12/1953
			$this->reasonFailOldFormat = "Index out of range 1-999 (found {$indexNum})";
			$indexNum = "???";
		} else {
			// OK - valid RC might exist
			$rc = substr($year, -2)
				.str_pad($month, 2, "0", STR_PAD_LEFT)
				.str_pad($day, 2, "0", STR_PAD_LEFT)
				.str_pad($indexNum, $year < 1954 ? 3 : 4, "0", STR_PAD_LEFT);
		}

		if ($rc && is_numeric($indexNum)) {
			// try to find closest valid index in old format
			for ($i = 0; $i <= self::MODULO; ++$i) {
				// current / legacy birth number
				$verifyOld = new \RodneCislo($rc);
				if ($verifyOld->isValid()) {
					break; // OK, we have valid birth number
				}
				++$indexNum;
				if($year < 1954 && $indexNum > 999){
					$indexNum = 1;
				}elseif($year >= 1954 && $indexNum > 9999){
					$indexNum = 1;
				}
				$rc = substr($year, -2)
					.str_pad($month, 2, "0", STR_PAD_LEFT)
					.str_pad($day, 2, "0", STR_PAD_LEFT)
					.str_pad($indexNum, $year < 1954 ? 3 : 4, "0", STR_PAD_LEFT);
			}
		}

		return $rc;
	}

}
	

Máte otázku?

Synet.sk

Profesionálna tvorba webových aplikácií a riešení na mieru. Konzultačné služby.

Demo

Kontakt


https://synet.sk