minimindslab-datetime-window-truncate 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.
- minimindslab_datetime_window_truncate-0.1.0/LICENSE +21 -0
- minimindslab_datetime_window_truncate-0.1.0/PKG-INFO +63 -0
- minimindslab_datetime_window_truncate-0.1.0/README.md +52 -0
- minimindslab_datetime_window_truncate-0.1.0/pyproject.toml +21 -0
- minimindslab_datetime_window_truncate-0.1.0/setup.cfg +4 -0
- minimindslab_datetime_window_truncate-0.1.0/src/minimindslab_datetime_window_truncate/__init__.py +55 -0
- minimindslab_datetime_window_truncate-0.1.0/src/minimindslab_datetime_window_truncate.egg-info/PKG-INFO +63 -0
- minimindslab_datetime_window_truncate-0.1.0/src/minimindslab_datetime_window_truncate.egg-info/SOURCES.txt +9 -0
- minimindslab_datetime_window_truncate-0.1.0/src/minimindslab_datetime_window_truncate.egg-info/dependency_links.txt +1 -0
- minimindslab_datetime_window_truncate-0.1.0/src/minimindslab_datetime_window_truncate.egg-info/top_level.txt +1 -0
- minimindslab_datetime_window_truncate-0.1.0/tests/test_datetime_window_truncate.py +40 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MiniMindsLab
|
|
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,63 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: minimindslab-datetime-window-truncate
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Truncate datetimes to a fixed window size in seconds, minutes, hours, or days with optional timezone-aware handling.
|
|
5
|
+
Author: MiniMindsLab
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Dynamic: license-file
|
|
11
|
+
|
|
12
|
+
# MiniMindsLab Datetime Window Truncate
|
|
13
|
+
|
|
14
|
+
`minimindslab-datetime-window-truncate` provides deterministic datetime bucketing with zero runtime dependencies.
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- Pure Python (standard library only)
|
|
19
|
+
- Python 3.11+
|
|
20
|
+
- Truncate naive or timezone-aware `datetime` values
|
|
21
|
+
- Supports units: `seconds`, `minutes`, `hours`, `days`
|
|
22
|
+
- Deterministic validation errors for invalid input
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install minimindslab-datetime-window-truncate
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from datetime import datetime, timezone
|
|
34
|
+
from minimindslab_datetime_window_truncate import truncate_datetime
|
|
35
|
+
|
|
36
|
+
# Naive datetime
|
|
37
|
+
value = datetime(2024, 1, 2, 3, 4, 5)
|
|
38
|
+
print(truncate_datetime(value, 15, "minutes"))
|
|
39
|
+
# 2024-01-02 03:00:00
|
|
40
|
+
|
|
41
|
+
# Timezone-aware datetime
|
|
42
|
+
aware = datetime(2024, 1, 2, 3, 4, 5, tzinfo=timezone.utc)
|
|
43
|
+
print(truncate_datetime(aware, 1, "hours"))
|
|
44
|
+
# 2024-01-02 03:00:00+00:00
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## API
|
|
48
|
+
|
|
49
|
+
- `truncate_datetime(dt, window_size, unit)`
|
|
50
|
+
|
|
51
|
+
### Parameters
|
|
52
|
+
|
|
53
|
+
- `dt`: `datetime.datetime`
|
|
54
|
+
- `window_size`: positive integer
|
|
55
|
+
- `unit`: one of `"seconds"`, `"minutes"`, `"hours"`, `"days"`
|
|
56
|
+
|
|
57
|
+
### Returns
|
|
58
|
+
|
|
59
|
+
A new `datetime.datetime` truncated (floored) to the requested fixed window in the datetime's own timezone context.
|
|
60
|
+
|
|
61
|
+
## License
|
|
62
|
+
|
|
63
|
+
MIT
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# MiniMindsLab Datetime Window Truncate
|
|
2
|
+
|
|
3
|
+
`minimindslab-datetime-window-truncate` provides deterministic datetime bucketing with zero runtime dependencies.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Pure Python (standard library only)
|
|
8
|
+
- Python 3.11+
|
|
9
|
+
- Truncate naive or timezone-aware `datetime` values
|
|
10
|
+
- Supports units: `seconds`, `minutes`, `hours`, `days`
|
|
11
|
+
- Deterministic validation errors for invalid input
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install minimindslab-datetime-window-truncate
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from datetime import datetime, timezone
|
|
23
|
+
from minimindslab_datetime_window_truncate import truncate_datetime
|
|
24
|
+
|
|
25
|
+
# Naive datetime
|
|
26
|
+
value = datetime(2024, 1, 2, 3, 4, 5)
|
|
27
|
+
print(truncate_datetime(value, 15, "minutes"))
|
|
28
|
+
# 2024-01-02 03:00:00
|
|
29
|
+
|
|
30
|
+
# Timezone-aware datetime
|
|
31
|
+
aware = datetime(2024, 1, 2, 3, 4, 5, tzinfo=timezone.utc)
|
|
32
|
+
print(truncate_datetime(aware, 1, "hours"))
|
|
33
|
+
# 2024-01-02 03:00:00+00:00
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## API
|
|
37
|
+
|
|
38
|
+
- `truncate_datetime(dt, window_size, unit)`
|
|
39
|
+
|
|
40
|
+
### Parameters
|
|
41
|
+
|
|
42
|
+
- `dt`: `datetime.datetime`
|
|
43
|
+
- `window_size`: positive integer
|
|
44
|
+
- `unit`: one of `"seconds"`, `"minutes"`, `"hours"`, `"days"`
|
|
45
|
+
|
|
46
|
+
### Returns
|
|
47
|
+
|
|
48
|
+
A new `datetime.datetime` truncated (floored) to the requested fixed window in the datetime's own timezone context.
|
|
49
|
+
|
|
50
|
+
## License
|
|
51
|
+
|
|
52
|
+
MIT
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77.0.3"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "minimindslab-datetime-window-truncate"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Truncate datetimes to a fixed window size in seconds, minutes, hours, or days with optional timezone-aware handling."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "MiniMindsLab" }
|
|
14
|
+
]
|
|
15
|
+
dependencies = []
|
|
16
|
+
|
|
17
|
+
[tool.setuptools]
|
|
18
|
+
package-dir = {"" = "src"}
|
|
19
|
+
|
|
20
|
+
[tool.setuptools.packages.find]
|
|
21
|
+
where = ["src"]
|
minimindslab_datetime_window_truncate-0.1.0/src/minimindslab_datetime_window_truncate/__init__.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""MiniMindsLab Datetime Window Truncate.
|
|
2
|
+
|
|
3
|
+
Utility for truncating datetimes into fixed windows.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from datetime import datetime, timedelta
|
|
9
|
+
|
|
10
|
+
__all__ = ["truncate_datetime"]
|
|
11
|
+
|
|
12
|
+
_UNIT_SECONDS = {
|
|
13
|
+
"seconds": 1,
|
|
14
|
+
"minutes": 60,
|
|
15
|
+
"hours": 3600,
|
|
16
|
+
"days": 86400,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def truncate_datetime(dt: datetime, window_size: int, unit: str) -> datetime:
|
|
21
|
+
"""Floor a datetime to a fixed-size window.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
dt:
|
|
26
|
+
Input datetime (naive or timezone-aware).
|
|
27
|
+
window_size:
|
|
28
|
+
Positive integer number of units.
|
|
29
|
+
unit:
|
|
30
|
+
One of "seconds", "minutes", "hours", "days".
|
|
31
|
+
|
|
32
|
+
Returns
|
|
33
|
+
-------
|
|
34
|
+
datetime
|
|
35
|
+
A new datetime truncated to the window boundary.
|
|
36
|
+
"""
|
|
37
|
+
if not isinstance(dt, datetime):
|
|
38
|
+
raise TypeError("dt must be a datetime.datetime instance")
|
|
39
|
+
if not isinstance(window_size, int) or isinstance(window_size, bool) or window_size <= 0:
|
|
40
|
+
raise ValueError("window_size must be a positive integer")
|
|
41
|
+
if unit not in _UNIT_SECONDS:
|
|
42
|
+
raise ValueError("unit must be one of: seconds, minutes, hours, days")
|
|
43
|
+
|
|
44
|
+
window_seconds = window_size * _UNIT_SECONDS[unit]
|
|
45
|
+
|
|
46
|
+
if dt.tzinfo is None:
|
|
47
|
+
epoch = datetime(1970, 1, 1)
|
|
48
|
+
else:
|
|
49
|
+
epoch = datetime(1970, 1, 1, tzinfo=dt.tzinfo)
|
|
50
|
+
|
|
51
|
+
delta = dt - epoch
|
|
52
|
+
total_seconds = delta.days * 86400 + delta.seconds
|
|
53
|
+
floored_seconds = (total_seconds // window_seconds) * window_seconds
|
|
54
|
+
|
|
55
|
+
return epoch + timedelta(seconds=floored_seconds)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: minimindslab-datetime-window-truncate
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Truncate datetimes to a fixed window size in seconds, minutes, hours, or days with optional timezone-aware handling.
|
|
5
|
+
Author: MiniMindsLab
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Dynamic: license-file
|
|
11
|
+
|
|
12
|
+
# MiniMindsLab Datetime Window Truncate
|
|
13
|
+
|
|
14
|
+
`minimindslab-datetime-window-truncate` provides deterministic datetime bucketing with zero runtime dependencies.
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- Pure Python (standard library only)
|
|
19
|
+
- Python 3.11+
|
|
20
|
+
- Truncate naive or timezone-aware `datetime` values
|
|
21
|
+
- Supports units: `seconds`, `minutes`, `hours`, `days`
|
|
22
|
+
- Deterministic validation errors for invalid input
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install minimindslab-datetime-window-truncate
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from datetime import datetime, timezone
|
|
34
|
+
from minimindslab_datetime_window_truncate import truncate_datetime
|
|
35
|
+
|
|
36
|
+
# Naive datetime
|
|
37
|
+
value = datetime(2024, 1, 2, 3, 4, 5)
|
|
38
|
+
print(truncate_datetime(value, 15, "minutes"))
|
|
39
|
+
# 2024-01-02 03:00:00
|
|
40
|
+
|
|
41
|
+
# Timezone-aware datetime
|
|
42
|
+
aware = datetime(2024, 1, 2, 3, 4, 5, tzinfo=timezone.utc)
|
|
43
|
+
print(truncate_datetime(aware, 1, "hours"))
|
|
44
|
+
# 2024-01-02 03:00:00+00:00
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## API
|
|
48
|
+
|
|
49
|
+
- `truncate_datetime(dt, window_size, unit)`
|
|
50
|
+
|
|
51
|
+
### Parameters
|
|
52
|
+
|
|
53
|
+
- `dt`: `datetime.datetime`
|
|
54
|
+
- `window_size`: positive integer
|
|
55
|
+
- `unit`: one of `"seconds"`, `"minutes"`, `"hours"`, `"days"`
|
|
56
|
+
|
|
57
|
+
### Returns
|
|
58
|
+
|
|
59
|
+
A new `datetime.datetime` truncated (floored) to the requested fixed window in the datetime's own timezone context.
|
|
60
|
+
|
|
61
|
+
## License
|
|
62
|
+
|
|
63
|
+
MIT
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/minimindslab_datetime_window_truncate/__init__.py
|
|
5
|
+
src/minimindslab_datetime_window_truncate.egg-info/PKG-INFO
|
|
6
|
+
src/minimindslab_datetime_window_truncate.egg-info/SOURCES.txt
|
|
7
|
+
src/minimindslab_datetime_window_truncate.egg-info/dependency_links.txt
|
|
8
|
+
src/minimindslab_datetime_window_truncate.egg-info/top_level.txt
|
|
9
|
+
tests/test_datetime_window_truncate.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
minimindslab_datetime_window_truncate
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from datetime import datetime, timezone, timedelta
|
|
3
|
+
|
|
4
|
+
from minimindslab_datetime_window_truncate import truncate_datetime
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TestTruncateDatetime(unittest.TestCase):
|
|
8
|
+
def test_acceptance_15_minute_window(self):
|
|
9
|
+
dt = datetime(2024, 1, 2, 3, 4, 5)
|
|
10
|
+
result = truncate_datetime(dt, 15, "minutes")
|
|
11
|
+
self.assertEqual(result, datetime(2024, 1, 2, 3, 0, 0))
|
|
12
|
+
|
|
13
|
+
def test_acceptance_timezone_aware_preserves_tz(self):
|
|
14
|
+
tz = timezone(timedelta(hours=5, minutes=30))
|
|
15
|
+
dt = datetime(2024, 1, 2, 3, 4, 5, tzinfo=tz)
|
|
16
|
+
result = truncate_datetime(dt, 1, "hours")
|
|
17
|
+
self.assertEqual(result, datetime(2024, 1, 2, 3, 0, 0, tzinfo=tz))
|
|
18
|
+
self.assertIs(result.tzinfo, tz)
|
|
19
|
+
|
|
20
|
+
def test_acceptance_invalid_unit_raises_value_error(self):
|
|
21
|
+
with self.assertRaises(ValueError):
|
|
22
|
+
truncate_datetime(datetime(2024, 1, 1, 0, 0, 0), 5, "weeks")
|
|
23
|
+
|
|
24
|
+
def test_negative_window_size_validation(self):
|
|
25
|
+
with self.assertRaises(ValueError):
|
|
26
|
+
truncate_datetime(datetime(2024, 1, 1, 0, 0, 0), 0, "minutes")
|
|
27
|
+
|
|
28
|
+
def test_negative_type_validation(self):
|
|
29
|
+
with self.assertRaises(TypeError):
|
|
30
|
+
truncate_datetime("2024-01-01T00:00:00", 1, "minutes")
|
|
31
|
+
|
|
32
|
+
def test_small_importable_api(self):
|
|
33
|
+
import minimindslab_datetime_window_truncate as mod
|
|
34
|
+
|
|
35
|
+
self.assertTrue(hasattr(mod, "truncate_datetime"))
|
|
36
|
+
self.assertEqual(mod.__all__, ["truncate_datetime"])
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
if __name__ == "__main__":
|
|
40
|
+
unittest.main()
|