Last active
May 6, 2021 07:42
-
-
Save mishak87/4667361 to your computer and use it in GitHub Desktop.
C# class for simple checking of birth number validity with some useful parameters. C# třída pro práci a validaci rodného čísla s pár užitečnými parametry.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using System.Text.RegularExpressions; | |
using System.Runtime.Serialization; | |
namespace net.mishak.utils | |
{ | |
class BirthNumber | |
{ | |
public string Suffix | |
{ | |
get; | |
private set; | |
} | |
public string YearMonthDay | |
{ | |
get; | |
private set; | |
} | |
public string Text | |
{ | |
get | |
{ | |
return YearMonthDay + "/" + Suffix; | |
} | |
} | |
public int Year | |
{ | |
get | |
{ | |
int year = Convert.ToInt16(YearMonthDay.Substring(0, 2)); | |
/* @TODO revisit in 2054 */ | |
return year + (year < 54 ? 2000 : 1900); | |
} | |
} | |
public int Month | |
{ | |
get | |
{ | |
int month = Convert.ToInt16(YearMonthDay.Substring(2, 2)); | |
if (month > 70) /* adjustment for females per 53/2004 */ | |
{ | |
month -= 70; | |
} | |
else if (month > 50) /* adjust for females */ | |
{ | |
month -= 50; | |
} | |
else if (month > 20) /* adjustment for males per 53/2004 */ | |
{ | |
month -= 20; | |
} | |
return month; | |
} | |
} | |
public int Day | |
{ | |
get | |
{ | |
return Convert.ToInt16(YearMonthDay.Substring(4, 2)); | |
} | |
} | |
public enum BirthNumberSex | |
{ | |
FEMALE, | |
MALE | |
} | |
public BirthNumberSex Sex | |
{ | |
get | |
{ | |
return Month > 50 ? BirthNumberSex.FEMALE : BirthNumberSex.MALE; | |
} | |
} | |
public DateTime Date | |
{ | |
get | |
{ | |
return new DateTime(Year, Month, Day); | |
} | |
} | |
private BirthNumber(string yearMonthDay, string suffix) | |
{ | |
YearMonthDay = yearMonthDay; | |
Suffix = suffix; | |
CheckChecksum(); | |
CheckDate(); | |
} | |
private void CheckChecksum() | |
{ | |
// birth number is padded with last digit to be divisible by 11 | |
if (Convert.ToInt16(YearMonthDay + Suffix) % 11 != 0 | |
// only exception is if remainder of first nine numbers divided by 11 is equal to 10 then it is padded with 0 and is not divisible by 11 | |
&& !(Suffix.Length == 4 && Suffix.Substring(3, 1) == "0" && Convert.ToInt16(YearMonthDay + Suffix.Substring(0, 3)) % 11 == 10)) | |
{ | |
throw new InvalidBirthNumberException("Checksum is not matching."); | |
} | |
} | |
private void CheckDate() | |
{ | |
try | |
{ | |
DateTime dateTime = Date; | |
} | |
catch (ArgumentOutOfRangeException) | |
{ | |
throw new InvalidBirthNumberException("Date is not valid."); | |
} | |
} | |
public static BirthNumber FromString(string s) | |
{ | |
Regex reg = new Regex("^([0-9]{6})/?([0-9]{3,4})$"); | |
Match match = reg.Match(s); | |
if (!match.Success) | |
{ | |
throw new InvalidBirthNumberException("Invalid format"); | |
} | |
return new BirthNumber(match.Groups[0].Value, match.Groups[4].Value); | |
} | |
public DateTime GetDate() | |
{ | |
return new DateTime(Year, Month, Day); | |
} | |
} | |
class InvalidBirthNumberException : Exception, ISerializable | |
{ | |
public InvalidBirthNumberException() | |
: base() | |
{ | |
} | |
public InvalidBirthNumberException(string message) | |
: base(message) | |
{ | |
} | |
public InvalidBirthNumberException(string message, Exception inner) | |
: base(message, inner) | |
{ | |
} | |
protected InvalidBirthNumberException(SerializationInfo info, StreamingContext context) | |
: base(info, context) | |
{ | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment