heliclockter


Nameheliclockter JSON
Version 2.1.0 PyPI version JSON
download
home_pageNone
SummaryA robust way of dealing with datetimes in python by ensuring all datetimes are timezone aware at runtime.
upload_time2025-09-04 09:13:12
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseBSD 3-Clause License Copyright (c) 2022, Channable All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
keywords datetime heliclockter timezone timezones tz tzinfo
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Heliclockter

[![PyPI](https://img.shields.io/pypi/v/heliclockter)](https://pypi.org/project/heliclockter/)
[![License](https://img.shields.io/github/license/channable/heliclockter)](https://github.com/channable/heliclockter/blob/master/LICENSE)
[![Python Versions](https://img.shields.io/pypi/pyversions/heliclockter)](https://pypi.org/project/heliclockter/)

**Timezone-aware datetimes for Python that just work.**

`heliclockter` is a timezone-aware datetime library that ensures your timestamps are always timezone-aware. It's statically type checkable and runtime enforceable.

## Installation

```bash
pip install heliclockter
```

## Quick Start

```python
from heliclockter import datetime_utc, datetime_local, datetime_tz

# UTC datetime
utc_now = datetime_utc.now()
# datetime_utc(2022, 11, 4, 15, 28, 10, 478176, tzinfo=zoneinfo.ZoneInfo(key='UTC'))

# Local timezone datetime  
local_now = datetime_local.now()

# Any timezone datetime
from zoneinfo import ZoneInfo
paris_tz = datetime_tz.now(tz=ZoneInfo("Europe/Paris"))

# Create a timestamp 2 hours in the future
future = datetime_utc.future(hours=2)

# Parse strings (naive timestamps assumed UTC)
parsed = datetime_utc.strptime('2022-11-04T15:49:29', '%Y-%m-%dT%H:%M:%S')
```

## Why heliclockter?

Python's standard `datetime` allows "naive" datetimes without timezone info, leading to bugs when:
- Mixing naive and aware datetimes (causes runtime TypeErrors)
- Deploying across different timezones
- Forgetting to add `tzinfo` when creating datetimes

`heliclockter` enforces timezone-aware datetimes at the type level, catching these issues before production.

## Key Features

- **Always timezone-aware** - No more naive datetime accidents
- **Type safe** - Full typing support for better IDE experience  
- **Zero dependencies** - Lightweight, uses only standard library
- **Pydantic support** - Automatic integration when Pydantic is installed
- **Python 3.10+** - Modern Python for modern applications

## Examples

### Timezone conversions

```python
from heliclockter import datetime_utc, datetime_tz
from zoneinfo import ZoneInfo

# Start with UTC
utc_time = datetime_utc.now()

# To convert to different timezones, create custom classes
class datetime_tokyo(datetime_tz):
    assumed_timezone_for_timezone_naive_input = ZoneInfo('Asia/Tokyo')

class datetime_ny(datetime_tz):
    assumed_timezone_for_timezone_naive_input = ZoneInfo('America/New_York')

# Convert using from_datetime
tokyo_time = datetime_tokyo.from_datetime(utc_time)
ny_time = datetime_ny.from_datetime(utc_time)
```

### Handling naive datetimes

```python
from heliclockter import datetime_utc, datetime_tz
from datetime import datetime

# datetime_utc assumes UTC for naive inputs
naive_dt = datetime(2022, 11, 4, 15, 30, 0)
utc_dt = datetime_utc.from_datetime(naive_dt)  # OK - assumes UTC

# datetime_tz requires explicit timezone
try:
    tz_dt = datetime_tz.from_datetime(naive_dt)  # Raises error
except Exception as e:
    print(e)  # "Cannot create aware datetime from naive if no tz is assumed"
```

### Custom timezone classes

```python
from zoneinfo import ZoneInfo
from heliclockter import datetime_tz

class datetime_cet(datetime_tz):
    """Datetime guaranteed to be in CET timezone."""
    assumed_timezone_for_timezone_naive_input = ZoneInfo('CET')

# Parse naive timestamps as CET
aware_dt = datetime_cet.strptime('2022-11-04T15:49:29', '%Y-%m-%dT%H:%M:%S')
```

### Type safety with mypy

```python
from heliclockter import datetime_utc, datetime_local

def schedule_task(when: datetime_utc) -> None:
    """Schedule a task at a specific UTC time."""
    print(f"Task scheduled for {when.isoformat()}")

# Type checker ensures only UTC datetimes are passed
utc_time = datetime_utc.now()
schedule_task(utc_time)  # ✓ OK

local_time = datetime_local.now()  
schedule_task(local_time)  # ✗ Type error
```

## API Overview

### Core Classes

- **`datetime_tz`** - Base class for timezone-aware datetimes
- **`datetime_utc`** - Always UTC (naive inputs assumed UTC)
- **`datetime_local`** - Always local timezone (naive inputs assumed local)

### Key Methods

- `now()` - Current time
- `from_datetime()` - Convert from standard datetime
- `strptime()` - Parse string to datetime
- `future()/past()` - Create relative timestamps
- `astimezone()` - Convert to other timezone   

## About the Name

`heliclockter` is a portmanteau of "clock" and "helicopter". Like a [helicopter parent](https://en.wikipedia.org/wiki/Helicopter_parent), it strictly supervises your datetime handling, ensuring you never make timezone mistakes.

## Contributing

We welcome contributions! See [CONTRIBUTING.md](https://github.com/channable/heliclockter/blob/master/CONTRIBUTING.md).

## License

BSD 3-Clause License. See [LICENSE](https://github.com/channable/heliclockter/blob/master/LICENSE).

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "heliclockter",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "datetime, heliclockter, timezone, timezones, tz, tzinfo",
    "author": null,
    "author_email": "Peter Nilsson <peter.nilsson@channable.com>",
    "download_url": "https://files.pythonhosted.org/packages/80/1e/ce7ce66569b38cf6636ea33d000220874f82f5224717b56e65e0e348a920/heliclockter-2.1.0.tar.gz",
    "platform": null,
    "description": "# Heliclockter\n\n[![PyPI](https://img.shields.io/pypi/v/heliclockter)](https://pypi.org/project/heliclockter/)\n[![License](https://img.shields.io/github/license/channable/heliclockter)](https://github.com/channable/heliclockter/blob/master/LICENSE)\n[![Python Versions](https://img.shields.io/pypi/pyversions/heliclockter)](https://pypi.org/project/heliclockter/)\n\n**Timezone-aware datetimes for Python that just work.**\n\n`heliclockter` is a timezone-aware datetime library that ensures your timestamps are always timezone-aware. It's statically type checkable and runtime enforceable.\n\n## Installation\n\n```bash\npip install heliclockter\n```\n\n## Quick Start\n\n```python\nfrom heliclockter import datetime_utc, datetime_local, datetime_tz\n\n# UTC datetime\nutc_now = datetime_utc.now()\n# datetime_utc(2022, 11, 4, 15, 28, 10, 478176, tzinfo=zoneinfo.ZoneInfo(key='UTC'))\n\n# Local timezone datetime  \nlocal_now = datetime_local.now()\n\n# Any timezone datetime\nfrom zoneinfo import ZoneInfo\nparis_tz = datetime_tz.now(tz=ZoneInfo(\"Europe/Paris\"))\n\n# Create a timestamp 2 hours in the future\nfuture = datetime_utc.future(hours=2)\n\n# Parse strings (naive timestamps assumed UTC)\nparsed = datetime_utc.strptime('2022-11-04T15:49:29', '%Y-%m-%dT%H:%M:%S')\n```\n\n## Why heliclockter?\n\nPython's standard `datetime` allows \"naive\" datetimes without timezone info, leading to bugs when:\n- Mixing naive and aware datetimes (causes runtime TypeErrors)\n- Deploying across different timezones\n- Forgetting to add `tzinfo` when creating datetimes\n\n`heliclockter` enforces timezone-aware datetimes at the type level, catching these issues before production.\n\n## Key Features\n\n- **Always timezone-aware** - No more naive datetime accidents\n- **Type safe** - Full typing support for better IDE experience  \n- **Zero dependencies** - Lightweight, uses only standard library\n- **Pydantic support** - Automatic integration when Pydantic is installed\n- **Python 3.10+** - Modern Python for modern applications\n\n## Examples\n\n### Timezone conversions\n\n```python\nfrom heliclockter import datetime_utc, datetime_tz\nfrom zoneinfo import ZoneInfo\n\n# Start with UTC\nutc_time = datetime_utc.now()\n\n# To convert to different timezones, create custom classes\nclass datetime_tokyo(datetime_tz):\n    assumed_timezone_for_timezone_naive_input = ZoneInfo('Asia/Tokyo')\n\nclass datetime_ny(datetime_tz):\n    assumed_timezone_for_timezone_naive_input = ZoneInfo('America/New_York')\n\n# Convert using from_datetime\ntokyo_time = datetime_tokyo.from_datetime(utc_time)\nny_time = datetime_ny.from_datetime(utc_time)\n```\n\n### Handling naive datetimes\n\n```python\nfrom heliclockter import datetime_utc, datetime_tz\nfrom datetime import datetime\n\n# datetime_utc assumes UTC for naive inputs\nnaive_dt = datetime(2022, 11, 4, 15, 30, 0)\nutc_dt = datetime_utc.from_datetime(naive_dt)  # OK - assumes UTC\n\n# datetime_tz requires explicit timezone\ntry:\n    tz_dt = datetime_tz.from_datetime(naive_dt)  # Raises error\nexcept Exception as e:\n    print(e)  # \"Cannot create aware datetime from naive if no tz is assumed\"\n```\n\n### Custom timezone classes\n\n```python\nfrom zoneinfo import ZoneInfo\nfrom heliclockter import datetime_tz\n\nclass datetime_cet(datetime_tz):\n    \"\"\"Datetime guaranteed to be in CET timezone.\"\"\"\n    assumed_timezone_for_timezone_naive_input = ZoneInfo('CET')\n\n# Parse naive timestamps as CET\naware_dt = datetime_cet.strptime('2022-11-04T15:49:29', '%Y-%m-%dT%H:%M:%S')\n```\n\n### Type safety with mypy\n\n```python\nfrom heliclockter import datetime_utc, datetime_local\n\ndef schedule_task(when: datetime_utc) -> None:\n    \"\"\"Schedule a task at a specific UTC time.\"\"\"\n    print(f\"Task scheduled for {when.isoformat()}\")\n\n# Type checker ensures only UTC datetimes are passed\nutc_time = datetime_utc.now()\nschedule_task(utc_time)  # \u2713 OK\n\nlocal_time = datetime_local.now()  \nschedule_task(local_time)  # \u2717 Type error\n```\n\n## API Overview\n\n### Core Classes\n\n- **`datetime_tz`** - Base class for timezone-aware datetimes\n- **`datetime_utc`** - Always UTC (naive inputs assumed UTC)\n- **`datetime_local`** - Always local timezone (naive inputs assumed local)\n\n### Key Methods\n\n- `now()` - Current time\n- `from_datetime()` - Convert from standard datetime\n- `strptime()` - Parse string to datetime\n- `future()/past()` - Create relative timestamps\n- `astimezone()` - Convert to other timezone   \n\n## About the Name\n\n`heliclockter` is a portmanteau of \"clock\" and \"helicopter\". Like a [helicopter parent](https://en.wikipedia.org/wiki/Helicopter_parent), it strictly supervises your datetime handling, ensuring you never make timezone mistakes.\n\n## Contributing\n\nWe welcome contributions! See [CONTRIBUTING.md](https://github.com/channable/heliclockter/blob/master/CONTRIBUTING.md).\n\n## License\n\nBSD 3-Clause License. See [LICENSE](https://github.com/channable/heliclockter/blob/master/LICENSE).\n",
    "bugtrack_url": null,
    "license": "BSD 3-Clause License\n        \n        Copyright (c) 2022, Channable\n        All rights reserved.\n        \n        Redistribution and use in source and binary forms, with or without\n        modification, are permitted provided that the following conditions are met:\n        \n        * Redistributions of source code must retain the above copyright notice, this\n          list of conditions and the following disclaimer.\n        \n        * Redistributions in binary form must reproduce the above copyright notice,\n          this list of conditions and the following disclaimer in the documentation\n          and/or other materials provided with the distribution.\n        \n        * Neither the name of the copyright holder nor the names of its\n          contributors may be used to endorse or promote products derived from\n          this software without specific prior written permission.\n        \n        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n        AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n        IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n        DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n        FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n        DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n        SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n        CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n        OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n        OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n        ",
    "summary": "A robust way of dealing with datetimes in python by ensuring all datetimes are timezone aware at runtime.",
    "version": "2.1.0",
    "project_urls": {
        "Homepage": "https://github.com/channable/heliclockter"
    },
    "split_keywords": [
        "datetime",
        " heliclockter",
        " timezone",
        " timezones",
        " tz",
        " tzinfo"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "21d03307b2ebbf217f4528cb1f7b5883ea2a750ef27ba93852b6b95fe494b5de",
                "md5": "0b8dcbfd24c6812bf6c2a5350d7729f2",
                "sha256": "36a9e00d02519962bb45019a75c62f28cb4c03af2ca74e0d0527a910e0117367"
            },
            "downloads": -1,
            "filename": "heliclockter-2.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "0b8dcbfd24c6812bf6c2a5350d7729f2",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 7871,
            "upload_time": "2025-09-04T09:13:10",
            "upload_time_iso_8601": "2025-09-04T09:13:10.735069Z",
            "url": "https://files.pythonhosted.org/packages/21/d0/3307b2ebbf217f4528cb1f7b5883ea2a750ef27ba93852b6b95fe494b5de/heliclockter-2.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "801ece7ce66569b38cf6636ea33d000220874f82f5224717b56e65e0e348a920",
                "md5": "75c79e05f38287d22c8b9ba02268b1ac",
                "sha256": "6eeaf88aaa1054c0227f351684b28b6cd7810f0708c31abac36e10c1352109b9"
            },
            "downloads": -1,
            "filename": "heliclockter-2.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "75c79e05f38287d22c8b9ba02268b1ac",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 18682,
            "upload_time": "2025-09-04T09:13:12",
            "upload_time_iso_8601": "2025-09-04T09:13:12.067442Z",
            "url": "https://files.pythonhosted.org/packages/80/1e/ce7ce66569b38cf6636ea33d000220874f82f5224717b56e65e0e348a920/heliclockter-2.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-04 09:13:12",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "channable",
    "github_project": "heliclockter",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "heliclockter"
}
        
Elapsed time: 0.50631s