httpdate


Namehttpdate JSON
Version 1.2.0 PyPI version JSON
download
home_page
SummaryParse and format HTTP dates, such as Last-Modified and If-Modified-Since headers.
upload_time2023-04-09 19:09:50
maintainer
docs_urlNone
author
requires_python>=3.7
license
keywords if-modified-since last-modified lastmodified rfc9110
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # httpdate

[![PyPi Version][pypi-img]][pypi-url]
[![License][license-img]][license-url]
[![Continuous Integration][ci-img]][ci-url]
[![Code Coverage][coverage-img]][coverage-url]
[![Python Versions][python-img]][python-url]

[pypi-img]: https://img.shields.io/pypi/v/httpdate.svg
[pypi-url]: https://pypi.org/project/httpdate
[license-img]:  https://img.shields.io/github/license/jamielinux/httpdate.svg
[license-url]: https://github.com/jamielinux/httpdate/blob/main/LICENSE
[ci-img]: https://github.com/jamielinux/httpdate/actions/workflows/ci.yml/badge.svg
[ci-url]: https://github.com/jamielinux/httpdate/actions/workflows/ci.yml
[coverage-img]: https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/jamielinux/f3b70fb7174f1a8a87f2185e80cbb2ef/raw/httpdate.covbadge.json
[coverage-url]: https://github.com/jamielinux/httpdate/actions/workflows/ci.yml
[python-img]: https://img.shields.io/pypi/pyversions/httpdate.svg
[python-url]: https://pypi.org/project/httpdate

---

**httpdate** is a Python library for parsing and formatting HTTP date fields that are
used in headers like `Last-Modified` and `If-Modified-Since`. It does so in strict
accordance with [RFC 9110 Section 5.6.7][0].

It has only one dependency, which is my tiny [leapseconds][1] library that just provides
a tuple of official leap seconds.

[0]: https://datatracker.ietf.org/doc/html/rfc9110#section-5.6.7
[1]: https://github.com/jamielinux/leapseconds

## HTTP date formats

All HTTP dates (eg, in `Last-Modified` headers) must be sent in this format:

```console
# IMF-fixdate
Sun, 06 Nov 1994 08:49:37 GMT
```

However, RFC 9110 states that recipients must also accept two other obsolete formats:

```console
# rfc850-date
Sunday, 06-Nov-94 08:49:37 GMT

# asctime-date
Sun Nov  6 08:49:37 1994
```

RFC 9110 criteria for the HTTP date field includes the following:

- It must represent time as an instance of UTC.
- It must represent weekday names and month names in English.
- It is case-sensitive.
- It must not have any additional whitespace.
- It must be semantically correct (eg, the weekday must be the correct weekday).
- It can include leap seconds (eg, `23:59:60`).
- It must represent a year of `1900` or above.

It isn't stated explicitly in the RFCs, but `httpdate` will only consider a leap second
semantically correct if it's an [official leap second][2].

[2]: https://www.ietf.org/timezones/data/leap-seconds.list

## Installation

```console
pip install httpdate
```

## Usage

```python
from httpdate import is_valid_httpdate, httpdate_to_unixtime, unixtime_to_httpdate

# Check if an HTTP date (eg, `Last-Modified` header) is valid:
is_valid_httpdate("Sun, 06 Nov 1994 08:49:37 GMT")

try:
    # Parse an HTTP date:
    httpdate_to_unixtime("Sun, 06 Nov 1994 08:49:37 GMT")
    # Parse an HTTP date (rfc850-date):
    httpdate_to_unixtime("Sunday, 06-Nov-94 08:49:37 GMT")
    # Parse an HTTP date (asctime-date):
    httpdate_to_unixtime("Sun Nov  6 08:49:37 1994")
except ValueError:
    # Not a valid HTTP date string.
    pass

# Format a Unix timestamp as an HTTP date:
try:
    unixtime_to_httpdate(784111777)
except ValueError:
    # Outside the range supported by the operating system.
    pass
```

- **`is_valid_httpdate(httpdate)`**:
  - *Args*
    - `httpdate (str)`: An HTTP date string.
  - *Returns*
    - `bool`: True if `httpdate` is a valid HTTP date string, otherwise False.
  - *Raises*
    - `TypeError` if `httpdate` is not of type `str`.
- **`httpdate_to_unixtime(httpdate)`**:
  - *Args*
    - `httpdate (str)`: An HTTP date string.
  - *Returns*
    - `int`: A Unix timestamp (`int`).
  - *Raises*
    - `TypeError` if `httpdate` is not of type `str`.
    - `ValueError` if `httpdate` is not a valid HTTP date string.
- **`unixtime_to_httpdate(unixtime)`**:
  - *Args*
    - `unixtime (int)`: A Unix timestamp.
  - *Returns*
    - `str`: An HTTP date string.
  - *Raises*
    - `TypeError` if `unixtime` is not of type `int`.
    - `ValueError` if `unixtime` represents a year before 1900, or if it is outside
      the range supported by the operating system.

## Why Unix timestamps?

Unix timestamps are unambiguous, efficient, and can easily be converted to other
date-time formats using only the standard library.

When a `Last-Modified` header is semantically correct, this conversion — from string to
Unix timestamp and back to string — is lossless. (The only exception is leap seconds;
for example `Sat, 31 Dec 2016 23:59:60 GMT` would be returned as `Sun, 01 Jan 2017
00:00:00 GMT`. Recipients should interpret these as being identical anyway.)

If you want to store the original string instead, just use `is_valid_httpdate()` to
validate before storing.

## License

`httpdate` is distributed under the terms of the [MIT][license] license.

[license]: https://spdx.org/licenses/MIT.html

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "httpdate",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "if-modified-since,last-modified,lastmodified,rfc9110",
    "author": "",
    "author_email": "Jamie Nguyen <j@jamielinux.com>",
    "download_url": "https://files.pythonhosted.org/packages/5d/8b/d7b18d45eeee13964c4bda9eb2dd7921fa9cd3ae4f9d1373eaff8b753dd0/httpdate-1.2.0.tar.gz",
    "platform": null,
    "description": "# httpdate\n\n[![PyPi Version][pypi-img]][pypi-url]\n[![License][license-img]][license-url]\n[![Continuous Integration][ci-img]][ci-url]\n[![Code Coverage][coverage-img]][coverage-url]\n[![Python Versions][python-img]][python-url]\n\n[pypi-img]: https://img.shields.io/pypi/v/httpdate.svg\n[pypi-url]: https://pypi.org/project/httpdate\n[license-img]:  https://img.shields.io/github/license/jamielinux/httpdate.svg\n[license-url]: https://github.com/jamielinux/httpdate/blob/main/LICENSE\n[ci-img]: https://github.com/jamielinux/httpdate/actions/workflows/ci.yml/badge.svg\n[ci-url]: https://github.com/jamielinux/httpdate/actions/workflows/ci.yml\n[coverage-img]: https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/jamielinux/f3b70fb7174f1a8a87f2185e80cbb2ef/raw/httpdate.covbadge.json\n[coverage-url]: https://github.com/jamielinux/httpdate/actions/workflows/ci.yml\n[python-img]: https://img.shields.io/pypi/pyversions/httpdate.svg\n[python-url]: https://pypi.org/project/httpdate\n\n---\n\n**httpdate** is a Python library for parsing and formatting HTTP date fields that are\nused in headers like `Last-Modified` and `If-Modified-Since`. It does so in strict\naccordance with [RFC 9110 Section 5.6.7][0].\n\nIt has only one dependency, which is my tiny [leapseconds][1] library that just provides\na tuple of official leap seconds.\n\n[0]: https://datatracker.ietf.org/doc/html/rfc9110#section-5.6.7\n[1]: https://github.com/jamielinux/leapseconds\n\n## HTTP date formats\n\nAll HTTP dates (eg, in `Last-Modified` headers) must be sent in this format:\n\n```console\n# IMF-fixdate\nSun, 06 Nov 1994 08:49:37 GMT\n```\n\nHowever, RFC 9110 states that recipients must also accept two other obsolete formats:\n\n```console\n# rfc850-date\nSunday, 06-Nov-94 08:49:37 GMT\n\n# asctime-date\nSun Nov  6 08:49:37 1994\n```\n\nRFC 9110 criteria for the HTTP date field includes the following:\n\n- It must represent time as an instance of UTC.\n- It must represent weekday names and month names in English.\n- It is case-sensitive.\n- It must not have any additional whitespace.\n- It must be semantically correct (eg, the weekday must be the correct weekday).\n- It can include leap seconds (eg, `23:59:60`).\n- It must represent a year of `1900` or above.\n\nIt isn't stated explicitly in the RFCs, but `httpdate` will only consider a leap second\nsemantically correct if it's an [official leap second][2].\n\n[2]: https://www.ietf.org/timezones/data/leap-seconds.list\n\n## Installation\n\n```console\npip install httpdate\n```\n\n## Usage\n\n```python\nfrom httpdate import is_valid_httpdate, httpdate_to_unixtime, unixtime_to_httpdate\n\n# Check if an HTTP date (eg, `Last-Modified` header) is valid:\nis_valid_httpdate(\"Sun, 06 Nov 1994 08:49:37 GMT\")\n\ntry:\n    # Parse an HTTP date:\n    httpdate_to_unixtime(\"Sun, 06 Nov 1994 08:49:37 GMT\")\n    # Parse an HTTP date (rfc850-date):\n    httpdate_to_unixtime(\"Sunday, 06-Nov-94 08:49:37 GMT\")\n    # Parse an HTTP date (asctime-date):\n    httpdate_to_unixtime(\"Sun Nov  6 08:49:37 1994\")\nexcept ValueError:\n    # Not a valid HTTP date string.\n    pass\n\n# Format a Unix timestamp as an HTTP date:\ntry:\n    unixtime_to_httpdate(784111777)\nexcept ValueError:\n    # Outside the range supported by the operating system.\n    pass\n```\n\n- **`is_valid_httpdate(httpdate)`**:\n  - *Args*\n    - `httpdate (str)`: An HTTP date string.\n  - *Returns*\n    - `bool`: True if `httpdate` is a valid HTTP date string, otherwise False.\n  - *Raises*\n    - `TypeError` if `httpdate` is not of type `str`.\n- **`httpdate_to_unixtime(httpdate)`**:\n  - *Args*\n    - `httpdate (str)`: An HTTP date string.\n  - *Returns*\n    - `int`: A Unix timestamp (`int`).\n  - *Raises*\n    - `TypeError` if `httpdate` is not of type `str`.\n    - `ValueError` if `httpdate` is not a valid HTTP date string.\n- **`unixtime_to_httpdate(unixtime)`**:\n  - *Args*\n    - `unixtime (int)`: A Unix timestamp.\n  - *Returns*\n    - `str`: An HTTP date string.\n  - *Raises*\n    - `TypeError` if `unixtime` is not of type `int`.\n    - `ValueError` if `unixtime` represents a year before 1900, or if it is outside\n      the range supported by the operating system.\n\n## Why Unix timestamps?\n\nUnix timestamps are unambiguous, efficient, and can easily be converted to other\ndate-time formats using only the standard library.\n\nWhen a `Last-Modified` header is semantically correct, this conversion \u2014 from string to\nUnix timestamp and back to string \u2014 is lossless. (The only exception is leap seconds;\nfor example `Sat, 31 Dec 2016 23:59:60 GMT` would be returned as `Sun, 01 Jan 2017\n00:00:00 GMT`. Recipients should interpret these as being identical anyway.)\n\nIf you want to store the original string instead, just use `is_valid_httpdate()` to\nvalidate before storing.\n\n## License\n\n`httpdate` is distributed under the terms of the [MIT][license] license.\n\n[license]: https://spdx.org/licenses/MIT.html\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "Parse and format HTTP dates, such as Last-Modified and If-Modified-Since headers.",
    "version": "1.2.0",
    "split_keywords": [
        "if-modified-since",
        "last-modified",
        "lastmodified",
        "rfc9110"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e2b7bebe9e60e89b38b4f0b57e152e7bb69d0d4f1b84c190487f528d38e7f5e2",
                "md5": "f813314bbcef6f6ce0857160906143a7",
                "sha256": "d383a5345a32d8115ab0ff333e6522690b4ce7474efc81598dda91dd41713a0a"
            },
            "downloads": -1,
            "filename": "httpdate-1.2.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "f813314bbcef6f6ce0857160906143a7",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 8999,
            "upload_time": "2023-04-09T19:09:48",
            "upload_time_iso_8601": "2023-04-09T19:09:48.713787Z",
            "url": "https://files.pythonhosted.org/packages/e2/b7/bebe9e60e89b38b4f0b57e152e7bb69d0d4f1b84c190487f528d38e7f5e2/httpdate-1.2.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5d8bd7b18d45eeee13964c4bda9eb2dd7921fa9cd3ae4f9d1373eaff8b753dd0",
                "md5": "bd8bb9a8f55fa68a3ea3192f7b30bf95",
                "sha256": "6193785e6f195c080a8c2aee1c74cbffb02000be4e69b22cc6e8171a5c5783f4"
            },
            "downloads": -1,
            "filename": "httpdate-1.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "bd8bb9a8f55fa68a3ea3192f7b30bf95",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 10839,
            "upload_time": "2023-04-09T19:09:50",
            "upload_time_iso_8601": "2023-04-09T19:09:50.205039Z",
            "url": "https://files.pythonhosted.org/packages/5d/8b/d7b18d45eeee13964c4bda9eb2dd7921fa9cd3ae4f9d1373eaff8b753dd0/httpdate-1.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-04-09 19:09:50",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "lcname": "httpdate"
}
        
Elapsed time: 0.32213s