todayjuliandate 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.
- todayjuliandate-0.1.0/LICENSE +21 -0
- todayjuliandate-0.1.0/PKG-INFO +62 -0
- todayjuliandate-0.1.0/README.md +42 -0
- todayjuliandate-0.1.0/pyproject.toml +32 -0
- todayjuliandate-0.1.0/setup.cfg +4 -0
- todayjuliandate-0.1.0/src/todayjuliandate/__init__.py +99 -0
- todayjuliandate-0.1.0/src/todayjuliandate/cli.py +34 -0
- todayjuliandate-0.1.0/src/todayjuliandate.egg-info/PKG-INFO +62 -0
- todayjuliandate-0.1.0/src/todayjuliandate.egg-info/SOURCES.txt +11 -0
- todayjuliandate-0.1.0/src/todayjuliandate.egg-info/dependency_links.txt +1 -0
- todayjuliandate-0.1.0/src/todayjuliandate.egg-info/entry_points.txt +2 -0
- todayjuliandate-0.1.0/src/todayjuliandate.egg-info/top_level.txt +1 -0
- todayjuliandate-0.1.0/tests/test_todayjuliandate.py +16 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ordinal Date Notes
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: todayjuliandate
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Today's Julian date helpers: YYDDD / CYYDDD ordinal lot codes, Julian Day (JD), and MJD converters.
|
|
5
|
+
Author: Ordinal Date Notes
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://todayjuliandate.com/
|
|
8
|
+
Project-URL: Documentation, https://todayjuliandate.com/code/
|
|
9
|
+
Project-URL: Live converter, https://todayjuliandate.com/
|
|
10
|
+
Keywords: julian-date,todays-julian-date,ordinal-date,yyddd,cyyddd,mjd,lot-code
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# todayjuliandate
|
|
22
|
+
|
|
23
|
+
Helpers for **today's Julian date** and related ordinal lot codes: YYDDD, CYYDDD, Julian Day (JD), and Modified Julian Day (MJD).
|
|
24
|
+
|
|
25
|
+
Companion library for [todayjuliandate.com](https://todayjuliandate.com/) — converters and code samples for egg-carton / food-lot stamps and calendar math.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install todayjuliandate
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick use
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from datetime import date
|
|
37
|
+
from todayjuliandate import to_yyddd, from_yyddd, to_cyyddd, julian_day, mjd
|
|
38
|
+
|
|
39
|
+
d = date(2024, 7, 1)
|
|
40
|
+
print(to_yyddd(d)) # "24183"
|
|
41
|
+
print(from_yyddd("24183"))
|
|
42
|
+
print(to_cyyddd(d)) # "2024183"
|
|
43
|
+
print(julian_day(d))
|
|
44
|
+
print(mjd(d))
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
CLI:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
todayjuliandate 2024-07-01
|
|
51
|
+
todayjuliandate --from-yyddd 24183
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Sources
|
|
55
|
+
|
|
56
|
+
- [USNO Julian Date](https://aa.usno.navy.mil/data/JulianDate) — astronomical JD definitions
|
|
57
|
+
- [todayjuliandate.com](https://todayjuliandate.com/) — today's Julian date converter and code
|
|
58
|
+
- [NIST time and frequency](https://www.nist.gov/pml/time-and-frequency-division) — civil time context
|
|
59
|
+
|
|
60
|
+
## License
|
|
61
|
+
|
|
62
|
+
MIT
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# todayjuliandate
|
|
2
|
+
|
|
3
|
+
Helpers for **today's Julian date** and related ordinal lot codes: YYDDD, CYYDDD, Julian Day (JD), and Modified Julian Day (MJD).
|
|
4
|
+
|
|
5
|
+
Companion library for [todayjuliandate.com](https://todayjuliandate.com/) — converters and code samples for egg-carton / food-lot stamps and calendar math.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install todayjuliandate
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick use
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from datetime import date
|
|
17
|
+
from todayjuliandate import to_yyddd, from_yyddd, to_cyyddd, julian_day, mjd
|
|
18
|
+
|
|
19
|
+
d = date(2024, 7, 1)
|
|
20
|
+
print(to_yyddd(d)) # "24183"
|
|
21
|
+
print(from_yyddd("24183"))
|
|
22
|
+
print(to_cyyddd(d)) # "2024183"
|
|
23
|
+
print(julian_day(d))
|
|
24
|
+
print(mjd(d))
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
CLI:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
todayjuliandate 2024-07-01
|
|
31
|
+
todayjuliandate --from-yyddd 24183
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Sources
|
|
35
|
+
|
|
36
|
+
- [USNO Julian Date](https://aa.usno.navy.mil/data/JulianDate) — astronomical JD definitions
|
|
37
|
+
- [todayjuliandate.com](https://todayjuliandate.com/) — today's Julian date converter and code
|
|
38
|
+
- [NIST time and frequency](https://www.nist.gov/pml/time-and-frequency-division) — civil time context
|
|
39
|
+
|
|
40
|
+
## License
|
|
41
|
+
|
|
42
|
+
MIT
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "todayjuliandate"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Today's Julian date helpers: YYDDD / CYYDDD ordinal lot codes, Julian Day (JD), and MJD converters."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [{ name = "Ordinal Date Notes" }]
|
|
13
|
+
keywords = ["julian-date", "todays-julian-date", "ordinal-date", "yyddd", "cyyddd", "mjd", "lot-code"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Topic :: Software Development :: Libraries",
|
|
19
|
+
"Topic :: Scientific/Engineering",
|
|
20
|
+
]
|
|
21
|
+
dependencies = []
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Homepage = "https://todayjuliandate.com/"
|
|
25
|
+
Documentation = "https://todayjuliandate.com/code/"
|
|
26
|
+
"Live converter" = "https://todayjuliandate.com/"
|
|
27
|
+
|
|
28
|
+
[project.scripts]
|
|
29
|
+
todayjuliandate = "todayjuliandate.cli:main"
|
|
30
|
+
|
|
31
|
+
[tool.setuptools.packages.find]
|
|
32
|
+
where = ["src"]
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""Ordinal / Julian lot-code helpers (YYDDD, CYYDDD) and JD/MJD."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from datetime import date, datetime, timezone
|
|
5
|
+
from typing import Union
|
|
6
|
+
|
|
7
|
+
DateLike = Union[date, datetime]
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"to_yyddd",
|
|
11
|
+
"from_yyddd",
|
|
12
|
+
"to_cyyddd",
|
|
13
|
+
"from_cyyddd",
|
|
14
|
+
"julian_day",
|
|
15
|
+
"mjd",
|
|
16
|
+
"__version__",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
__version__ = "0.1.0"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _as_date(value: DateLike) -> date:
|
|
23
|
+
if isinstance(value, datetime):
|
|
24
|
+
return value.date()
|
|
25
|
+
if isinstance(value, date):
|
|
26
|
+
return value
|
|
27
|
+
raise TypeError("expected datetime.date or datetime.datetime")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def to_yyddd(value: DateLike) -> str:
|
|
31
|
+
"""Return YYDDD lot code (2-digit year + day-of-year, zero-padded)."""
|
|
32
|
+
d = _as_date(value)
|
|
33
|
+
return f"{d.year % 100:02d}{d.timetuple().tm_yday:03d}"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def from_yyddd(code: str, *, century: int | None = None) -> date:
|
|
37
|
+
"""Parse YYDDD into a date.
|
|
38
|
+
|
|
39
|
+
If ``century`` is omitted, years 00–69 map to 2000–2069 and 70–99 to 1970–1999
|
|
40
|
+
(common manufacturing default). Pass ``century`` as 1900 or 2000 to force it.
|
|
41
|
+
"""
|
|
42
|
+
s = str(code).strip()
|
|
43
|
+
if len(s) != 5 or not s.isdigit():
|
|
44
|
+
raise ValueError("YYDDD must be exactly 5 digits")
|
|
45
|
+
yy, doy = int(s[:2]), int(s[2:])
|
|
46
|
+
if not 1 <= doy <= 366:
|
|
47
|
+
raise ValueError("day-of-year out of range")
|
|
48
|
+
if century is None:
|
|
49
|
+
year = 2000 + yy if yy < 70 else 1900 + yy
|
|
50
|
+
else:
|
|
51
|
+
year = century + yy
|
|
52
|
+
# Validate doy against the year (handles leap)
|
|
53
|
+
try:
|
|
54
|
+
return date.fromordinal(date(year, 1, 1).toordinal() + doy - 1)
|
|
55
|
+
except ValueError as e:
|
|
56
|
+
raise ValueError(f"invalid YYDDD for year {year}") from e
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def to_cyyddd(value: DateLike) -> str:
|
|
60
|
+
"""Return CYYDDD (4-digit year + day-of-year)."""
|
|
61
|
+
d = _as_date(value)
|
|
62
|
+
return f"{d.year:04d}{d.timetuple().tm_yday:03d}"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def from_cyyddd(code: str) -> date:
|
|
66
|
+
"""Parse CYYDDD (YYYYDDD) into a date."""
|
|
67
|
+
s = str(code).strip()
|
|
68
|
+
if len(s) != 7 or not s.isdigit():
|
|
69
|
+
raise ValueError("CYYDDD must be exactly 7 digits")
|
|
70
|
+
year, doy = int(s[:4]), int(s[4:])
|
|
71
|
+
if not 1 <= doy <= 366:
|
|
72
|
+
raise ValueError("day-of-year out of range")
|
|
73
|
+
try:
|
|
74
|
+
return date.fromordinal(date(year, 1, 1).toordinal() + doy - 1)
|
|
75
|
+
except ValueError as e:
|
|
76
|
+
raise ValueError(f"invalid CYYDDD for year {year}") from e
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def julian_day(value: DateLike) -> float:
|
|
80
|
+
"""Astronomical Julian Day number at 0h UTC for the civil date.
|
|
81
|
+
|
|
82
|
+
Uses the standard Fliegel–Van Flandern / USNO civil-to-JD algorithm for
|
|
83
|
+
the Gregorian calendar (noon-based JD; this returns the JD for 00:00 UTC,
|
|
84
|
+
i.e. JD at previous noon + 0.5).
|
|
85
|
+
"""
|
|
86
|
+
d = _as_date(value)
|
|
87
|
+
y, m, day = d.year, d.month, d.day
|
|
88
|
+
# Algorithm for JD at 0h UT (Gregorian)
|
|
89
|
+
a = (14 - m) // 12
|
|
90
|
+
y2 = y + 4800 - a
|
|
91
|
+
m2 = m + 12 * a - 3
|
|
92
|
+
jdn = day + (153 * m2 + 2) // 5 + 365 * y2 + y2 // 4 - y2 // 100 + y2 // 400 - 32045
|
|
93
|
+
# jdn is Julian Day Number at noon; for 0h UT subtract 0.5
|
|
94
|
+
return float(jdn) - 0.5
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def mjd(value: DateLike) -> float:
|
|
98
|
+
"""Modified Julian Day (JD − 2400000.5) at 0h UTC."""
|
|
99
|
+
return julian_day(value) - 2400000.5
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Minimal CLI for yyddd."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
from datetime import date
|
|
6
|
+
|
|
7
|
+
from todayjuliandate import from_cyyddd, from_yyddd, julian_day, mjd, to_cyyddd, to_yyddd
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main(argv: list[str] | None = None) -> int:
|
|
11
|
+
p = argparse.ArgumentParser(prog="todayjuliandate", description="Ordinal / Julian lot-code converter")
|
|
12
|
+
g = p.add_mutually_exclusive_group(required=True)
|
|
13
|
+
g.add_argument("iso_date", nargs="?", help="Gregorian date YYYY-MM-DD")
|
|
14
|
+
g.add_argument("--from-yyddd", dest="yyddd", help="5-digit YYDDD code")
|
|
15
|
+
g.add_argument("--from-cyyddd", dest="cyyddd", help="7-digit CYYDDD code")
|
|
16
|
+
args = p.parse_args(argv)
|
|
17
|
+
|
|
18
|
+
if args.yyddd:
|
|
19
|
+
d = from_yyddd(args.yyddd)
|
|
20
|
+
elif args.cyyddd:
|
|
21
|
+
d = from_cyyddd(args.cyyddd)
|
|
22
|
+
else:
|
|
23
|
+
d = date.fromisoformat(args.iso_date)
|
|
24
|
+
|
|
25
|
+
print(f"date: {d.isoformat()}")
|
|
26
|
+
print(f"YYDDD: {to_yyddd(d)}")
|
|
27
|
+
print(f"CYYDDD: {to_cyyddd(d)}")
|
|
28
|
+
print(f"JD: {julian_day(d)}")
|
|
29
|
+
print(f"MJD: {mjd(d)}")
|
|
30
|
+
return 0
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
if __name__ == "__main__":
|
|
34
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: todayjuliandate
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Today's Julian date helpers: YYDDD / CYYDDD ordinal lot codes, Julian Day (JD), and MJD converters.
|
|
5
|
+
Author: Ordinal Date Notes
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://todayjuliandate.com/
|
|
8
|
+
Project-URL: Documentation, https://todayjuliandate.com/code/
|
|
9
|
+
Project-URL: Live converter, https://todayjuliandate.com/
|
|
10
|
+
Keywords: julian-date,todays-julian-date,ordinal-date,yyddd,cyyddd,mjd,lot-code
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# todayjuliandate
|
|
22
|
+
|
|
23
|
+
Helpers for **today's Julian date** and related ordinal lot codes: YYDDD, CYYDDD, Julian Day (JD), and Modified Julian Day (MJD).
|
|
24
|
+
|
|
25
|
+
Companion library for [todayjuliandate.com](https://todayjuliandate.com/) — converters and code samples for egg-carton / food-lot stamps and calendar math.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install todayjuliandate
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick use
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from datetime import date
|
|
37
|
+
from todayjuliandate import to_yyddd, from_yyddd, to_cyyddd, julian_day, mjd
|
|
38
|
+
|
|
39
|
+
d = date(2024, 7, 1)
|
|
40
|
+
print(to_yyddd(d)) # "24183"
|
|
41
|
+
print(from_yyddd("24183"))
|
|
42
|
+
print(to_cyyddd(d)) # "2024183"
|
|
43
|
+
print(julian_day(d))
|
|
44
|
+
print(mjd(d))
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
CLI:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
todayjuliandate 2024-07-01
|
|
51
|
+
todayjuliandate --from-yyddd 24183
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Sources
|
|
55
|
+
|
|
56
|
+
- [USNO Julian Date](https://aa.usno.navy.mil/data/JulianDate) — astronomical JD definitions
|
|
57
|
+
- [todayjuliandate.com](https://todayjuliandate.com/) — today's Julian date converter and code
|
|
58
|
+
- [NIST time and frequency](https://www.nist.gov/pml/time-and-frequency-division) — civil time context
|
|
59
|
+
|
|
60
|
+
## License
|
|
61
|
+
|
|
62
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/todayjuliandate/__init__.py
|
|
5
|
+
src/todayjuliandate/cli.py
|
|
6
|
+
src/todayjuliandate.egg-info/PKG-INFO
|
|
7
|
+
src/todayjuliandate.egg-info/SOURCES.txt
|
|
8
|
+
src/todayjuliandate.egg-info/dependency_links.txt
|
|
9
|
+
src/todayjuliandate.egg-info/entry_points.txt
|
|
10
|
+
src/todayjuliandate.egg-info/top_level.txt
|
|
11
|
+
tests/test_todayjuliandate.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
todayjuliandate
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from datetime import date
|
|
2
|
+
from todayjuliandate import from_cyyddd, from_yyddd, julian_day, mjd, to_cyyddd, to_yyddd
|
|
3
|
+
|
|
4
|
+
def test_yyddd_roundtrip():
|
|
5
|
+
d = date(2024, 7, 1)
|
|
6
|
+
assert to_yyddd(d) == "24183"
|
|
7
|
+
assert from_yyddd("24183") == d
|
|
8
|
+
|
|
9
|
+
def test_cyyddd():
|
|
10
|
+
d = date(2024, 1, 1)
|
|
11
|
+
assert to_cyyddd(d) == "2024001"
|
|
12
|
+
assert from_cyyddd("2024001") == d
|
|
13
|
+
|
|
14
|
+
def test_jd_known():
|
|
15
|
+
assert julian_day(date(2000, 1, 1)) == 2451544.5
|
|
16
|
+
assert mjd(date(2000, 1, 1)) == 51544.0
|