🇱🇰 Sri Lanka NIC Decoder
Decode Sri Lankan National Identity Card (NIC) numbers into birth date, gender, and NIC type.
This package provides a simple and accurate way to decode both:
- Old NIC format (10 characters →
YYDDDxxxxV) - New NIC format (12 digits →
YYYYDDDxxxx)
The decoder uses Python's datetime module to correctly compute dates, including leap years and month boundaries.
It also implements the correct NIC day-number offset discovered from real NIC examples.
✨ Features
✔ Supports Old and New Sri Lankan NIC formats
✔ Extracts full Date of Birth
✔ Determines Gender (Male / Female)
✔ Automatically identifies NIC type
✔ Correct leap-year handling
✔ Configurable NIC day-code offset (default = 2)
✔ Clean, reusable functions
✔ Includes a structured NICInfo dataclass
📦 Installation
pip install lka-nic-decoder
🔧 Usage Example
from lka_nic_decoder import decode_nic
# Decode an old NIC
info = decode_nic("912680444V")
print(info.nic_type) # Old NIC
print(info.gender) # Male
print(info.birth_year) # 1991
print(info.birth_date) # 1991-09-24
# Decode a new NIC
info_new = decode_nic("199253600001")
print(info_new.nic_type) # New NIC
print(info_new.gender) # Female
print(info_new.birth_year) # 1992
print(info_new.birth_date) # 1992-02-05
📋 Import Methods
1. Import Specific Function (Recommended)
from lka_nic_decoder import decode_nic
info = decode_nic("912680444V")
2. Import Entire Module
import lka_nic_decoder
info = lka_nic_decoder.decode_nic("912680444V")
3. Import Multiple Functions
from lka_nic_decoder import decode_nic, parse_nic_base, nic_to_date
info = decode_nic("912680444V")
nic_type, year, day_code = parse_nic_base("912680444V")
4. Import with Alias
from lka_nic_decoder import decode_nic as decode
info = decode("912680444V")
5. Import Validation Function
from lka_nic_decoder import is_valid_nic, decode_nic
if is_valid_nic("912680444V"):
info = decode_nic("912680444V")
print(f"Valid NIC: {info.birth_date}")
6. Import Dataclass for Type Hints
from lka_nic_decoder import NICInfo, decode_nic
def process_nic(nic: str) -> NICInfo:
return decode_nic(nic)
7. Import Constants
from lka_nic_decoder import DEFAULT_NIC_DAY_OFFSET, nic_to_date
custom_date = nic_to_date(1991, 268, offset=DEFAULT_NIC_DAY_OFFSET)
8. Error Handling Pattern
from lka_nic_decoder import decode_nic, is_valid_nic
try:
if is_valid_nic("912680444V"):
info = decode_nic("912680444V")
print(f"Birth Date: {info.birth_date}")
except ValueError as e:
print(f"Error: {e}")
📘 What the Decoder Extracts
| Field | Example Value | Description |
|---|---|---|
| NIC Type | Old NIC,New NIC |
Old (10 chars) or New (12 chars) |
| Birth Year | 1991 |
Parsed from NIC digits |
| Gender | Male,Female |
Based on day code (>500 → Female) |
| Birth Date | 1991-09-24 |
Fully computed using datetime |
| Raw Day Code | 268 |
Original 3-digit day component |
| Day Code | 268 / -500 |
Adjusted for females |
🧠 How NIC Decoding Works
1. NIC Type
-
Old NIC (10 chars)
-
Year = 1900/2000 + YY
-
Day-of-year = DDD
-
New NIC (12 digits)
-
Year = YYYY
-
Day-of-year = DDD
2. Gender
- If day code > 500 → Female
- Else → Male
- Female NICs subtract 500 from day code
3. Date Calculation
The NIC system has a known offset of +2 days, so decoding uses:
Date calculation uses:
from datetime import datetime, timedelta
start_of_year = datetime(year, 1, 1)
birth_date = start_of_year + timedelta(days=actual_day_of_year)
This ensures:
- Leap years handled properly
- Month boundaries handled
- No manual month/day mapping needed
📚 Full API Documentation
decode_nic(nic: str, offset: int = 2) -> NICInfo
Main high-level function — decodes a Sri Lankan NIC and returns a NICInfo dataclass.
Parameters:
nic(str): The NIC number to decode (10-character old NIC or 12-digit new NIC).offset(int, optional): Day-of-year offset. Default is2.
Returns:
NICInfoobject containing:nic_type(str):"Old NIC"or"New NIC"gender(str):"Male"or"Female"birth_year(int): Year of birthraw_day_code(int): Original 3-digit day code from NICday_code(int): Adjusted day code (after gender correction)birth_date(date): Full date of birth asdatetime.date
Example:
from lka_nic_decoder import decode_nic
info = decode_nic("912680444V")
print(info.birth_date) # 1991-09-24
### `parse_nic_base(nic: str) -> tuple`
Parses NIC type, birth year, and raw day code without computing the full date.
**Returns:**
```python
(nic_type, birth_year, raw_day_code)
from lka_nic_decoder import parse_nic_base
nic_type, birth_year, day_code = parse_nic_base("912680444V")
print(nic_type) # Old NIC
print(birth_year) # 1991
print(day_code) # 268
nic_to_date(birth_year: int, day_code: int, offset: int = 2) -> date
Converts the day-of-year code to an actual datetime.date.
Parameters:
birth_year(int): Year of birthday_code(int): Adjusted day-of-year codeoffset(int, optional): NIC system day offset (default2)
Example:
from lka_nic_decoder import nic_to_date
from datetime import date
birth_date = nic_to_date(1991, 268)
print(birth_date) # 1991-09-24
is_valid_nic(nic: str) -> bool
Checks if a NIC string is a valid format (10-character old NIC or 12-digit new NIC).
Example:
from lka_nic_decoder import is_valid_nic
print(is_valid_nic("912680444V")) # True
print(is_valid_nic("1234567890")) # True
print(is_valid_nic("ABCDE")) # False
NICInfo Dataclass
Stores all decoded NIC information in a structured object.
from dataclasses import dataclass
from datetime import date
@dataclass(frozen=True)
class NICInfo:
nic_type: str
gender: str
birth_year: int
raw_day_code: int
day_code: int
birth_date: date
from lka_nic_decoder import decode_nic
info = decode_nic("912680444V")
print(info.nic_type) # Old NIC
print(info.gender) # Male
print(info.birth_year) # 1991
print(info.birth_date) # 1991-09-24
🏷️ Versioning
Follows Semantic Versioning (SemVer):
1.0.18
📄 License
MIT License — permits both personal and commercial use.
🤝 Contributing
Pull requests welcome!
Open issues for improvements, validation rules, or new features.
Metadata
Release files for lka-nic-decoder 1.0.18
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| lka_nic_decoder-1.0.18.tar.gz | 6.6 kB | Without provenance | Details for lka_nic_decoder-1.0.18.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| lka_nic_decoder-1.0.18-py3-none-any.whl | Python 3 | none | any | Details for lka_nic_decoder-1.0.18-py3-none-any.whl |
Total release size: 13.1 kB
Release files / lka_nic_decoder-1.0.18.tar.gz
| Download URL | lka_nic_decoder-1.0.18.tar.gz |
|---|---|
| Size | 6.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
562bc1916cbeef517f5d998939028846d28c68703ecbcc7969ce427ddbb8b678
|
|
BLAKE2b-256 checksum How to use checksums |
bcf625c54deae13c23eb864aef5b38a478666c2f1da0a45225009ea187f39bcf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.0
|
Release files / lka_nic_decoder-1.0.18-py3-none-any.whl
| Download URL | lka_nic_decoder-1.0.18-py3-none-any.whl |
|---|---|
| Size | 6.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a27a3576f1786221918eb31a4abea83673c9ea4853c7651c803c52987ce0756a
|
|
BLAKE2b-256 checksum How to use checksums |
2b1fc1a81d924db3c9696fa2fa5a79e51b1107df840b8bcd5eeeaac03e5d3947
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.0
|
Security for lka-nic-decoder 1.0.18
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.