Skip to content

fix(python): return local timezone info from TimePlugin timeZoneOffset/timeZoneName - #14381

Open
Shxiao (Shxiao101) wants to merge 2 commits into
microsoft:mainfrom
Shxiao101:Shxiao101/fix/time-plugin-timezone
Open

fix(python): return local timezone info from TimePlugin timeZoneOffset/timeZoneName#14381
Shxiao (Shxiao101) wants to merge 2 commits into
microsoft:mainfrom
Shxiao101:Shxiao101/fix/time-plugin-timezone

Conversation

@Shxiao101

Copy link
Copy Markdown

Problem

TimePlugin.time_zone_offset() and time_zone_name() call strftime("%z")/strftime("%Z") on datetime.datetime.now(), which returns a naive datetime. Per the Python docs, %z and %Z format to an empty string on naive datetimes, so both kernel functions always return "":

>>> import datetime
>>> datetime.datetime.now().strftime("%z")
''

Fix

Attach the local timezone via astimezone() when the datetime is naive; aware datetimes are rendered as-is (the existing aware-mock tests keep passing unchanged). Also corrects the method docstring example from -08:00 to -0800 to match the actual %z output format (the class-level docstring already used -0800).

Testing

  • Two new regression tests mock a naive now() and assert the rendered offset/name is non-empty and equals the astimezone() reference. Expected values are computed through the same reference, so they hold on any machine and timezone. Both tests fail on the unfixed code.
  • Full pytest tests/unit/core_plugins/ passes; ruff check / ruff format --check clean.

Notes

%Z renders the OS-localized timezone name (standard strftime behavior); the function contract ("current time zone name") is unchanged.

…t/timeZoneName

datetime.now() returns a naive datetime, so strftime('%z')/('%Z') always
returned empty strings. Attach the local timezone via astimezone() when
the datetime is naive; aware datetimes are rendered as-is.
The new tests pin the regression fixed in the previous commit: with a
naive datetime, timeZoneOffset/timeZoneName must render the local
timezone instead of returning empty strings. Expected values are
computed via the same astimezone() reference, so they hold on any
machine and timezone.
Copilot AI lite review requested due to automatic review settings September 6, 2026 11:50
@Shxiao101
Shxiao (Shxiao101) requested a review from a team as a code owner September 6, 2026 11:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The fix is minimal, aligns with Python strftime behavior for naive datetimes, and includes targeted regression tests to prevent reintroduction.

Pull request overview

This PR fixes the Python TimePlugin kernel functions timeZoneOffset and timeZoneName so they return local timezone information even when datetime.datetime.now() is naive (the default), by attaching the local timezone before calling strftime("%z") / strftime("%Z"). This addresses the issue where %z/%Z render as an empty string on naive datetimes.

Changes:

  • Update TimePlugin.time_zone_offset() / time_zone_name() to call astimezone() when now.tzinfo is None.
  • Correct the time_zone_offset docstring example to match %z’s ±HHMM format.
  • Add regression tests that mock a naive now() and assert the returned offset/name matches the astimezone() reference and is non-empty.
File summaries
File Description
python/semantic_kernel/core_plugins/time_plugin.py Attach local tzinfo to naive now() before formatting %z/%Z; update docstring example formatting.
python/tests/unit/core_plugins/test_time_plugin.py Add regression tests covering naive datetime.now() behavior for offset/name.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

MAF Automated Review — Iteration 1

Result: No findings
Scope: full PR (2 commit(s)): acdcbeb30537, 4c5e36f19427
Model: claude-opus-4.8

Overview

This PR fixes a real correctness bug: TimePlugin.time_zone_offset() and
time_zone_name() called strftime("%z")/strftime("%Z") on a naive
datetime.datetime.now(), which per the Python docs always rendered to "". The
fix guards with if now.tzinfo is None: now = now.astimezone(), attaching the
system-local timezone before formatting, and corrects the offset docstring example
to the real %z output (-0800). The tzinfo is None guard is intentional and
well-chosen: it preserves the pre-existing aware-mock tests (+0000/UTC) while
fixing the naive production path. Two new regression tests derive expected values
from the same astimezone() reference, so they are machine-timezone independent,
and the change touches no shared state, persistence, or trust boundary. No
Critical/High/Medium issue was substantiated.

Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
No publishable findings remained after source verification for this scope.

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.

2 participants