Skip to content

Commit 49d4cfe

Browse files
smtakedaankit-bhatnagar167
authored andcommitted
SNOW-66722: Fixed regression for DATE format in Windows
1 parent 2ab51d3 commit 49d4cfe

File tree

3 files changed

+53
-7
lines changed

3 files changed

+53
-7
lines changed

converter_snowsql.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
#
66

77
import time
8-
from datetime import timedelta, datetime
8+
from datetime import timedelta, datetime, date
99
from logging import getLogger
1010

1111
import pytz
1212

13-
from .compat import TO_UNICODE
13+
from .compat import TO_UNICODE, IS_WINDOWS
1414
from .constants import (is_timestamp_type_name, is_date_type_name)
1515
from .converter import (SnowflakeConverter, ZERO_EPOCH, _extract_timestamp)
1616
from .sfbinaryformat import (binary_to_python, SnowflakeBinaryFormat)
@@ -72,10 +72,11 @@ def to_python_method(self, type_name, column):
7272
ctx['zero_fill'] = '0' * (9 - ctx['scale'])
7373
fmt = None
7474
if is_date_type_name(type_name):
75+
datetime_class = time.struct_time if not IS_WINDOWS else date
7576
fmt = SnowflakeDateFormat(
7677
self._get_format(type_name),
7778
support_negative_year=self._support_negative_year,
78-
datetime_class=time.struct_time)
79+
datetime_class=datetime_class)
7980
elif is_timestamp_type_name(type_name):
8081
fmt = SnowflakeDateTimeFormat(
8182
self._get_format(type_name),
@@ -121,14 +122,19 @@ def _BINARY_to_python(self, ctx):
121122

122123
def _DATE_to_python(self, ctx):
123124
"""
124-
DATE to datetime
125+
DATE to struct_time/date
125126
126127
No timezone is attached.
127128
"""
129+
128130
def conv(value):
129131
return ctx['fmt'].format(time.gmtime(int(value) * (24 * 60 * 60)))
130132

131-
return conv
133+
def conv_windows(value):
134+
ts = ZERO_EPOCH + timedelta(seconds=int(value) * (24 * 60 * 60))
135+
return ctx['fmt'].format(date(ts.year, ts.month, ts.day))
136+
137+
return conv if not IS_WINDOWS else conv_windows
132138

133139
def _TIMESTAMP_TZ_to_python(self, ctx):
134140
"""

sfdatetime.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
#
44
# Copyright (c) 2012-2018 Snowflake Computing Inc. All right reserved.
55
#
6-
import time
76
from collections import namedtuple
8-
from datetime import timedelta, datetime
7+
8+
import time
9+
from datetime import timedelta, datetime, date
910

1011
from .compat import TO_UNICODE
1112

@@ -79,6 +80,11 @@ def _build_raw_year_format(year_raw_value, year_len):
7980
return fmt.format(year_raw_value)
8081

8182

83+
def _support_negative_year_date(value, year_len):
84+
# if YYYY/YY is included
85+
return _build_year_format(value, year_len)
86+
87+
8288
def _inject_fraction(value, fraction_len):
8389
# if FF is included
8490
nano_str = u'{:09d}'
@@ -112,6 +118,7 @@ def _inject_others(_, value0):
112118
_support_negative_year,
113119
_support_negative_year_datetime,
114120
_support_negative_year_struct_time,
121+
_support_negative_year_date,
115122
_inject_fraction
116123
}
117124

@@ -134,6 +141,8 @@ def __init__(
134141
self._support_negative_year_method = _support_negative_year_datetime
135142
elif datetime_class == time.struct_time:
136143
self._support_negative_year_method = _support_negative_year_struct_time
144+
elif datetime_class == date:
145+
self._support_negative_year_method = _support_negative_year_date
137146
else:
138147
self._support_negative_year_method = _support_negative_year
139148

@@ -350,3 +359,7 @@ def _format_struct_time(self, value):
350359
"""
351360
fmt = self._pre_format(value)
352361
return TO_UNICODE(time.strftime(fmt, value))
362+
363+
def _format_date(self, value):
364+
fmt = self._pre_format(value)
365+
return value.strftime(fmt)

test/test_converter.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,33 @@ def test_fetch_timestamps_negative_epoch(conn_cnx):
344344
assert ret[1] == r1
345345

346346

347+
def test_date_0001_9999(conn_cnx):
348+
"""
349+
Test 0001 and 9999 for all platforms
350+
"""
351+
with conn_cnx(
352+
converter_class=SnowflakeConverterSnowSQL,
353+
support_negative_year=True) as cnx:
354+
cnx.cursor().execute("""
355+
ALTER SESSION SET
356+
DATE_OUTPUT_FORMAT='YYYY-MM-DD'
357+
""")
358+
cur = cnx.cursor()
359+
cur.execute("""
360+
SELECT
361+
DATE_FROM_PARTS(1900, 1, 1),
362+
DATE_FROM_PARTS(2500, 2, 3),
363+
DATE_FROM_PARTS(1, 10, 31),
364+
DATE_FROM_PARTS(9999, 3, 20)
365+
;
366+
""")
367+
ret = cur.fetchone()
368+
assert ret[0] == '1900-01-01'
369+
assert ret[1] == '2500-02-03'
370+
assert ret[2] == '0001-10-31'
371+
assert ret[3] == '9999-03-20'
372+
373+
347374
@pytest.mark.skipif(PY2 or IS_WINDOWS, reason="year out of range error")
348375
def test_five_or_more_digit_year_date_converter(conn_cnx):
349376
"""

0 commit comments

Comments
 (0)