Skip to main content

A Python library for validating and parsing Serbian unique master citizen numbers (JMBG)

Project description

JMBG Python Library

License: MIT Python Version

A Python library for validating and parsing Serbian unique master citizen numbers (JMBG - Jedinstveni Matični Broj Građana).

Features

  • ✅ Validate JMBG numbers with comprehensive checks
  • ✅ Extract birth date, region, and gender information
  • ✅ Support for all Serbian regions
  • ✅ Calculate age from JMBG
  • ✅ Type-safe with Python type hints
  • ✅ Fully tested with unittest
  • ✅ No external dependencies

Installation

Install via pip:

pip install jmbg-labs

Or clone the repository:

git clone https://github.com/jmbg-labs/python.git
cd python

Usage

Basic Validation

from jmbg import Jmbg, valid

# Quick validation
if valid('0101000710009'):
    print("Valid JMBG")

# Parse and validate
try:
    jmbg = Jmbg.parse('0101000710009')
    print(f"Valid JMBG: {jmbg.format()}")
except JmbgError as e:
    print(f"Invalid JMBG: {e}")

Extract Information

from jmbg import Jmbg

jmbg = Jmbg('0101000710009')

# Get birth date
date = jmbg.get_date()  # datetime.date object
print(date.strftime('%Y-%m-%d'))  # 2000-01-01

# Get age
print(jmbg.get_age())  # e.g., 26

# Check gender
if jmbg.is_male():
    print("Male")

if jmbg.is_female():
    print("Female")

# Access individual parts
print(jmbg.day)           # 1
print(jmbg.month)         # 1
print(jmbg.year)          # 2000
print(jmbg.region)        # 71
print(jmbg.region_text)   # "Belgrade"
print(jmbg.country)       # "Serbia"
print(jmbg.unique)        # 0
print(jmbg.checksum)      # 9

Using Built-in Methods

jmbg = Jmbg('1505995800002')

# String conversion
print(str(jmbg))  # "1505995800002"
print(jmbg.format())  # "1505995800002"

# Property access
print(jmbg.original)        # "1505995800002"
print(jmbg.day_original)    # "15"
print(jmbg.month_original)  # "05"
print(jmbg.year_original)   # "995"
print(jmbg.region_original) # "80"
print(jmbg.unique_original) # "000"

# Check adult status
if jmbg.is_adult():
    print("Adult (18+)")

JMBG Format

JMBG consists of 13 digits: DDMMYYYRRBBBC

  • DD - Day of birth (01-31)
  • MM - Month of birth (01-12)
  • YYY - Year of birth (last 3 digits)
  • RR - Region code
  • BBB - Unique number (000-499 for males, 500-999 for females)
  • C - Checksum digit

Supported Regions

The library supports all Serbian and ex-Yugoslav regions including (beware: ex-Yugoslav regions codes may have changed since the breakup):

  • Serbia (71-79): Belgrade, Kragujevac, Niš, etc.
  • Serbia/Vojvodina (80-89): Novi Sad, Subotica, Pančevo, etc.
  • Serbia/Kosovo (91-96): Priština, Peć, Prizren, etc.
  • Bosnia and Herzegovina (10-19)
  • Montenegro (21-29)
  • Croatia (30-39)
  • Macedonia (41-49)
  • Slovenia (50)

Validation Rules

The library performs comprehensive validation:

  1. Length check - Must be exactly 13 digits
  2. Format check - Must contain only numeric characters
  3. Date validation - Birth date must be valid (including leap year support)
  4. Region validation - Region code must exist in the registry
  5. Checksum validation - Modulo 11 algorithm verification

Development

Running Tests

# Run all tests
python -m unittest discover

# Run specific test file
python -m unittest test_jmbg

# Run tests with verbose output
python -m unittest test_jmbg -v

Code Style

# Format code with black
black .

# Check types with mypy
mypy jmbg.py

Requirements

  • Python ^3.8
  • No external dependencies (for production use)

Contributing

Contributions are welcome! Please ensure:

  1. All tests pass (python -m unittest discover)
  2. Code follows PEP 8 standards
  3. Add tests for new features
  4. Update documentation as needed

License

This project is licensed under the MIT License - see the LICENSE file for details.

Credits

Developed by JMBG Labs

Support

Examples

Validate Multiple JMBGs

from jmbg import Jmbg, valid

jmbgs = ['0710003730015', '1705978730032', 'invalid']

for jmbg_string in jmbgs:
    if valid(jmbg_string):
        jmbg = Jmbg.parse(jmbg_string)
        print(f"{jmbg.format()} - Born: {jmbg.get_date()}, "
              f"Region: {jmbg.region_text}, "
              f"Gender: {'Male' if jmbg.is_male() else 'Female'}")
    else:
        print(f"{jmbg_string} - Invalid")

Age Calculation

from jmbg import Jmbg

jmbg = Jmbg('0710003730015')
age = jmbg.get_age()

if age >= 18:
    print("Adult")
else:
    print("Minor")

Error Handling

from jmbg import Jmbg
from jmbg_error import JmbgError

try:
    jmbg = Jmbg('1234567890123')
except JmbgError as e:
    # Handle specific validation errors
    print(f"Validation failed: {e}")
    # Possible messages:
    # - "JMBG string must have exactly 13 digits, got X"
    # - "JMBG must contain only numeric characters"
    # - "Date 'DD/MM/YYYY' is not valid"
    # - "Region 'XX' is not valid for JMBG"
    # - "Checksum is not valid"

Working with Gender

from jmbg import Jmbg
from gender import Gender

jmbg = Jmbg('0710003730015')

# Get gender enum
gender = jmbg.gender()
if gender == Gender.MALE:
    print("Male")
elif gender == Gender.FEMALE:
    print("Female")

# Or use convenience methods
print(jmbg.is_male())    # True
print(jmbg.is_female())  # False

Date Operations

from jmbg import Jmbg
import datetime

jmbg = Jmbg('2902992710005')  # Leap year date
birth_date = jmbg.get_date()

# Calculate days until next birthday
today = datetime.date.today()
next_birthday = datetime.date(today.year, birth_date.month, birth_date.day)
if next_birthday < today:
    next_birthday = datetime.date(today.year + 1, birth_date.month, birth_date.day)

days_until = (next_birthday - today).days
print(f"Days until birthday: {days_until}")

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jmbg_labs-1.0.0.tar.gz (8.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jmbg_labs-1.0.0-py3-none-any.whl (9.0 kB view details)

Uploaded Python 3

File details

Details for the file jmbg_labs-1.0.0.tar.gz.

File metadata

  • Download URL: jmbg_labs-1.0.0.tar.gz
  • Upload date:
  • Size: 8.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for jmbg_labs-1.0.0.tar.gz
Algorithm Hash digest
SHA256 2da9943adfc638e30cae01401dab93d576d453a434f1dd198d169af11184f679
MD5 1d9d8d3154b12c3662ad843f34a35d53
BLAKE2b-256 df39658c4c474c0bcc262b5e256f3adb5268ad05b3e35a3c8f8c990a9b7c687b

See more details on using hashes here.

File details

Details for the file jmbg_labs-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: jmbg_labs-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 9.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for jmbg_labs-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 707e4ec8d4a3666a481467b9702c6b6cd8a8e90e840164e85f8211c03b764b3d
MD5 25f803a7114caa80f69ad78e3405721b
BLAKE2b-256 3da2d8524b7634ed4eb9695d112b4888cb75e54eb560a0f834efcc7e59d42d87

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page