Skip to content

fix: use UTC consistently across all datetime operations to resolve timezone display issues#14192

Draft
euvre wants to merge 2 commits intoinfiniflow:mainfrom
euvre:fix-issue-6970
Draft

fix: use UTC consistently across all datetime operations to resolve timezone display issues#14192
euvre wants to merge 2 commits intoinfiniflow:mainfrom
euvre:fix-issue-6970

Conversation

@euvre
Copy link
Copy Markdown
Contributor

@euvre euvre commented Apr 17, 2026

What problem does this PR solve?

Description

Fixes #6970

API responses returned incorrect times when the server timezone was not UTC. Date strings like create_date and update_date were generated using local time (e.g., UTC+8) but displayed without timezone context, causing an offset of several hours between the displayed and actual time.

Root Cause

  • timestamp_to_date() used time.localtime() instead of time.gmtime()
  • date_string_to_timestamp() used time.mktime() (local-tz) instead of calendar.timegm() (UTC)
  • get_format_time() and all service layers used datetime.now() instead of datetime.utcnow()
  • datetime_format() did not handle timezone-aware inputs

These caused a mismatch: timestamps were correct UTC values, while the corresponding date strings reflected server local time.

Changes

Core time utilities (common/time_utils.py)

Function Before After
timestamp_to_date() time.localtime() time.gmtime()
date_string_to_timestamp() time.mktime() calendar.timegm()
datetime_format() Strip microseconds only Also convert tz-aware inputs to UTC
get_format_time() datetime.now() datetime.utcnow()
delta_seconds() datetime.now() datetime.utcnow()

Service & API layer (23 files)

Replaced all datetime.now() with datetime.utcnow() across:

  • api/db/services/ — common_service, user_service, dialog_service, api_service, langfuse_service, search_service, file2document_service, knowledgebase_service, system_settings_service, pipeline_operation_log_service, task_service, connector_service, document_service, evaluation_service
  • api/apps/ — user_app, api_app, system_app, chunk_app, restful_apis/system_api, sdk/doc
  • api/utils/ — health_utils
  • admin/server/ — auth, routes

Testing

  • All datetime.now() occurrences in api/ and admin/ have been replaced — verified with grep.
  • The round-trip timestamp_to_date()date_string_to_timestamp() now uses UTC consistently on both ends.
  • No new linter errors introduced.

Type of change

  • Bug Fix (non-breaking change which fixes an issue)

Signed-off-by: noob <yixiao121314@outlook.com>
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. 🌈 python Pull requests that update Python code 🐖api The modified files are located under directory 'api/apps/sdk' 🐞 bug Something isn't working, pull request that fix bug. labels Apr 17, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 17, 2026

📝 Walkthrough

Walkthrough

This PR standardizes timestamp handling across the codebase by converting local-time usages to UTC (e.g., datetime.now()datetime.utcnow(), timezone-aware conversions, and time utility updates). Changes are limited to timestamp generation/formatting; control flow and public interfaces remain unchanged. (≤50 words)

Changes

Cohort / File(s) Summary
Time Utility Foundation
common/time_utils.py
Core time helpers updated to use UTC: added calendar, timestamp_to_date() uses gmtime(), date_string_to_timestamp() uses calendar.timegm(), datetime_format() normalizes to UTC, get_format_time()/delta_seconds() use utcnow().
API Endpoints – Timestamps
api/apps/api_app.py, api/apps/chunk_app.py, api/apps/system_app.py, api/apps/user_app.py
Endpoint defaults and returned metadata (stats window, chunk create_time, system status, user login update_date) now use UTC-based timestamps.
Admin Server – Auth & Keys
admin/server/auth.py, admin/server/routes.py
Admin login user.update_date and API key create_date generation switched to UTC.
API System & SDK
api/apps/restful_apis/system_api.py, api/apps/sdk/doc.py
System token creation and SDK chunk metadata now use UTC for create_date/create_time and timestamps.
Database Services – Common
api/db/services/common_service.py, api/db/services/user_service.py, api/db/services/knowledgebase_service.py, api/db/services/api_service.py
create_date/update_date assignments in generic insert/update methods and user/api services changed to use UTC.
Database Services – Domain-Specific
api/db/services/connector_service.py, api/db/services/dialog_service.py, api/db/services/document_service.py, api/db/services/evaluation_service.py, api/db/services/file2document_service.py, api/db/services/langfuse_service.py, api/db/services/pipeline_operation_log_service.py, api/db/services/search_service.py, api/db/services/system_settings_service.py, api/db/services/task_service.py
Numerous domain service methods updated to generate/store UTC timestamps (sync logs, dialog updates, document processing times, evaluation run names, file→document updates, task begin/process durations, etc.). One query filter changed: file2document_service.update_by_file_id now matches model.file_id.
Health & Monitoring
api/utils/health_utils.py, api/utils/health_utils.py
Heartbeat and executor-alive checks now use UTC timestamps for Redis ZSET score ranges.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I hop in UTC, leaving offsets behind,
Timestamps aligned, no surprises to find.
From chunks to tokens, timestamps made true,
A rabbit’s small patch to unify you! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 47.73% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Out of Scope Changes check ❓ Inconclusive All changes are directly scoped to resolving the UTC timezone issue. One minor discrepancy exists: File2DocumentService.update_by_file_id includes a filter change (id == file_id to file_id == file_id) alongside the UTC fix, which appears tangentially related but is not explicitly mentioned in the PR objectives. Clarify whether the filter change in File2DocumentService.update_by_file_id (id to file_id) is intentional and related to the timezone fix, or if it should be addressed separately.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely describes the main change: using UTC consistently across datetime operations to fix timezone display issues.
Description check ✅ Passed The PR description includes a clear problem statement, root cause analysis, comprehensive list of changes, and testing verification. It follows the template structure with 'What problem does this PR solve' and 'Type of change' sections properly filled.
Linked Issues check ✅ Passed The PR successfully addresses issue #6970 by systematically replacing all datetime.now() with datetime.utcnow() across 24 files and updating core time utilities to handle UTC consistently, directly resolving the timezone display problem documented in the issue.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@euvre euvre added the ci Continue Integration label Apr 17, 2026
@euvre euvre marked this pull request as draft April 17, 2026 07:34
@euvre euvre marked this pull request as ready for review April 17, 2026 07:34
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (4)
api/apps/chunk_app.py (1)

328-329: Use one UTC value for both creation fields.

This prevents intra-record timestamp drift between create_time and create_timestamp_flt.

Proposed tweak
-    d["create_time"] = str(datetime.datetime.utcnow()).replace("T", " ")[:19]
-    d["create_timestamp_flt"] = datetime.datetime.utcnow().timestamp()
+    now_utc = datetime.datetime.utcnow()
+    d["create_time"] = now_utc.strftime("%Y-%m-%d %H:%M:%S")
+    d["create_timestamp_flt"] = now_utc.timestamp()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/apps/chunk_app.py` around lines 328 - 329, Compute a single UTC datetime
once and reuse it for both fields to avoid drift: assign now =
datetime.datetime.utcnow() (or similar) and then set d["create_time"] =
str(now).replace("T", " ")[:19] and d["create_timestamp_flt"] = now.timestamp(),
referencing the existing dict d and the keys "create_time" and
"create_timestamp_flt".
api/db/services/document_service.py (2)

1006-1007: Capture datetime.utcnow() once per emitted record/task.

Paired fields (progress_msg+begin_at, create_time+create_timestamp_flt) should come from the same instant for consistency.

Proposed tweak
-            "progress_msg": datetime.utcnow().strftime("%H:%M:%S") + " created task " + ty,
-            "begin_at": datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"),
+            "progress_msg": now_utc.strftime("%H:%M:%S") + " created task " + ty,
+            "begin_at": now_utc.strftime("%Y-%m-%d %H:%M:%S"),
-            d["create_time"] = str(datetime.utcnow()).replace("T", " ")[:19]
-            d["create_timestamp_flt"] = datetime.utcnow().timestamp()
+            now_utc = datetime.utcnow()
+            d["create_time"] = now_utc.strftime("%Y-%m-%d %H:%M:%S")
+            d["create_timestamp_flt"] = now_utc.timestamp()

Also applies to: 1082-1083

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/db/services/document_service.py` around lines 1006 - 1007, The code calls
datetime.utcnow() separately for paired timestamp fields causing inconsistency;
capture a single utcnow() into a local variable (e.g., now) at the start of the
record/task creation and use that same value to derive both "progress_msg" and
"begin_at" (and likewise for "create_time" and "create_timestamp_flt") so those
pairs come from the same instant; update the blocks that set
progress_msg/begin_at and create_time/create_timestamp_flt to use the single
captured timestamp variable.

886-890: Use one captured UTC instant for duration updates.

This avoids tiny skew between fallback process_begin_at and process_duration in the same update cycle.

Proposed tweak
-                begin_at = d.get("process_begin_at")
-                if not begin_at:
-                    begin_at = datetime.utcnow()
+                now_utc = datetime.utcnow()
+                begin_at = d.get("process_begin_at")
+                if not begin_at:
+                    begin_at = now_utc
                     # fallback
                     cls.update_by_id(d["id"], {"process_begin_at": begin_at})

-                info = {"process_duration": max(datetime.timestamp(datetime.utcnow()) - begin_at.timestamp(), 0), "run": status}
+                info = {"process_duration": max((now_utc - begin_at).total_seconds(), 0), "run": status}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/db/services/document_service.py` around lines 886 - 890, Capture a single
UTC instant and reuse it for both the fallback process_begin_at update and as
the start timestamp when computing process_duration: assign now =
datetime.utcnow() (or reuse the existing begin_at variable but only set it
once), call cls.update_by_id(d["id"], {"process_begin_at": begin_at_or_now})
with that captured instant, and compute info["process_duration"] using that same
captured instant as the start (e.g. process_duration =
max(datetime.timestamp(datetime.utcnow()) - begin_at_or_now.timestamp(), 0));
update the code paths around begin_at, cls.update_by_id, and the info dict to
use this single captured timestamp.
api/db/services/evaluation_service.py (1)

287-287: Make auto-generated run names timezone-explicit.

After switching to UTC, this label can still be read as local time in UI/logs. Appending UTC avoids ambiguity.

Proposed tweak
-                name = f"Evaluation Run {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')}"
+                name = f"Evaluation Run {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')} UTC"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/db/services/evaluation_service.py` at line 287, The auto-generated
evaluation run name currently uses datetime.utcnow() but lacks timezone context;
update the assignment that builds the name (the line setting the variable name
to f"Evaluation Run {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')}") to
append an explicit timezone indicator (e.g., " UTC") so the resulting label is
"Evaluation Run <timestamp> UTC" to remove ambiguity in UI/logs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@admin/server/auth.py`:
- Around line 182-183: The assignments to user.update_time and user.update_date
are creating one-element tuples because of trailing commas; change the
assignments in the auth code to assign the raw values returned by
current_timestamp() and datetime_format(datetime.utcnow()) (remove the trailing
commas) so that user.update_time and user.update_date receive the expected
scalar types before calling user.save().

In `@api/apps/sdk/doc.py`:
- Around line 955-956: The create_timestamp_flt assignment uses a naive datetime
(datetime.utcnow().timestamp()) which Python treats as local time and can be
offset on non-UTC hosts; update the code that sets d["create_timestamp_flt"] to
use a timezone-aware UTC datetime (e.g., create a datetime with
timezone=datetime.timezone.utc via datetime.now(datetime.timezone.utc) or
utcnow().replace(tzinfo=datetime.timezone.utc)) before calling .timestamp() so
the epoch is correct; locate d["create_timestamp_flt"] in api/apps/sdk/doc.py
and replace the naive timestamp call accordingly (you can also consider using
the same UTC-aware source for d["create_time"] to keep consistency).

In `@api/apps/system_app.py`:
- Around line 130-133: The heartbeat time calculation uses a naive UTC datetime
which can be misinterpreted on non-UTC servers; replace the naive call that sets
now in system_app.py with an aware UTC timestamp (e.g., use
datetime.now(timezone.utc).timestamp()) so
REDIS_CONN.zrangebyscore(task_executor_id, now - 60 * 30, now) queries the
correct epoch range; also add the required import for timezone from datetime if
not present.

In `@api/db/services/file2document_service.py`:
- Around line 75-79: The update_by_file_id method is filtering on the primary id
(cls.model.id) instead of the file mapping column; change the where clause to
use the file_id column (e.g., cls.model.file_id == file_id) so the update
targets the row identified by file_id, keep the existing timestamp updates
(obj["update_time"], obj["update_date"]) and the call to
cls.model.update(...).execute(), and return File2Document(**obj) as before.

In `@api/db/services/task_service.py`:
- Around line 345-346: The subtraction datetime.utcnow() - task.begin_at can
raise when task.begin_at is None; guard the duration calculation in the method
that sets process_duration by checking task.begin_at (or Task.begin_at) before
computing seconds and only compute/update process_duration when begin_at is
present, otherwise set process_duration to None or 0 as appropriate and call
cls.model.update(...) with that value (use the same id/cls.model.id selector);
ensure you reference task.begin_at, process_duration, datetime.utcnow(),
cls.model.update and id when making the change.

In `@api/utils/health_utils.py`:
- Around line 312-315: The health window computation uses
datetime.utcnow().timestamp() which can be misinterpreted on non-UTC hosts;
update the import to include timezone (from datetime import datetime, timezone)
and replace datetime.utcnow().timestamp() with
datetime.now(timezone.utc).timestamp() where `now` is computed (used by
`REDIS_CONN.zrangebyscore` for `task_executors` heartbeat queries) so the Redis
score range is based on an explicit UTC timestamp.

In `@common/time_utils.py`:
- Around line 50-53: In timestamp_to_date: treat 0 as a valid timestamp by
changing the check to "if timestamp is None: timestamp = time.time()", and stop
unconditionally dividing by 1000; instead detect milliseconds vs seconds (e.g.,
if timestamp > 1e12 then timestamp = timestamp / 1000) so time.time() (seconds)
isn't mis-scaled, then call time.gmtime(timestamp); update references to the
timestamp variable and use time.time() and time.gmtime() accordingly.

---

Nitpick comments:
In `@api/apps/chunk_app.py`:
- Around line 328-329: Compute a single UTC datetime once and reuse it for both
fields to avoid drift: assign now = datetime.datetime.utcnow() (or similar) and
then set d["create_time"] = str(now).replace("T", " ")[:19] and
d["create_timestamp_flt"] = now.timestamp(), referencing the existing dict d and
the keys "create_time" and "create_timestamp_flt".

In `@api/db/services/document_service.py`:
- Around line 1006-1007: The code calls datetime.utcnow() separately for paired
timestamp fields causing inconsistency; capture a single utcnow() into a local
variable (e.g., now) at the start of the record/task creation and use that same
value to derive both "progress_msg" and "begin_at" (and likewise for
"create_time" and "create_timestamp_flt") so those pairs come from the same
instant; update the blocks that set progress_msg/begin_at and
create_time/create_timestamp_flt to use the single captured timestamp variable.
- Around line 886-890: Capture a single UTC instant and reuse it for both the
fallback process_begin_at update and as the start timestamp when computing
process_duration: assign now = datetime.utcnow() (or reuse the existing begin_at
variable but only set it once), call cls.update_by_id(d["id"],
{"process_begin_at": begin_at_or_now}) with that captured instant, and compute
info["process_duration"] using that same captured instant as the start (e.g.
process_duration = max(datetime.timestamp(datetime.utcnow()) -
begin_at_or_now.timestamp(), 0)); update the code paths around begin_at,
cls.update_by_id, and the info dict to use this single captured timestamp.

In `@api/db/services/evaluation_service.py`:
- Line 287: The auto-generated evaluation run name currently uses
datetime.utcnow() but lacks timezone context; update the assignment that builds
the name (the line setting the variable name to f"Evaluation Run
{datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')}") to append an explicit
timezone indicator (e.g., " UTC") so the resulting label is "Evaluation Run
<timestamp> UTC" to remove ambiguity in UI/logs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fd843fcc-6410-48c9-b685-3bee288dc65c

📥 Commits

Reviewing files that changed from the base of the PR and between 28d8b1c and a18c188.

📒 Files selected for processing (24)
  • admin/server/auth.py
  • admin/server/routes.py
  • api/apps/api_app.py
  • api/apps/chunk_app.py
  • api/apps/restful_apis/system_api.py
  • api/apps/sdk/doc.py
  • api/apps/system_app.py
  • api/apps/user_app.py
  • api/db/services/api_service.py
  • api/db/services/common_service.py
  • api/db/services/connector_service.py
  • api/db/services/dialog_service.py
  • api/db/services/document_service.py
  • api/db/services/evaluation_service.py
  • api/db/services/file2document_service.py
  • api/db/services/knowledgebase_service.py
  • api/db/services/langfuse_service.py
  • api/db/services/pipeline_operation_log_service.py
  • api/db/services/search_service.py
  • api/db/services/system_settings_service.py
  • api/db/services/task_service.py
  • api/db/services/user_service.py
  • api/utils/health_utils.py
  • common/time_utils.py

Comment thread admin/server/auth.py Outdated
Comment thread api/apps/sdk/doc.py Outdated
Comment thread api/apps/system_app.py Outdated
Comment thread api/db/services/file2document_service.py
Comment thread api/db/services/task_service.py Outdated
Comment thread api/utils/health_utils.py Outdated
Comment thread common/time_utils.py Outdated
Comment on lines +50 to +53
if not timestamp:
timestamp = time.time()
timestamp = int(timestamp) / 1000
time_array = time.localtime(timestamp)
time_array = time.gmtime(timestamp)
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.

⚠️ Potential issue | 🟠 Major

Fix default timestamp handling in timestamp_to_date.

On Line 51, time.time() returns seconds, but Line 52 divides by 1000 again, producing a 1970-era date. Also, 0 is incorrectly treated as “missing”.

Proposed fix
-    if not timestamp:
-        timestamp = time.time()
-    timestamp = int(timestamp) / 1000
+    if timestamp in (None, ""):
+        timestamp = current_timestamp()
+    timestamp = int(timestamp) / 1000
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@common/time_utils.py` around lines 50 - 53, In timestamp_to_date: treat 0 as
a valid timestamp by changing the check to "if timestamp is None: timestamp =
time.time()", and stop unconditionally dividing by 1000; instead detect
milliseconds vs seconds (e.g., if timestamp > 1e12 then timestamp = timestamp /
1000) so time.time() (seconds) isn't mis-scaled, then call
time.gmtime(timestamp); update references to the timestamp variable and use
time.time() and time.gmtime() accordingly.

Signed-off-by: noob <yixiao121314@outlook.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@api/db/services/document_service.py`:
- Around line 1084-1086: now_utc is created as a naive datetime via
datetime.utcnow() so calling .timestamp() will be interpreted as local time on
non-UTC hosts; change creation of now_utc to an aware UTC datetime (e.g.
datetime.now(timezone.utc) or datetime.utcnow().replace(tzinfo=timezone.utc))
before setting d["create_time"] and d["create_timestamp_flt"] so that
d["create_timestamp_flt"] is the true UTC epoch seconds for the document.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 35941532-4bf3-4aab-8321-8fd112a2d261

📥 Commits

Reviewing files that changed from the base of the PR and between a18c188 and 339f401.

📒 Files selected for processing (10)
  • admin/server/auth.py
  • api/apps/chunk_app.py
  • api/apps/sdk/doc.py
  • api/apps/system_app.py
  • api/db/services/document_service.py
  • api/db/services/evaluation_service.py
  • api/db/services/file2document_service.py
  • api/db/services/task_service.py
  • api/utils/health_utils.py
  • common/time_utils.py
✅ Files skipped from review due to trivial changes (3)
  • api/db/services/evaluation_service.py
  • api/apps/sdk/doc.py
  • api/apps/system_app.py
🚧 Files skipped from review as they are similar to previous changes (5)
  • admin/server/auth.py
  • api/utils/health_utils.py
  • api/apps/chunk_app.py
  • api/db/services/task_service.py
  • api/db/services/file2document_service.py

Comment on lines +1084 to +1086
now_utc = datetime.utcnow()
d["create_time"] = now_utc.strftime("%Y-%m-%d %H:%M:%S")
d["create_timestamp_flt"] = now_utc.timestamp()
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.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

In Python 3, does datetime.timestamp() interpret naive datetime objects as local time, and is datetime.now(timezone.utc) the recommended UTC-safe approach over datetime.utcnow() for epoch conversion?

💡 Result:

Yes, in Python 3, datetime.timestamp interprets naive datetime objects as local time. For UTC-safe epoch conversion, datetime.now(timezone.utc) is the recommended approach over the deprecated datetime.utcnow.

Citations:


🏁 Script executed:

# First, verify the file exists and check lines around 1084-1086
head -1090 api/db/services/document_service.py | tail -20

Repository: infiniflow/ragflow

Length of output: 989


🏁 Script executed:

# Check imports at the top of the file
head -50 api/db/services/document_service.py

Repository: infiniflow/ragflow

Length of output: 1993


🏁 Script executed:

# Search for all datetime imports in the file
rg "from datetime import|import datetime" api/db/services/document_service.py

Repository: infiniflow/ragflow

Length of output: 91


🏁 Script executed:

rg "datetime\.utcnow" api/db/services/document_service.py -n

Repository: infiniflow/ragflow

Length of output: 195


🏁 Script executed:

# Check context around line 884
sed -n '880,890p' api/db/services/document_service.py

Repository: infiniflow/ragflow

Length of output: 551


🏁 Script executed:

# Check context around line 1001
sed -n '998,1008p' api/db/services/document_service.py

Repository: infiniflow/ragflow

Length of output: 448


create_timestamp_flt is incorrect with naive utcnow() + .timestamp().

At Line 1086, now_utc is naive (datetime.utcnow()), and .timestamp() treats naive datetimes as local time. On non-UTC servers this stores an offset epoch value, which breaks the UTC-fix objective.

Proposed fix
-from datetime import datetime
+from datetime import datetime, timezone
@@
-            now_utc = datetime.utcnow()
+            now_utc = datetime.now(timezone.utc)
             d["create_time"] = now_utc.strftime("%Y-%m-%d %H:%M:%S")
             d["create_timestamp_flt"] = now_utc.timestamp()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/db/services/document_service.py` around lines 1084 - 1086, now_utc is
created as a naive datetime via datetime.utcnow() so calling .timestamp() will
be interpreted as local time on non-UTC hosts; change creation of now_utc to an
aware UTC datetime (e.g. datetime.now(timezone.utc) or
datetime.utcnow().replace(tzinfo=timezone.utc)) before setting d["create_time"]
and d["create_timestamp_flt"] so that d["create_timestamp_flt"] is the true UTC
epoch seconds for the document.

@euvre euvre marked this pull request as draft April 17, 2026 08:05
@euvre
Copy link
Copy Markdown
Contributor Author

euvre commented Apr 17, 2026

I'll open this pr after investigation.

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

Labels

🐖api The modified files are located under directory 'api/apps/sdk' 🐞 bug Something isn't working, pull request that fix bug. ci Continue Integration 🌈 python Pull requests that update Python code size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Question]: Incorrect Time Display in API Due to Missing Timezone Information in RFC 1123 Format

1 participant