I Have a problem with my regular expression. I have made it possible to valdiate correct swedish social security number to match these criteria.
But i would also like to reject a user to register if the user is under 18 years old. My reqular expression is looking like this at the moment: Do anyone encountered the same problem with the age range Swedish SSN?
private const string RegExForValidation =
@"^(\d{6}|\d{8})[-|(\s)]{0,1}\d{4}$";
UPDATE
private const string RegExForValidation = @"^(?<date>\d{6}|\d{8})[-\s]?\d{4}$";
string date = Regex.Match("19970918-1234", RegExForValidation).Groups["date"].Value;
DateTime dt;
[Required(ErrorMessage = "Du måste ange personnummer")]
[RegularExpression(RegExForValidation, ErrorMessage = "Personnummer anges med 10 siffror (yymmddnnnn)")]
public string PersonalIdentityNumber { get; set; }
Second Update
public class ValidateOfAge : ValidationAttribute
{
public bool IsOfAge(DateTime birthdate)
{
DateTime today = DateTime.Today;
int age = today.Year - 18;
if (birthdate.AddYears(birthdate.Year) < today.AddYears(-age))
return false;
else
return true;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string RegExForValidation = @"^(?<date>\d{6}|\d{8})[-\s]?\d{4}$";
string date = Regex.Match((string)value, RegExForValidation).Groups["date"].Value;
DateTime dt;
if (DateTime.TryParseExact(date, new[] { "yyMMdd", "yyyyMMdd" }, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt))
if (IsOfAge(dt))
return ValidationResult.Success;
return new ValidationResult("Personnummer anges med 10 siffror (yymmddnnnn)");
}
}
You need to get the birthdate from the SSN, parse to DateTime, and then compare with today's date.
Here is the method checking if a person is of age:
public bool IsOfAge(DateTime birthdate)
{
DateTime today = DateTime.Today; // Calculating age...
int age = today.Year - birthdate.Year;
if (birthdate > today.AddYears(-age))
age--;
return age < 18 ? false : true; // If the age is 18+ > true, else false.
}
And here is how you can use this:
string RegExForValidation = @"^(?<date>\d{6}|\d{8})[-\s]?\d{4}$";
string date = Regex.Match("19970918-1234", RegExForValidation).Groups["date"].Value;
DateTime dt;
if (DateTime.TryParseExact(date, new[] { "yyMMdd", "yyyyMMdd" }, new CultureInfo("sv-SE"), DateTimeStyles.None, out dt))
Console.WriteLine(IsOfAge(dt));
Note that [-|(\s)]
matches a -
, |
, (
, whitespace or )
. I am sure you only want to match a hyphen or whitespace.
I added a named capture to the regex and removed unnecessary symbols from the character class. Also, note that {0,1}
is the same as ?
.
UPDATE
To make it work in an MVC app, you need to implement a custom validator:
[Required(ErrorMessage = "Du måste ange personnummer")]
[ValidateOfAge] // <---------------------------- HERE
public string PersonalIdentityNumber { get; set; }
And implement this as follows:
public class ValidateOfAge: ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string RegExForValidation = @"^(?<date>\d{6}|\d{8})[-\s]?\d{4}$";
string date = Regex.Match((string)value, RegExForValidation).Groups["date"].Value;
DateTime dt;
if (DateTime.TryParseExact(date, new[] { "yyMMdd", "yyyyMMdd" }, new CultureInfo("sv-SE"), DateTimeStyles.None, out dt))
if (IsOfAge(dt))
return ValidationResult.Success;
return new ValidationResult("Personnummer anges med 10 siffror (yymmddnnnn)");
}
}
This is a case where I wouldn't use regular expressions, but instead rely on the base class library's built-in DateTime parsing functionality:
public DateTime GetBirthDate(string ssn)
{
var strippedOfSerial =
ssn.Substring(0, ssn.Length - 4).TrimEnd('-');
return DateTime.ParseExact(
strippedOfSerial,
new[] { "yyMMdd", "yyyyMMdd" },
new CultureInfo("se-SE"),
DateTimeStyles.None);
}
Now you can look at the returned DateTime
value and compare it to DateTime.Now
in order to figure out if you want to reject it or not.
In my opinion, this is much more readable than relying on regular expressions, and may be safer and more flexible as well. As you can tell, you can e.g. use other cultures etc. to tweak the parsing strategy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With