diff --git a/docs/cli.rst b/docs/cli.rst index 5c3bd7e..ad88f4c 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -178,6 +178,16 @@ to change are supplied: :: $ ytpb download -i 2024-01-02T10:20:00+00/T25M30S ... +*Unix timestamp* +^^^^^^^^^^^^^^^^ + +* ``--interval /`` + +where `` = "@"``: + +The date and time interval can also be specified with Unix timestamps as: :: + + $ ytpb download -i @1704190800/@1704190830 ... *'Now' keyword* ^^^^^^^^^^^^^^^ @@ -267,21 +277,22 @@ Compatibility table .. table:: **Table:** Interval parts compatibility - +----------------------+---------------+------+----------+----------------------+-----------------+-------------+ - | | Date and time | Time | Duration | Replacing components | Sequence number | 'Now', '..' | - +======================+===============+======+==========+======================+=================+=============+ - | Date and time | Y | Y | Y | Y | Y | Y | - +----------------------+---------------+------+----------+----------------------+-----------------+-------------+ - | Time | Y | Y | Y | *N* | Y | Y | - +----------------------+---------------+------+----------+----------------------+-----------------+-------------+ - | Duration | Y | Y | *N* | *N* | Y | *N* | - +----------------------+---------------+------+----------+----------------------+-----------------+-------------+ - | Replacing components | Y | *N* | *N* | *N* | *N* | *N* | - +----------------------+---------------+------+----------+----------------------+-----------------+-------------+ - | Sequence number | Y | Y | Y | *N* | Y | Y | - +----------------------+---------------+------+----------+----------------------+-----------------+-------------+ - | 'Now', '..' | Y | Y | *N* | *N* | Y | *N* | - +----------------------+---------------+------+----------+----------------------+-----------------+-------------+ + +---------------------------+---------------+------+----------+----------------------+-----------------+-------------+ + | | Date and time | Time | Duration | Replacing components | Sequence number | 'Now', '..' | + | | / Timestamp | | | | | | + +===========================+===============+======+==========+======================+=================+=============+ + | Date and time / Timestamp | Y | Y | Y | Y | Y | Y | + +---------------------------+---------------+------+----------+----------------------+-----------------+-------------+ + | Time | Y | Y | Y | *N* | Y | Y | + +---------------------------+---------------+------+----------+----------------------+-----------------+-------------+ + | Duration | Y | Y | *N* | *N* | Y | *N* | + +---------------------------+---------------+------+----------+----------------------+-----------------+-------------+ + | Replacing components | Y | *N* | *N* | *N* | *N* | *N* | + +---------------------------+---------------+------+----------+----------------------+-----------------+-------------+ + | Sequence number | Y | Y | Y | *N* | Y | Y | + +---------------------------+---------------+------+----------+----------------------+-----------------+-------------+ + | 'Now', '..' | Y | Y | *N* | *N* | Y | *N* | + +---------------------------+---------------+------+----------+----------------------+-----------------+-------------+ Specifying formats ================== diff --git a/src/ytpb/cli/parameters.py b/src/ytpb/cli/parameters.py index a566e63..0a71146 100644 --- a/src/ytpb/cli/parameters.py +++ b/src/ytpb/cli/parameters.py @@ -1,4 +1,4 @@ -from datetime import datetime, time, timedelta +from datetime import datetime, time, timedelta, timezone from enum import auto, StrEnum from typing import Literal, NamedTuple @@ -47,6 +47,12 @@ def convert(self, value: str, param, ctx) -> types.AbsolutePointInStream | str: except ValueError: message = f"'{value}' does not match ISO 8601 date format." self.fail(message, param, ctx) + # Unix timestamp + case value if value.startswith("@"): + timestamp = float(value.lstrip("@")) + output = ensure_date_aware( + datetime.fromtimestamp(timestamp, timezone.utc) + ) case _: self.fail("Option doesn't allow '{}' value", param, ctx) return output @@ -106,6 +112,10 @@ def _parse_interval_part( # Date and time case x if "T" in x: output = datetime.fromisoformat(x) + # Unix timestamp + case x if x.startswith("@"): + timestamp = float(x.lstrip("@")) + output = datetime.fromtimestamp(timestamp, timezone.utc) case "now" | ".." as x: output = x case _: diff --git a/tests/cli/test_parameters.py b/tests/cli/test_parameters.py index 8d12992..e6244ad 100644 --- a/tests/cli/test_parameters.py +++ b/tests/cli/test_parameters.py @@ -86,6 +86,13 @@ def test_format_spec_with_function(): "20240102T102000+00/..", (datetime(2024, 1, 2, 10, 20, tzinfo=timezone.utc), ".."), ), + ( + "@1704190800/@1704190830.123", + ( + datetime(2024, 1, 2, 10, 20, 0, tzinfo=timezone.utc), + datetime(2024, 1, 2, 10, 20, 30, 123000, tzinfo=timezone.utc), + ), + ), ], ) def test_rewind_interval(value: str, expected):