Skip to main content

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}")

Metadata

Release files for jmbg-labs 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jmbg-labs 1.0.0
File Size Uploaded
jmbg_labs-1.0.0.tar.gz 8.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jmbg-labs 1.0.0
File Interpreter ABI Platform
jmbg_labs-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 17.5 kB

Release files / jmbg_labs-1.0.0.tar.gz

Download URL jmbg_labs-1.0.0.tar.gz
Size 8.5 kB
Tags Source
SHA-256 checksum
How to use checksums
2da9943adfc638e30cae01401dab93d576d453a434f1dd198d169af11184f679
BLAKE2b-256 checksum
How to use checksums
df39658c4c474c0bcc262b5e256f3adb5268ad05b3e35a3c8f8c990a9b7c687b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.0

Release files / jmbg_labs-1.0.0-py3-none-any.whl

Download URL jmbg_labs-1.0.0-py3-none-any.whl
Size 9.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
707e4ec8d4a3666a481467b9702c6b6cd8a8e90e840164e85f8211c03b764b3d
BLAKE2b-256 checksum
How to use checksums
3da2d8524b7634ed4eb9695d112b4888cb75e54eb560a0f834efcc7e59d42d87
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.0

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page