Created
December 2, 2010 08:56
-
-
Save matthewd/725009 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 2621822b8a88c438de81c221a6a2d7f65c98c558 Mon Sep 17 00:00:00 2001 | |
From: Matthew Draper <matthew@trebex.net> | |
Date: Thu, 2 Dec 2010 20:51:43 +1030 | |
Subject: [PATCH] Consider DST status of the given date, not today. | |
In passing, use the thread-safe time.h functions, and don't assume | |
tm_isdst will always be 0 or 1. | |
--- | |
.../data_objects/spec/typecast/datetime_spec.rb | 26 +++++++++++++ | |
do_derby/spec/spec_helper.rb | 4 ++ | |
do_h2/spec/spec_helper.rb | 4 ++ | |
do_hsqldb/spec/spec_helper.rb | 4 ++ | |
do_mysql/ext/do_mysql/do_mysql.c | 40 ++++++++++++++----- | |
do_mysql/spec/spec_helper.rb | 4 ++ | |
do_oracle/spec/spec_helper.rb | 4 ++ | |
do_postgres/ext/do_postgres/do_postgres.c | 40 ++++++++++++++----- | |
do_postgres/spec/spec_helper.rb | 4 ++ | |
do_sqlite3/ext/do_sqlite3/do_sqlite3.c | 40 ++++++++++++++----- | |
do_sqlite3/spec/spec_helper.rb | 4 ++ | |
do_sqlserver/spec/spec_helper.rb | 4 ++ | |
12 files changed, 145 insertions(+), 33 deletions(-) | |
diff --git a/data_objects/lib/data_objects/spec/typecast/datetime_spec.rb b/data_objects/lib/data_objects/spec/typecast/datetime_spec.rb | |
index 442ff9a..bb1f63a 100644 | |
--- a/data_objects/lib/data_objects/spec/typecast/datetime_spec.rb | |
+++ b/data_objects/lib/data_objects/spec/typecast/datetime_spec.rb | |
@@ -63,6 +63,32 @@ shared 'supporting DateTime' do | |
end | |
+ describe 'with manual typecasting a datetime column' do | |
+ | |
+ before do | |
+ @command = @connection.create_command("SELECT release_datetime FROM widgets WHERE id = ? OR id = ? ORDER BY id") | |
+ @command.set_types(DateTime) | |
+ @reader = @command.execute_reader(1, 10) | |
+ @reader.next! | |
+ @feb_row = @reader.values | |
+ @reader.next! | |
+ @jul_row = @reader.values | |
+ end | |
+ | |
+ after do | |
+ @reader.close | |
+ end | |
+ | |
+ it 'should return the correct offset in Feb' do | |
+ (@feb_row.first.offset * 86400).to_i.should == Time.local(2008, 2, 14, 0, 31, 12).utc_offset | |
+ end | |
+ | |
+ it 'should return the correct offset in Jul' do | |
+ (@jul_row.first.offset * 86400).to_i.should == Time.local(2008, 7, 14, 0, 31, 12).utc_offset | |
+ end | |
+ | |
+ end | |
+ | |
end | |
describe 'writing an DateTime' do | |
diff --git a/do_derby/spec/spec_helper.rb b/do_derby/spec/spec_helper.rb | |
index 1e83bb1..3d38f42 100644 | |
--- a/do_derby/spec/spec_helper.rb | |
+++ b/do_derby/spec/spec_helper.rb | |
@@ -176,6 +176,10 @@ module DataObjectsSpecHelpers | |
update widgets set release_timestamp = NULL where id = 9 | |
EOF | |
+ conn.create_command(<<-EOF).execute_non_query | |
+ update widgets set release_datetime = '2008-07-14 00:31:12' where id = 10 | |
+ EOF | |
+ | |
conn.close | |
end | |
diff --git a/do_h2/spec/spec_helper.rb b/do_h2/spec/spec_helper.rb | |
index 8abdbe8..f886e4b 100644 | |
--- a/do_h2/spec/spec_helper.rb | |
+++ b/do_h2/spec/spec_helper.rb | |
@@ -155,6 +155,10 @@ module DataObjectsSpecHelpers | |
update widgets set release_timestamp = NULL where id = 9 | |
EOF | |
+ conn.create_command(<<-EOF).execute_non_query | |
+ update widgets set release_datetime = '2008-07-14 00:31:12' where id = 10 | |
+ EOF | |
+ | |
conn.close | |
end | |
diff --git a/do_hsqldb/spec/spec_helper.rb b/do_hsqldb/spec/spec_helper.rb | |
index ce09c13..601f16d 100644 | |
--- a/do_hsqldb/spec/spec_helper.rb | |
+++ b/do_hsqldb/spec/spec_helper.rb | |
@@ -154,6 +154,10 @@ module DataObjectsSpecHelpers | |
update widgets set release_timestamp = NULL where id = 9 | |
EOF | |
+ conn.create_command(<<-EOF).execute_non_query | |
+ update widgets set release_datetime = '2008-07-14 00:31:12' where id = 10 | |
+ EOF | |
+ | |
## TODO: change the hexadecimal examples | |
conn.close | |
end | |
diff --git a/do_mysql/ext/do_mysql/do_mysql.c b/do_mysql/ext/do_mysql/do_mysql.c | |
index 92fe5b3..232437b 100755 | |
--- a/do_mysql/ext/do_mysql/do_mysql.c | |
+++ b/do_mysql/ext/do_mysql/do_mysql.c | |
@@ -230,10 +230,10 @@ static VALUE parse_date_time(const char *date) { | |
time_t gmt_offset; | |
- int is_dst; | |
+ int dst_adjustment; | |
time_t rawtime; | |
- struct tm * timeinfo; | |
+ struct tm timeinfo; | |
int tokens_read, max_tokens; | |
@@ -267,22 +267,40 @@ static VALUE parse_date_time(const char *date) { | |
} | |
// We read the Date and Time, default to the current locale's offset | |
+ tzset(); | |
+ | |
// Get localtime | |
time(&rawtime); | |
- timeinfo = localtime(&rawtime); | |
+ localtime_r(&rawtime, &timeinfo); | |
+ | |
+ timeinfo.tm_sec = sec; | |
+ timeinfo.tm_min = min; | |
+ timeinfo.tm_hour = hour; | |
+ timeinfo.tm_mday = day; | |
+ timeinfo.tm_mon = month; | |
+ timeinfo.tm_year = year - 1900; | |
+ timeinfo.tm_isdst = -1; | |
+ | |
+ // Update tm_isdst | |
+ mktime(&timeinfo); | |
- is_dst = timeinfo->tm_isdst * 3600; | |
+ if (timeinfo.tm_isdst) { | |
+ dst_adjustment = 3600; | |
+ } else { | |
+ dst_adjustment = 0; | |
+ } | |
// Reset to GM Time | |
- timeinfo = gmtime(&rawtime); | |
+ gmtime_r(&rawtime, &timeinfo); | |
- gmt_offset = mktime(timeinfo) - rawtime; | |
+ gmt_offset = rawtime - mktime(&timeinfo); | |
- if ( is_dst > 0 ) | |
- gmt_offset -= is_dst; | |
+ if (dst_adjustment) { | |
+ gmt_offset += dst_adjustment; | |
+ } | |
- hour_offset = -((int)gmt_offset / 3600); | |
- minute_offset = -((int)gmt_offset % 3600 / 60); | |
+ hour_offset = ((int)gmt_offset / 3600); | |
+ minute_offset = ((int)gmt_offset % 3600 / 60); | |
} else { | |
// Something went terribly wrong | |
diff --git a/do_mysql/spec/spec_helper.rb b/do_mysql/spec/spec_helper.rb | |
index d4615c0..e23b37c 100644 | |
--- a/do_mysql/spec/spec_helper.rb | |
+++ b/do_mysql/spec/spec_helper.rb | |
@@ -141,6 +141,10 @@ module DataObjectsSpecHelpers | |
update widgets set release_timestamp = NULL where id = 9 | |
EOF | |
+ conn.create_command(<<-EOF).execute_non_query | |
+ update widgets set release_datetime = '2008-07-14 00:31:12' where id = 10 | |
+ EOF | |
+ | |
conn.close | |
end | |
diff --git a/do_oracle/spec/spec_helper.rb b/do_oracle/spec/spec_helper.rb | |
index 0f4586f..07246cc 100644 | |
--- a/do_oracle/spec/spec_helper.rb | |
+++ b/do_oracle/spec/spec_helper.rb | |
@@ -181,6 +181,10 @@ module DataObjectsSpecHelpers | |
update widgets set release_timestamp = NULL where id = 9 | |
EOF | |
+ conn.create_command(<<-EOF).execute_non_query | |
+ update widgets set release_datetime = '2008-07-14 00:31:12' where id = 10 | |
+ EOF | |
+ | |
conn.close | |
$test_environment_setup_done = true | |
end | |
diff --git a/do_postgres/ext/do_postgres/do_postgres.c b/do_postgres/ext/do_postgres/do_postgres.c | |
index ea77885..f5d3901 100755 | |
--- a/do_postgres/ext/do_postgres/do_postgres.c | |
+++ b/do_postgres/ext/do_postgres/do_postgres.c | |
@@ -201,10 +201,10 @@ static VALUE parse_date_time(const char *date) { | |
do_int64 num, den; | |
long int gmt_offset; | |
- int is_dst; | |
+ int dst_adjustment; | |
time_t rawtime; | |
- struct tm * timeinfo; | |
+ struct tm timeinfo; | |
int tokens_read, max_tokens; | |
@@ -234,22 +234,40 @@ static VALUE parse_date_time(const char *date) { | |
} | |
// We read the Date and Time, default to the current locale's offset | |
+ tzset(); | |
+ | |
// Get localtime | |
time(&rawtime); | |
- timeinfo = localtime(&rawtime); | |
+ localtime_r(&rawtime, &timeinfo); | |
+ | |
+ timeinfo.tm_sec = sec; | |
+ timeinfo.tm_min = min; | |
+ timeinfo.tm_hour = hour; | |
+ timeinfo.tm_mday = day; | |
+ timeinfo.tm_mon = month; | |
+ timeinfo.tm_year = year - 1900; | |
+ timeinfo.tm_isdst = -1; | |
+ | |
+ // Update tm_isdst | |
+ mktime(&timeinfo); | |
- is_dst = timeinfo->tm_isdst * 3600; | |
+ if (timeinfo.tm_isdst) { | |
+ dst_adjustment = 3600; | |
+ } else { | |
+ dst_adjustment = 0; | |
+ } | |
// Reset to GM Time | |
- timeinfo = gmtime(&rawtime); | |
+ gmtime_r(&rawtime, &timeinfo); | |
- gmt_offset = mktime(timeinfo) - rawtime; | |
+ gmt_offset = rawtime - mktime(&timeinfo); | |
- if ( is_dst > 0 ) | |
- gmt_offset -= is_dst; | |
+ if (dst_adjustment) { | |
+ gmt_offset += dst_adjustment; | |
+ } | |
- hour_offset = -((int)gmt_offset / 3600); | |
- minute_offset = -((int)gmt_offset % 3600 / 60); | |
+ hour_offset = ((int)gmt_offset / 3600); | |
+ minute_offset = ((int)gmt_offset % 3600 / 60); | |
} else { | |
// Something went terribly wrong | |
diff --git a/do_postgres/spec/spec_helper.rb b/do_postgres/spec/spec_helper.rb | |
index 3f657bd..8067863 100644 | |
--- a/do_postgres/spec/spec_helper.rb | |
+++ b/do_postgres/spec/spec_helper.rb | |
@@ -139,6 +139,10 @@ module DataObjectsSpecHelpers | |
update widgets set release_timestamp = NULL where id = 9 | |
EOF | |
+ conn.create_command(<<-EOF).execute_non_query | |
+ update widgets set release_datetime = '2008-07-14 00:31:12' where id = 10 | |
+ EOF | |
+ | |
conn.close | |
end | |
diff --git a/do_sqlite3/ext/do_sqlite3/do_sqlite3.c b/do_sqlite3/ext/do_sqlite3/do_sqlite3.c | |
index 7fb7964..18ef604 100755 | |
--- a/do_sqlite3/ext/do_sqlite3/do_sqlite3.c | |
+++ b/do_sqlite3/ext/do_sqlite3/do_sqlite3.c | |
@@ -142,10 +142,10 @@ static VALUE parse_date_time(char *date) { | |
do_int64 num, den; | |
long int gmt_offset; | |
- int is_dst; | |
+ int dst_adjustment; | |
time_t rawtime; | |
- struct tm * timeinfo; | |
+ struct tm timeinfo; | |
int tokens_read, max_tokens; | |
@@ -179,22 +179,40 @@ static VALUE parse_date_time(char *date) { | |
} | |
// We read the Date and Time, default to the current locale's offset | |
+ tzset(); | |
+ | |
// Get localtime | |
time(&rawtime); | |
- timeinfo = localtime(&rawtime); | |
+ localtime_r(&rawtime, &timeinfo); | |
+ | |
+ timeinfo.tm_sec = sec; | |
+ timeinfo.tm_min = min; | |
+ timeinfo.tm_hour = hour; | |
+ timeinfo.tm_mday = day; | |
+ timeinfo.tm_mon = month; | |
+ timeinfo.tm_year = year - 1900; | |
+ timeinfo.tm_isdst = -1; | |
+ | |
+ // Update tm_isdst | |
+ mktime(&timeinfo); | |
- is_dst = timeinfo->tm_isdst * 3600; | |
+ if (timeinfo.tm_isdst) { | |
+ dst_adjustment = 3600; | |
+ } else { | |
+ dst_adjustment = 0; | |
+ } | |
// Reset to GM Time | |
- timeinfo = gmtime(&rawtime); | |
+ gmtime_r(&rawtime, &timeinfo); | |
- gmt_offset = mktime(timeinfo) - rawtime; | |
+ gmt_offset = rawtime - mktime(&timeinfo); | |
- if ( is_dst > 0 ) | |
- gmt_offset -= is_dst; | |
+ if (dst_adjustment) { | |
+ gmt_offset += dst_adjustment; | |
+ } | |
- hour_offset = -((int)gmt_offset / 3600); | |
- minute_offset = -((int)gmt_offset % 3600 / 60); | |
+ hour_offset = ((int)gmt_offset / 3600); | |
+ minute_offset = ((int)gmt_offset % 3600 / 60); | |
} else { | |
// Something went terribly wrong | |
diff --git a/do_sqlite3/spec/spec_helper.rb b/do_sqlite3/spec/spec_helper.rb | |
index 1d9694c..0777d31 100644 | |
--- a/do_sqlite3/spec/spec_helper.rb | |
+++ b/do_sqlite3/spec/spec_helper.rb | |
@@ -131,6 +131,10 @@ module DataObjectsSpecHelpers | |
update widgets set release_timestamp = NULL where id = 9 | |
EOF | |
+ conn.create_command(<<-EOF).execute_non_query | |
+ update widgets set release_datetime = '2008-07-14 00:31:12' where id = 10 | |
+ EOF | |
+ | |
conn.close | |
end | |
diff --git a/do_sqlserver/spec/spec_helper.rb b/do_sqlserver/spec/spec_helper.rb | |
index 8b30cb2..18514c0 100644 | |
--- a/do_sqlserver/spec/spec_helper.rb | |
+++ b/do_sqlserver/spec/spec_helper.rb | |
@@ -138,6 +138,10 @@ module DataObjectsSpecHelpers | |
update widgets set release_timestamp = NULL where id = 9 | |
EOF | |
+ conn.create_command(<<-EOF).execute_non_query | |
+ update widgets set release_datetime = '2008-07-14 00:31:12' where id = 10 | |
+ EOF | |
+ | |
conn.close | |
end | |
-- | |
1.7.2.3 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment