Skip to content

Commit c2ac0c2

Browse files
author
Peng Ren
committed
Fix time zone issue for date function
1 parent 7ee01a8 commit c2ac0c2

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

pymongosql/sql/projection_functions.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import logging
33
import re
44
from abc import ABC, abstractmethod
5-
from datetime import date, datetime
5+
from datetime import date, datetime, timezone
66
from typing import Any, List, Optional, Tuple
77

88
from bson import Timestamp
@@ -115,7 +115,7 @@ def extract_column_and_format(self, text: str) -> Tuple[str, Optional[str]]:
115115
return "", None
116116

117117
def convert_value(self, value: Any, format_param: Optional[str] = None) -> Any:
118-
"""Convert to BSON Timestamp"""
118+
"""Convert to BSON Timestamp using UTC for consistency"""
119119
if value is None:
120120
return None
121121

@@ -130,33 +130,39 @@ def convert_value(self, value: Any, format_param: Optional[str] = None) -> Any:
130130
# Try ISO format first
131131
try:
132132
dt = datetime.fromisoformat(value)
133+
# Use UTC if no timezone info
134+
if dt.tzinfo is None:
135+
dt = dt.replace(tzinfo=timezone.utc)
133136
timestamp_int = int(dt.timestamp())
134137
return Timestamp(timestamp_int, 0)
135138
except (ValueError, TypeError):
136139
pass
137140

138-
# Try date-only format (YYYY-MM-DD)
141+
# Try date-only format (YYYY-MM-DD) - treat as UTC
139142
if re.match(r"^\d{4}-\d{2}-\d{2}$", value):
140143
try:
141144
dt = datetime.strptime(value, "%Y-%m-%d")
145+
dt = dt.replace(tzinfo=timezone.utc) # Treat as UTC
142146
timestamp_int = int(dt.timestamp())
143147
return Timestamp(timestamp_int, 0)
144148
except ValueError:
145149
pass
146150

147-
# Try custom format if provided
151+
# Try custom format if provided - treat as UTC
148152
if format_param:
149153
try:
150154
dt = datetime.strptime(value, format_param)
155+
dt = dt.replace(tzinfo=timezone.utc) # Treat as UTC
151156
timestamp_int = int(dt.timestamp())
152157
return Timestamp(timestamp_int, 0)
153158
except ValueError:
154159
pass
155160

156-
# Try common formats
161+
# Try common formats - treat as UTC
157162
for fmt in ["%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%d %H:%M:%S", "%Y-%m-%d", "%d-%m-%Y", "%m/%d/%Y"]:
158163
try:
159164
dt = datetime.strptime(value, fmt)
165+
dt = dt.replace(tzinfo=timezone.utc) # Treat as UTC
160166
timestamp_int = int(dt.timestamp())
161167
return Timestamp(timestamp_int, 0)
162168
except ValueError:

tests/test_projection_functions.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"""Tests for projection functions"""
33

44
import re
5-
from datetime import date, datetime
5+
from datetime import date, datetime, timezone
66

77
from bson import Timestamp
88

@@ -202,7 +202,14 @@ def test_convert_iso_date_string(self):
202202
func = TimestampFunction()
203203
result = func.convert_value("2025-01-15")
204204
assert isinstance(result, Timestamp)
205-
assert result.time == 1736917200 # Unix timestamp for 2025-01-15 00:00:00 UTC
205+
# Verify the timestamp represents 2025-01-15 00:00:00 UTC
206+
# Use UTC explicitly for timezone-independent validation (Windows/Unix compatible)
207+
dt = datetime.fromtimestamp(result.time, tz=timezone.utc)
208+
assert dt.year == 2025
209+
assert dt.month == 1
210+
assert dt.day == 15
211+
assert dt.hour == 0
212+
assert dt.minute == 0
206213

207214
def test_convert_iso_datetime_string(self):
208215
"""Test conversion from ISO datetime strings"""

0 commit comments

Comments
 (0)