Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions docs/tool-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,12 @@ other whitespace is significant. Empty input is supported.

`value` is a string. `to_iso` accepts Unix **seconds**, including fractions and
negative values. `to_unix` accepts an ISO 8601 date/time with `Z` or a UTC offset.
Both return `unix_seconds` and `iso_utc`. For example,
`convert_timestamp("1970-01-01T05:30:00+05:30", "to_unix")` returns zero seconds.
Both return `unix_seconds`, `iso_utc`, and `weekday_utc`, the English weekday name
of the converted UTC date. For example,
`convert_timestamp("1970-01-01T05:30:00+05:30", "to_unix")` returns zero seconds,
and `convert_timestamp("1970-01-02T00:30:00+01:00", "to_unix")` is Thursday in UTC
even though the input's local date is Friday. A fixed Monday-to-Sunday list is used,
so the name does not depend on the machine's locale.
Timezone-less dates are rejected so results do not depend on the machine's timezone.
Python datetime's year range (1–9999) and microsecond precision apply; finer fractional
seconds may be rounded. Invalid, infinite, or out-of-range values raise `ValueError`.
Expand Down
11 changes: 10 additions & 1 deletion src/mcp_tools_lab/tools/timestamps.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@
from datetime import datetime, timedelta, timezone
from typing import Literal

# A fixed list keeps the name in English whatever the machine's locale is.
WEEKDAYS = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")


def convert_timestamp(value: str, direction: Literal["to_iso", "to_unix"] = "to_iso") -> dict:
"""Convert Unix seconds to UTC ISO 8601, or an offset-aware ISO date to seconds.

ISO input must include a time and timezone, such as 2026-01-01T12:00:00+05:30.

weekday_utc is the English weekday name of the converted UTC date.
"""
epoch = datetime(1970, 1, 1, tzinfo=timezone.utc)
try:
Expand All @@ -27,4 +32,8 @@ def convert_timestamp(value: str, direction: Literal["to_iso", "to_unix"] = "to_
raise ValueError("direction must be to_iso or to_unix.")
except (ValueError, OverflowError) as error:
raise ValueError(f"Cannot convert timestamp: {error}") from error
return {"unix_seconds": seconds, "iso_utc": date.isoformat().replace("+00:00", "Z")}
return {
"unix_seconds": seconds,
"iso_utc": date.isoformat().replace("+00:00", "Z"),
"weekday_utc": WEEKDAYS[date.weekday()],
}
20 changes: 20 additions & 0 deletions tests/test_timestamps.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,23 @@ def test_fractional_and_negative_seconds():
def test_invalid_input(value, direction):
with pytest.raises(ValueError, match="Cannot convert"):
convert_timestamp(value, direction)


def test_weekday_utc_for_known_days():
assert convert_timestamp("0")["weekday_utc"] == "Thursday"
assert convert_timestamp("345600")["weekday_utc"] == "Monday"
assert convert_timestamp("1970-01-04T00:00:00Z", "to_unix")["weekday_utc"] == "Sunday"


def test_weekday_utc_uses_utc_not_the_inputs_local_date():
result = convert_timestamp("1970-01-02T00:30:00+01:00", "to_unix")
assert result["iso_utc"] == "1970-01-01T23:30:00Z"
assert result["weekday_utc"] == "Thursday"


def test_weekday_utc_for_negative_timestamp():
assert convert_timestamp("-0.5")["weekday_utc"] == "Wednesday"


def test_weekday_utc_in_both_directions():
assert convert_timestamp("0")["weekday_utc"] == convert_timestamp("1970-01-01T00:00:00Z", "to_unix")["weekday_utc"]
Loading