khmer-time-format 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ name: CI
2
+ on: [push, pull_request]
3
+ jobs:
4
+ test:
5
+ runs-on: ubuntu-latest
6
+ steps:
7
+ - uses: actions/checkout@v4
8
+ - uses: actions/setup-python@v5
9
+ with:
10
+ python-version: "3.11"
11
+ - run: python -m pip install -U pip
12
+ - run: pip install -e ".[dev]"
13
+ - run: ruff check .
14
+ - run: mypy src
15
+ - run: pytest
@@ -0,0 +1,25 @@
1
+ name: Publish to PyPI
2
+ on:
3
+ push:
4
+ tags:
5
+ - "v*"
6
+ workflow_dispatch:
7
+ permissions:
8
+ id-token: write
9
+ contents: read
10
+ jobs:
11
+ publish:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ with:
16
+ fetch-depth: 0
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.11"
20
+ - run: python -m pip install -U build
21
+ - run: python -m build
22
+ - run: python -m pip install -U twine
23
+ - run: python -m twine check dist/*
24
+ - name: Publish
25
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,9 @@
1
+ __pycache__/
2
+ *.pyc
3
+ dist/
4
+ build/
5
+ *.egg-info/
6
+ .venv/
7
+ .pytest_cache/
8
+ .mypy_cache/
9
+ .ruff_cache/
@@ -0,0 +1,4 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+ - Initial release
@@ -0,0 +1,3 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
@@ -0,0 +1,76 @@
1
+ Metadata-Version: 2.4
2
+ Name: khmer-time-format
3
+ Version: 0.1.0
4
+ Summary: Format 12/24 hour time into Khmer (digits or words).
5
+ Author: Kon Thaina
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Konthaina/khmer-time-format-py
8
+ Project-URL: Repository, https://github.com/Konthaina/khmer-time-format-py
9
+ Keywords: khmer,time,format
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.8
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Provides-Extra: dev
17
+ Requires-Dist: pytest>=7; extra == "dev"
18
+ Requires-Dist: ruff>=0.5; extra == "dev"
19
+ Requires-Dist: mypy>=1.10; extra == "dev"
20
+ Dynamic: license-file
21
+
22
+ # khmer-time-format (Python)
23
+
24
+ Format 12-hour / 24-hour time (e.g. `1:22 PM`, `13:22`) into Khmer with **two options**:
25
+
26
+ 1) **Khmer numerals (digits)**
27
+ `ម៉ោង១ និង ២២ នាទី រសៀល`
28
+
29
+ 2) **Khmer words (no digits)**
30
+ `ម៉ោងមួយ និង ម្ភៃពីរ នាទី រសៀល`
31
+
32
+ ## Install
33
+
34
+ ```bash
35
+ pip install khmer-time-format
36
+ ```
37
+
38
+ ## Usage
39
+
40
+ ```python
41
+ from khmer_time_format import format_time
42
+
43
+ print(format_time("1:22 PM", mode="digits"))
44
+ print(format_time("13:22", mode="words"))
45
+ ```
46
+
47
+ ## Development
48
+
49
+ ```bash
50
+ python -m venv .venv
51
+ # Windows: .venv\Scripts\activate
52
+ # macOS/Linux: source .venv/bin/activate
53
+ pip install -e ".[dev]"
54
+ pytest
55
+ ruff check .
56
+ mypy src
57
+ ```
58
+
59
+ ## Build & publish (PyPI)
60
+
61
+ ```bash
62
+ python -m build
63
+ python -m twine check dist/*
64
+ ```
65
+
66
+ Push a version tag to publish to PyPI via GitHub Actions:
67
+
68
+ ```bash
69
+ # tag value becomes package version
70
+ git tag v0.1.0
71
+ git push origin v0.1.0
72
+ ```
73
+
74
+ Tag pushes matching `v*` trigger `.github/workflows/publish.yml`.
75
+
76
+ With this setup, you do not need to edit the version in `pyproject.toml` for each release.
@@ -0,0 +1,55 @@
1
+ # khmer-time-format (Python)
2
+
3
+ Format 12-hour / 24-hour time (e.g. `1:22 PM`, `13:22`) into Khmer with **two options**:
4
+
5
+ 1) **Khmer numerals (digits)**
6
+ `ម៉ោង១ និង ២២ នាទី រសៀល`
7
+
8
+ 2) **Khmer words (no digits)**
9
+ `ម៉ោងមួយ និង ម្ភៃពីរ នាទី រសៀល`
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ pip install khmer-time-format
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ```python
20
+ from khmer_time_format import format_time
21
+
22
+ print(format_time("1:22 PM", mode="digits"))
23
+ print(format_time("13:22", mode="words"))
24
+ ```
25
+
26
+ ## Development
27
+
28
+ ```bash
29
+ python -m venv .venv
30
+ # Windows: .venv\Scripts\activate
31
+ # macOS/Linux: source .venv/bin/activate
32
+ pip install -e ".[dev]"
33
+ pytest
34
+ ruff check .
35
+ mypy src
36
+ ```
37
+
38
+ ## Build & publish (PyPI)
39
+
40
+ ```bash
41
+ python -m build
42
+ python -m twine check dist/*
43
+ ```
44
+
45
+ Push a version tag to publish to PyPI via GitHub Actions:
46
+
47
+ ```bash
48
+ # tag value becomes package version
49
+ git tag v0.1.0
50
+ git push origin v0.1.0
51
+ ```
52
+
53
+ Tag pushes matching `v*` trigger `.github/workflows/publish.yml`.
54
+
55
+ With this setup, you do not need to edit the version in `pyproject.toml` for each release.
@@ -0,0 +1,41 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "setuptools-scm[toml]>=8", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "khmer-time-format"
7
+ dynamic = ["version"]
8
+ description = "Format 12/24 hour time into Khmer (digits or words)."
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = {text = "MIT"}
12
+ authors = [{name = "Kon Thaina"}]
13
+ keywords = ["khmer", "time", "format"]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent"
18
+ ]
19
+
20
+ [project.urls]
21
+ Homepage = "https://github.com/Konthaina/khmer-time-format-py"
22
+ Repository = "https://github.com/Konthaina/khmer-time-format-py"
23
+
24
+ [project.optional-dependencies]
25
+ dev = ["pytest>=7", "ruff>=0.5", "mypy>=1.10"]
26
+
27
+ [tool.pytest.ini_options]
28
+ testpaths = ["tests"]
29
+
30
+ [tool.ruff]
31
+ line-length = 88
32
+ target-version = "py38"
33
+
34
+ [tool.mypy]
35
+ python_version = "3.8"
36
+ strict = true
37
+ mypy_path = ["src"]
38
+
39
+ [tool.setuptools_scm]
40
+ fallback_version = "0.0.0"
41
+ local_scheme = "no-local-version"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,10 @@
1
+ from importlib.metadata import PackageNotFoundError, version
2
+
3
+ from .formatter import format_time
4
+
5
+ __all__ = ["format_time", "__version__"]
6
+
7
+ try:
8
+ __version__ = version("khmer-time-format")
9
+ except PackageNotFoundError:
10
+ __version__ = "0.0.0"
@@ -0,0 +1,104 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from typing import Literal, Tuple
5
+
6
+ Mode = Literal["digits", "words"]
7
+
8
+ _KHMER_DIGITS = str.maketrans(
9
+ {"0": "០", "1": "១", "2": "២", "3": "៣", "4": "៤", "5": "៥", "6": "៦", "7": "៧", "8": "៨", "9": "៩"}
10
+ )
11
+
12
+ _UNITS = {
13
+ 0: "សូន្យ",
14
+ 1: "មួយ",
15
+ 2: "ពីរ",
16
+ 3: "បី",
17
+ 4: "បួន",
18
+ 5: "ប្រាំ",
19
+ 6: "ប្រាំមួយ",
20
+ 7: "ប្រាំពីរ",
21
+ 8: "ប្រាំបី",
22
+ 9: "ប្រាំបួន",
23
+ }
24
+
25
+ _TENS = {10: "ដប់", 20: "ម្ភៃ", 30: "សាមសិប", 40: "សែសិប", 50: "ហាសិប"}
26
+
27
+ _TIME_RE = re.compile(r"^\s*(\d{1,2})\s*:\s*(\d{2})\s*(AM|PM)?\s*$", re.IGNORECASE)
28
+
29
+
30
+ def _number_to_khmer_words(n: int) -> str:
31
+ if n < 0 or n > 59:
32
+ raise ValueError("number out of supported range (0-59)")
33
+ if n < 10:
34
+ return _UNITS[n]
35
+ if n < 20:
36
+ if n == 10:
37
+ return _TENS[10]
38
+ return _TENS[10] + _UNITS[n - 10]
39
+ tens = (n // 10) * 10
40
+ ones = n % 10
41
+ if ones == 0:
42
+ return _TENS[tens]
43
+ return _TENS[tens] + _UNITS[ones]
44
+
45
+
46
+ def _number_to_khmer_digits(n: int) -> str:
47
+ return str(n).translate(_KHMER_DIGITS)
48
+
49
+
50
+ def _period_km(hour24: int) -> str:
51
+ if 0 <= hour24 <= 5:
52
+ return "យប់"
53
+ if 6 <= hour24 <= 11:
54
+ return "ព្រឹក"
55
+ if 12 <= hour24 <= 17:
56
+ return "រសៀល"
57
+ return "ល្ងាច"
58
+
59
+
60
+ def _to_12h(hour24: int) -> int:
61
+ h = hour24 % 12
62
+ return 12 if h == 0 else h
63
+
64
+
65
+ def _parse_time(time_str: str) -> Tuple[int, int]:
66
+ m = _TIME_RE.match(time_str)
67
+ if not m:
68
+ raise ValueError("Invalid time format. Use 'H:MM', 'HH:MM', or 'H:MM AM/PM'.")
69
+ hour = int(m.group(1))
70
+ minute = int(m.group(2))
71
+ ampm = m.group(3)
72
+ if minute < 0 or minute > 59:
73
+ raise ValueError("Minute must be 00-59.")
74
+ if ampm:
75
+ if hour < 1 or hour > 12:
76
+ raise ValueError("Hour must be 1-12 when using AM/PM.")
77
+ ap = ampm.upper()
78
+ if ap == "AM":
79
+ hour24 = 0 if hour == 12 else hour
80
+ else:
81
+ hour24 = 12 if hour == 12 else hour + 12
82
+ else:
83
+ if hour < 0 or hour > 23:
84
+ raise ValueError("Hour must be 0-23 for 24-hour input.")
85
+ hour24 = hour
86
+ return hour24, minute
87
+
88
+
89
+ def format_time(time_str: str, mode: Mode = "digits") -> str:
90
+ hour24, minute = _parse_time(time_str)
91
+ hour12 = _to_12h(hour24)
92
+ period = _period_km(hour24)
93
+
94
+ if mode == "digits":
95
+ h = _number_to_khmer_digits(hour12)
96
+ m = _number_to_khmer_digits(minute)
97
+ return f"ម៉ោង{h} និង {m} នាទី {period}"
98
+
99
+ if mode == "words":
100
+ h = _number_to_khmer_words(hour12)
101
+ m = _number_to_khmer_words(minute)
102
+ return f"ម៉ោង{h} និង {m} នាទី {period}"
103
+
104
+ raise ValueError("mode must be 'digits' or 'words'")
@@ -0,0 +1,76 @@
1
+ Metadata-Version: 2.4
2
+ Name: khmer-time-format
3
+ Version: 0.1.0
4
+ Summary: Format 12/24 hour time into Khmer (digits or words).
5
+ Author: Kon Thaina
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Konthaina/khmer-time-format-py
8
+ Project-URL: Repository, https://github.com/Konthaina/khmer-time-format-py
9
+ Keywords: khmer,time,format
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.8
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Provides-Extra: dev
17
+ Requires-Dist: pytest>=7; extra == "dev"
18
+ Requires-Dist: ruff>=0.5; extra == "dev"
19
+ Requires-Dist: mypy>=1.10; extra == "dev"
20
+ Dynamic: license-file
21
+
22
+ # khmer-time-format (Python)
23
+
24
+ Format 12-hour / 24-hour time (e.g. `1:22 PM`, `13:22`) into Khmer with **two options**:
25
+
26
+ 1) **Khmer numerals (digits)**
27
+ `ម៉ោង១ និង ២២ នាទី រសៀល`
28
+
29
+ 2) **Khmer words (no digits)**
30
+ `ម៉ោងមួយ និង ម្ភៃពីរ នាទី រសៀល`
31
+
32
+ ## Install
33
+
34
+ ```bash
35
+ pip install khmer-time-format
36
+ ```
37
+
38
+ ## Usage
39
+
40
+ ```python
41
+ from khmer_time_format import format_time
42
+
43
+ print(format_time("1:22 PM", mode="digits"))
44
+ print(format_time("13:22", mode="words"))
45
+ ```
46
+
47
+ ## Development
48
+
49
+ ```bash
50
+ python -m venv .venv
51
+ # Windows: .venv\Scripts\activate
52
+ # macOS/Linux: source .venv/bin/activate
53
+ pip install -e ".[dev]"
54
+ pytest
55
+ ruff check .
56
+ mypy src
57
+ ```
58
+
59
+ ## Build & publish (PyPI)
60
+
61
+ ```bash
62
+ python -m build
63
+ python -m twine check dist/*
64
+ ```
65
+
66
+ Push a version tag to publish to PyPI via GitHub Actions:
67
+
68
+ ```bash
69
+ # tag value becomes package version
70
+ git tag v0.1.0
71
+ git push origin v0.1.0
72
+ ```
73
+
74
+ Tag pushes matching `v*` trigger `.github/workflows/publish.yml`.
75
+
76
+ With this setup, you do not need to edit the version in `pyproject.toml` for each release.
@@ -0,0 +1,15 @@
1
+ .gitignore
2
+ CHANGELOG.md
3
+ LICENSE
4
+ README.md
5
+ pyproject.toml
6
+ .github/workflows/ci.yml
7
+ .github/workflows/publish.yml
8
+ src/khmer_time_format/__init__.py
9
+ src/khmer_time_format/formatter.py
10
+ src/khmer_time_format.egg-info/PKG-INFO
11
+ src/khmer_time_format.egg-info/SOURCES.txt
12
+ src/khmer_time_format.egg-info/dependency_links.txt
13
+ src/khmer_time_format.egg-info/requires.txt
14
+ src/khmer_time_format.egg-info/top_level.txt
15
+ tests/test_formatter.py
@@ -0,0 +1,5 @@
1
+
2
+ [dev]
3
+ pytest>=7
4
+ ruff>=0.5
5
+ mypy>=1.10
@@ -0,0 +1 @@
1
+ khmer_time_format
@@ -0,0 +1,13 @@
1
+ from khmer_time_format import format_time
2
+
3
+ def test_digits_12h_pm():
4
+ assert format_time("1:22 PM", mode="digits") == "ម៉ោង១ និង ២២ នាទី រសៀល"
5
+
6
+ def test_words_12h_pm():
7
+ assert format_time("1:22 PM", mode="words") == "ម៉ោងមួយ និង ម្ភៃពីរ នាទី រសៀល"
8
+
9
+ def test_digits_24h():
10
+ assert format_time("13:22", mode="digits") == "ម៉ោង១ និង ២២ នាទី រសៀល"
11
+
12
+ def test_words_24h():
13
+ assert format_time("13:22", mode="words") == "ម៉ោងមួយ និង ម្ភៃពីរ នាទី រសៀល"