gamesheet_sdk.common.cli.game_times module

Start/end/duration resolution shared by the admin and teams game commands.

Both CLIs accept the same seven time options (--start-datetime/--start-date-time/--start, --end-datetime/--end-date-time/--end, --start-date/--date, --start-time, --end-date, --end-time, --duration) and resolve them identically here. Only the final wire format differs: gamesheet-admin sends the ISO 8601 pair returned by these helpers verbatim, while gamesheet-teams reformats it into its YYYY-MM-DDTHH:MM + HH:MM pair.

A bare --end-time (no --end-date) inherits the resolved start date, which is what makes --date 2026-07-04 --start-time 7pm --end-time 9pm mean the same thing on both CLIs.

gamesheet_sdk.common.cli.game_times.build_raw_end(date_time, date, time, date_prefix)[source]

Merge the three end spellings into a single parseable string.

A bare --end-time is paired with date_prefix — normally the resolved start date — so an end time without an explicit end date lands on the same day as the start.

Parameters:
  • date_time (str | None) – Combined --end-datetime value.

  • date (str | None) – --end-date value.

  • time (str | None) – --end-time value.

  • date_prefix (str | None) – Date to pair a bare time with.

Returns:

str | None – A string for parse_flexible_datetime(), or None if nothing was supplied.

Return type:

str | None

gamesheet_sdk.common.cli.game_times.build_raw_start(date_time, date, time, fallback_date=None)[source]

Merge the three start spellings into a single parseable string.

Parameters:
  • date_time (str | None) – Combined --start-datetime value.

  • date (str | None) – --start-date / --date value.

  • time (str | None) – --start-time value.

  • fallback_date (str | None) – Date to pair a bare time with (the game’s current date, on update).

Returns:

str | None – A string for parse_flexible_datetime(), or None if nothing was supplied.

Return type:

str | None

gamesheet_sdk.common.cli.game_times.extract_date_prefix(raw)[source]

Return the YYYY-MM-DD prefix of a datetime string, if one can be recovered.

Parameters:

raw (str | None) – A datetime-ish string, or None.

Returns:

str | None – The date portion, or None when it cannot be determined.

Return type:

str | None

gamesheet_sdk.common.cli.game_times.is_bare_time(value)[source]

Return whether a value is a time of day with no date attached.

--start / --end are the flexible spellings and accept either form. Recognizing the bare-time case is what lets --date 2026-08-20 --start 12:00 --end 13:15 keep working: the time-only value is folded into the split date/time slot instead of colliding with --date.

Parameters:

value (str | None) – The supplied value.

Returns:

boolTrue when the value looks like a time of day and nothing else.

Return type:

bool

gamesheet_sdk.common.cli.game_times.parse_duration_minutes(raw)[source]

Parse a duration in any of the spellings both CLIs accept.

gamesheet-admin historically took an integer count of minutes and gamesheet-teams a suffixed string; both spellings now work everywhere. A value that cannot be interpreted raises click.UsageError from _parse_duration_text().

Parameters:

raw (str | int | None) – Duration as minutes (75), a suffixed string ('1h15m', '90m', '1.5h'), a H:MM string ('1:15'), or None.

Returns:

int | None – Duration in whole minutes, or None when raw is None or blank.

Return type:

int | None

gamesheet_sdk.common.cli.game_times.resolve_game_window(start_date_time, start_date, start_time, end_date_time, end_date, end_time, duration)[source]

Resolve create-time inputs into an ISO 8601 start/end pair.

Exactly two of start, end, and duration are required; the third is calculated. Supplying all three is allowed as long as they agree.

Parameters:
  • start_date_time (str | None) – Combined start value.

  • start_date (str | None) – Start date part.

  • start_time (str | None) – Start time part.

  • end_date_time (str | None) – Combined end value.

  • end_date (str | None) – End date part.

  • end_time (str | None) – End time part.

  • duration (str | int | None) – Duration in any accepted spelling.

Returns:

tuple[str, str](start, end) as YYYY-MM-DDTHH:MM:SSZ strings.

Return type:

tuple[str, str]

gamesheet_sdk.common.cli.game_times.resolve_game_window_update(start_date_time, start_date, start_time, end_date_time, end_date, end_time, duration, current_start, current_end)[source]

Resolve update-time inputs against the game’s current window.

Partial input is allowed: one new value updates that field and preserves the other, two or more trigger a recalculation, and no time input at all leaves the window untouched.

Parameters:
  • start_date_time (str | None) – Combined start value.

  • start_date (str | None) – Start date part.

  • start_time (str | None) – Start time part.

  • end_date_time (str | None) – Combined end value.

  • end_date (str | None) – End date part.

  • end_time (str | None) – End time part.

  • duration (str | int | None) – Duration in any accepted spelling.

  • current_start (str) – The game’s current start, ISO 8601.

  • current_end (str) – The game’s current end, ISO 8601.

Returns:

tuple[str | None, str | None]

The new (start, end) pair, or (None, None) when no time option

was supplied.

Return type:

tuple[str | None, str | None]

gamesheet_sdk.common.cli.game_times.resolve_time_zone(name, offset)[source]

Fill in whichever of the time zone name and offset was not supplied.

Both CLIs fall back to the system time zone, which is what create already did on either side. It is also what gamesheet-admin games update now does instead of assuming a hardcoded -240.

Parameters:
  • name (str | None) – --time-zone-name / --timezone, or None.

  • offset (int | None) – --time-zone-offset, or None.

Returns:

tuple[str, int] – The resolved (name, offset) pair.

Return type:

tuple[str, int]

gamesheet_sdk.common.cli.game_times.validate_game_time_inputs(start_date_time, start_date, start_time, end_date_time, end_date, end_time)[source]

Reject combining a --*-datetime option with its split counterparts.

A combined value that is only a time of day is exempt, because --start / --end are the flexible spellings and --date 2026-08-20 --start 12:00 has to keep meaning what it did before the two CLIs shared one option set. Two times for the same end of the window are still a conflict.

Parameters:
  • start_date_time (str | None) – Combined start value.

  • start_date (str | None) – Start date part.

  • start_time (str | None) – Start time part.

  • end_date_time (str | None) – Combined end value.

  • end_date (str | None) – End date part.

  • end_time (str | None) – End time part.