Skip to content

Add global option for overriding timezone#870

Open
nfultz wants to merge 1 commit intoinsanum:mainfrom
nfultz:nfultz/timezone
Open

Add global option for overriding timezone#870
nfultz wants to merge 1 commit intoinsanum:mainfrom
nfultz:nfultz/timezone

Conversation

@nfultz
Copy link
Copy Markdown

@nfultz nfultz commented Feb 10, 2026

closes #320


This pull request introduces a new global command-line option, --timezone, allowing users to specify a timezone to be used by gcalcli.

When the --timezone option is provided, its value is used to set the TZ environment variable, effectively overriding the system's default timezone for the execution of the gcalcli command. This ensures that all time-related operations within gcalcli adhere to the specified timezone.

@kody-ai
Copy link
Copy Markdown

kody-ai Bot commented Feb 10, 2026

Code Review Completed! 🔥

The code review was successfully completed based on your current configurations.

Automatic Review: Kody reviews this PR automatically on every push.

Kody Guide: Usage and Configuration
Interacting with Kody
  • Request a Review: Ask Kody to review your PR manually by adding a comment with the `@kody start-review` command at the root of your PR.

  • Provide Feedback: Help Kody learn and improve by reacting to its comments with a 👍 for helpful suggestions or a 👎 if improvements are needed.

Current Kody Configuration
Review Options

The following review options are enabled or disabled:

Options Enabled
Bug
Performance
Security
Cross File

Access your configuration settings here.

Comment thread gcalcli/argparsers.py
'given',
},
'--locale': {'default': '', 'type': str, 'help': 'System locale'},
'--timezone': {'default': '', 'type': str, 'help': 'Timezone to use'},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kody code-review Bug high

The newly added --timezone command-line argument has a default value of '' (an empty string). Standard Python timezone libraries, such as the built-in zoneinfo or third-party pytz, do not recognize an empty string as a valid timezone identifier. When code attempts to use this default value (e.g., zoneinfo.ZoneInfo('')), it will raise an exception like ZoneInfoNotFoundError, causing the application to crash.

The default value for an optional string argument that may not be provided should be None to clearly indicate its absence. This allows downstream code to reliably check for the presence of the value using if value is not None:. Other optional string arguments in this file, such as --client-id, already follow this pattern by defaulting to None.

'--timezone': {'default': None, 'type': str, 'help': 'Timezone to use'},
Prompt for LLM

File gcalcli/argparsers.py:

Line 65:

The provided Python code defines a command-line argument named `--timezone` using Python's `argparse` library. The configuration for this argument sets its default value to an empty string (`''`).

Please explain why this is a bug. Your explanation should focus on how standard timezone handling libraries in Python (such as the built-in `zoneinfo` module or the third-party `pytz` library) would process an empty string as a timezone identifier. Detail the specific exceptions that would be raised.

Then, propose a fix by changing the default value to `None` and justify why `None` is a more appropriate default for an optional argument of this type, contrasting it with the behavior of an empty string.

Suggested Code:

'--timezone': {'default': None, 'type': str, 'help': 'Timezone to use'},

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kody is it better to match style of --client-id with default None, or --locale with default ''

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to match the style of --client-id and use default: None.

Here's why:

  1. Clarity and Explicitness: Using None makes it unambiguous that the user did not provide a value. An empty string ('') could be interpreted as a deliberate (though invalid) input.
  2. Error Prevention: As the original review pointed out, an empty string is not a valid timezone and would cause a crash. A None value can be easily checked for (if timezone is not None:) before it's used, preventing runtime errors.
  3. Consistency: While --locale uses '', the argument for using None is stronger from a robustness standpoint. Aligning with the --client-id pattern establishes a safer convention for optional string arguments in the codebase.

Comment thread gcalcli/cli.py
Comment on lines +230 to +232
if parsed_args.timezone:
os.environ['TZ'] = parsed_args.timezone
time.tzset()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kody code-review Bug high

The added code uses os.environ['TZ'] and time.tzset() to set the application's timezone. According to the official Python documentation, time.tzset() is a Unix-only function. On other operating systems, such as Windows, this function is a no-op and does nothing. As a result, the --timezone feature will silently fail for users on Windows. The application will continue to run using the system's default timezone, leading to incorrect times for created or queried events, which can be considered a form of data corruption.

    if parsed_args.timezone:
        if sys.platform == 'win32':
            printer.err_msg(
                'Warning: The --timezone flag is not supported on Windows '
                'and will be ignored.\n'
            )
        else:
            os.environ['TZ'] = parsed_args.timezone
            time.tzset()
Prompt for LLM

File gcalcli/cli.py:

Line 230 to 232:

The provided Python code attempts to set the process's timezone using `os.environ['TZ']` and `time.tzset()`. Please analyze this code for platform compatibility issues. Specifically, consider how this code would behave on a non-Unix operating system like Windows. Based on the Python documentation for the `time` module, explain whether `time.tzset()` will function as intended on Windows and describe the user-facing consequences if it does not. Finally, propose a code modification that either warns the user about the incompatibility or provides a more robust, cross-platform solution.

Suggested Code:

    if parsed_args.timezone:
        if sys.platform == 'win32':
            printer.err_msg(
                'Warning: The --timezone flag is not supported on Windows '
                'and will be ignored.\n'
            )
        else:
            os.environ['TZ'] = parsed_args.timezone
            time.tzset()

Talk to Kody by mentioning @kody

Was this suggestion helpful? React with 👍 or 👎 to help Kody learn from this interaction.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kody how to properly override tz for windows?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've hit on a classic Python cross-platform issue! os.environ['TZ'] and time.tzset() are indeed the way to change the process's timezone on Unix-like systems, but this has no effect on Windows.

On Windows, there isn't a direct equivalent to the TZ environment variable for overriding the timezone for a single process. The proper, cross-platform way to handle this in Python is not to change the process's timezone, but to work with timezone-aware datetime objects.

Here are the recommended approaches:

1. Using pytz (Most Compatible)

This is a robust, third-party library that is the standard for timezone calculations in older Python versions.

import datetime
import pytz

# Get the timezone object
# Replace 'US/Pacific' with the desired timezone from parsed_args.timezone
us_pacific = pytz.timezone('US/Pacific')

# Create a timezone-aware datetime object
now_aware = datetime.datetime.now(us_pacific)

print(f"Time in US/Pacific: {now_aware}")
print(f"Timezone info: {now_aware.tzinfo}")

# To convert an existing naive datetime object
naive_dt = datetime.datetime.utcnow()
aware_dt = pytz.utc.localize(naive_dt).astimezone(us_pacific)
print(f"Converted UTC time: {aware_dt}")

2. Using zoneinfo (Python 3.9+)

If your project targets Python 3.9 or newer, the zoneinfo module is now part of the standard library and is the recommended approach.

import datetime
from zoneinfo import ZoneInfo

# Get the timezone object
# Replace 'US/Pacific' with the desired timezone from parsed_args.timezone
us_pacific = ZoneInfo('US/Pacific')

# Create a timezone-aware datetime object
now_aware = datetime.datetime.now(us_pacific)

print(f"Time in US/Pacific: {now_aware}")
print(f"Timezone info: {now_aware.tzinfo}")

# To convert an existing naive datetime object
naive_dt = datetime.datetime.utcnow()
aware_dt = naive_dt.replace(tzinfo=ZoneInfo("UTC")).astimezone(us_pacific)
print(f"Converted UTC time: {aware_dt}")

Recommendation for gcalcli:

Instead of trying to set a global process timezone, the application logic should be updated to use the user-provided timezone string to create timezone-aware datetime objects whenever it handles dates and times. This will make the behavior consistent and correct across all operating systems.

@nfultz
Copy link
Copy Markdown
Author

nfultz commented Feb 10, 2026

I can confirm this works inside .gcalclirc:

~$cat .gcalclirc 
--timezone=America/Los_Angeles
--default-calendar=UCLA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

give timezone parameter for showing agenda

1 participant