Skip to content

Commit

Permalink
fixed problem with bith date validationa and parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
p333ter committed Dec 17, 2024
1 parent cca41d3 commit b720af2
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 55 deletions.
10 changes: 5 additions & 5 deletions examples/basic-usage.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/* eslint-disable no-console */
import {
generateCzechBirthNumber,
generateSlovakBirthNumber,
generateCzechBirthNumber,
generateSlovakBirthNumber,
} from '../src/generators';
import {
isValidBirthNumber,
parseBirthNumber,
} from '../src/validators/birthNumber';
isValidBirthNumber,
parseBirthNumber,
} from '../src/validators';

// Example 1: Generate a birth number for a male (Czech Republic)
const czechMaleBirthNumber = generateCzechBirthNumber({ gender: 'MALE' });
Expand Down
27 changes: 19 additions & 8 deletions src/__tests__/birthClass.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { generateCzechBirthNumber } from '../generators/czech';
import { BirthNumber, rodnecislo } from '../model';
import { BirthNumber, rodnecislo } from '../classes';
import { generateCzechBirthNumber } from '../generators/czech';

describe('BirthNumber Class', () => {
describe('Valid Birth Numbers', () => {
Expand All @@ -11,8 +11,8 @@ describe('BirthNumber Class', () => {
expect(rc.day()).toBe(20);
expect(rc.isMale()).toBe(true);
expect(rc.isFemale()).toBe(false);
expect(rc.birthDate()).toEqual(new Date(1990, 6, 20));
expect(rc.birthDateAsString()).toBe('20.7.1990');
expect(rc.birthDate()).toEqual(new Date(Date.UTC(1990, 6, 20)));
expect(rc.birthDateAsString()).toBe('20.07.1990');
expect(rc.isValid()).toBe(true);
expect(rc.isPossible()).toBe(true);
expect(rc.isAdult()).toBe(true);
Expand All @@ -28,8 +28,8 @@ describe('BirthNumber Class', () => {
expect(rc.day()).toBe(20);
expect(rc.isMale()).toBe(false);
expect(rc.isFemale()).toBe(true);
expect(rc.birthDate()).toEqual(new Date(1990, 6, 20));
expect(rc.birthDateAsString()).toBe('20.7.1990');
expect(rc.birthDate()).toEqual(new Date(Date.UTC(1990, 6, 20)));
expect(rc.birthDateAsString()).toBe('20.07.1990');
expect(rc.isValid()).toBe(true);
expect(rc.isPossible()).toBe(true);
expect(rc.isAdult()).toBe(true);
Expand Down Expand Up @@ -58,7 +58,7 @@ describe('BirthNumber Class', () => {
expect(rc.isPossible()).toBe(false);
expect(rc.isAdult()).toBe(false);
expect(rc.age()).toBe(null);
expect(rc.error()).toBe('Invalid birth number');
expect(rc.error()).toBe('Invalid birth number format');
});

it('handles invalid modulo', () => {
Expand Down Expand Up @@ -109,7 +109,7 @@ describe('BirthNumber Class', () => {
it('handles leap years correctly', () => {
const leapYear = rodnecislo('0002295689'); // 29.2.2000
expect(leapYear.isValid()).toBe(true);
expect(leapYear.birthDateAsString()).toBe('29.2.2000');
expect(leapYear.birthDateAsString()).toBe('29.02.2000');
});

it('handles month edge cases', () => {
Expand All @@ -132,4 +132,15 @@ describe('BirthNumber Class', () => {
expect(fromConstructor.isValid()).toBe(fromFactory.isValid());
});
});

describe('Future Birth Numbers', () => {
it('validates future birth numbers correctly', () => {
const future = rodnecislo('4012170954'); // 17.12.2040

expect(future.isValid()).toBe(true); // formálne správne
expect(future.isPossible()).toBe(true); // formálne správne
expect(future.isBorn()).toBe(false); // ešte nenarodený
expect(future.age()).toBeLessThan(0); // záporný vek
});
});
});
8 changes: 4 additions & 4 deletions src/__tests__/birthNumber.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ describe('Birth Number Validation and Parsing', () => {
});

it('parses valid male birth number', () => {
const birthDate = new Date(1990, 6, 20);
const birthDate = new Date(Date.UTC(1990, 6, 20));
const result = parseBirthNumber('9007203117'); // Platné číslo
expect(result).not.toBe(false);
if (result) {
Expand All @@ -72,13 +72,13 @@ describe('Birth Number Validation and Parsing', () => {
expect(result.isAdult).toBe(true);
expect(result.isMale).toBe(true);
expect(result.isFemale).toBe(false);
expect(result.birthDateAsString).toBe('20.7.1990');
expect(result.birthDateAsString).toBe('20.07.1990');
expect(result.error).toBe(null);
}
});

it('parses valid female birth number', () => {
const birthDate = new Date(1990, 6, 20);
const birthDate = new Date(Date.UTC(1990, 6, 20));
const result = parseBirthNumber('9057203111'); // Platné číslo pre ženu
expect(result).not.toBe(false);
if (result) {
Expand All @@ -95,7 +95,7 @@ describe('Birth Number Validation and Parsing', () => {
expect(result.isAdult).toBe(true);
expect(result.isMale).toBe(false);
expect(result.isFemale).toBe(true);
expect(result.birthDateAsString).toBe('20.7.1990');
expect(result.birthDateAsString).toBe('20.07.1990');
expect(result.error).toBe(null);
}
});
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/czech.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { generateCzechBirthNumber } from '../generators/czech';
import {
isValidBirthNumber,
isValidBirthNumber
} from '../validators';

describe('generateCzechBirthNumber', () => {
Expand Down
14 changes: 10 additions & 4 deletions src/model/BirthNumber.ts → src/classes/BirthNumber.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BirthNumberDetails } from "../types";
import { parseBirthNumber, sanitizeBirthNumber } from "../validators";
import { BirthNumberDetails } from '../types';
import { parseBirthNumber, sanitizeBirthNumber } from '../validators';

export class BirthNumber {
private readonly rawValue: string;
Expand All @@ -26,6 +26,11 @@ export class BirthNumber {
return this.parsedValue.birthDate.getDate();
}

isBorn(): boolean {
if (!this.parsedValue) return false;
return this.parsedValue.age >= 0;
}

// Pomocné metódy pre pohlavie
isMale(): boolean {
return this.parsedValue ? this.parsedValue.isMale : false;
Expand All @@ -48,7 +53,7 @@ export class BirthNumber {

// Validačné metódy
isValid(): boolean {
return this.parsedValue !== false && this.parsedValue.age >= 0;
return this.parsedValue !== false;
}

isPossible(): boolean {
Expand All @@ -68,7 +73,8 @@ export class BirthNumber {

// Getter pre error
error(): string | null {
if (!this.parsedValue) return 'Invalid birth number';
if (!this.parsedValue) return 'Invalid birth number format';
if (!this.isBorn()) return 'Birth date is in future';
return this.parsedValue.error;
}
}
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { BirthNumber, rodnecislo } from './model/BirthNumber';
export { BirthNumber, rodnecislo } from './classes/BirthNumber';
export {
generateCzechBirthNumber,
generateSlovakBirthNumber
Expand Down
51 changes: 19 additions & 32 deletions src/validators/birthNumberValidator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { BirthNumberDetails, Gender } from "../types";
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import { BirthNumberDetails, Gender } from '../types';

export const sanitizeBirthNumber = (input: string): string => input.replace(/\//g, '');
dayjs.extend(utc);


export const sanitizeBirthNumber = (input: string): string =>
input.replace(/\//g, '');

const CONSTANTS = {
MONTH_OFFSET: 1,
Expand All @@ -21,22 +27,9 @@ const CONSTANTS = {
const RODNECISLO_RE = /^(\d\d)(\d\d)(\d\d)\/?(\d\d\d\d?)$/;

// Pomocné funkcie
const calculateAge = (birthDate: Date): number => {
const today = new Date();
let age = today.getFullYear() - birthDate.getFullYear();
const m = today.getMonth() - birthDate.getMonth();

if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
age--;
}

return age;
};

const formatDate = (date: Date): string => {
return `${date.getDate()}.${
date.getMonth() + CONSTANTS.MONTH_OFFSET
}.${date.getFullYear()}`;
const formatDate = (date: dayjs.Dayjs): string => {
return date.format('DD.MM.YYYY');
};

const validateModulo = (
Expand Down Expand Up @@ -121,26 +114,20 @@ export const parseBirthNumber = (
if (!isValid) return false;

const day = parseInt(dd, 10);
const birthDate = new Date(year, month - CONSTANTS.MONTH_OFFSET, day);
const birthDate = dayjs.utc(`${year}-${month}-${day}`, 'YYYY-M-D', true);

// Validácia dátumu
if (
birthDate.getFullYear() !== year ||
birthDate.getMonth() !== month - CONSTANTS.MONTH_OFFSET ||
birthDate.getDate() !== day
) {
return false;
}
if (!birthDate.isValid()) return false;

const age = calculateAge(birthDate);
const age = dayjs().diff(birthDate, 'year');

// Kontrola validity veku
if (age < CONSTANTS.AGE_WHEN_BORN) {
return false;
}
// Commented out due to the fact that the age of the person is not relevant for the validation
// if (age < CONSTANTS.AGE_WHEN_BORN) {
// return false;
// }

return {
birthDate,
birthDate: birthDate.toDate(),
gender,
age,
isAdult: age >= CONSTANTS.DEFAULT_ADULTHOOD,
Expand All @@ -154,4 +141,4 @@ export const parseBirthNumber = (
export const isValidBirthNumber = (birthNumber: string): boolean => {
const sanitized = sanitizeBirthNumber(birthNumber);
return parseBirthNumber(sanitized) !== false;
};
};

0 comments on commit b720af2

Please sign in to comment.