# Patch for AR SQLServer adapter to allow for \< 1970 datetimes

**URL:** <https://www.ruby-forum.com/t/patch-for-ar-sqlserver-adapter-to-allow-for-1970-datetimes/130492>\
**Category:** Rails\
**Created:** [February 28, 2008, 7:27pm UTC](https://www.ruby-forum.com/t/patch-for-ar-sqlserver-adapter-to-allow-for-1970-datetimes/130492 "2008-02-28T19:27:02Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![weyus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/7ab992/32.png) [@weyus](https://www.ruby-forum.com/u/weyus)\
**Post date:** [February 28, 2008, 7:27pm UTC](https://www.ruby-forum.com/t/patch-for-ar-sqlserver-adapter-to-allow-for-1970-datetimes/130492/1 "2008-02-28T19:27:02Z")

</div>

All,

> = Rails 1.2.6

I’ve been down this road of not being able to get the SQLServer AR  
driver to support pre-1970 SQLServer datetime fields before back in  
Rails 1.1.6 ([Selecting datetime values from SQL Server (year \< 1970) - Rails - Ruby-Forum](http://www.ruby-forum.com/topic/85216)), but now I’m finally  
updating this app. to Rails 1.2 and beyond.

So…below is a patch to the current 1.0.0 version of  
sqlserver\_adapter.rb (from the new separate AR adapter Rails 2.0-style  
gem) that appears (in my app. so far) to successfully allow for the  
successful manipulation of \< 1970 datetime values in Rails. It requires  
mods. to both the “cast\_to\_datetime” and “string\_to\_time” methods, and  
as you can see, simply returns DateTime objects instead of Time objects  
(which are limited to 1970 and later).

I’m not sure why the casts to time are there in the first place - my  
guess is that the way that MySQL handles dates influences how this  
SQLServer driver is handling dates.

I will try and make time to set up a proper patch submission in Trac at  
some point, but really pressed for time these days.

Thanks,  
Wes

---- BEGIN PATCH ----

# Index: sqlserver\_adapter.rb

— sqlserver\_adapter.rb (revision 8940)  
+++ sqlserver\_adapter.rb (working copy)  
@@ -104,8 +104,7 @@  
end

```
     if value.is_a?(DateTime)

```

- 

```
     return Time.mktime(value.year, value.mon, value.day,

```

value.hour, valu  
e.min, value.sec)

- 

```
     #return DateTime.new(value.year, value.mon, value.day,

```

value.hour, va  
lue.min, value.sec)

- 

```
     return DateTime.new(value.year, value.mon, value.day,

```

value.hour, val  
ue.min, value.sec)  
end

```
     return cast_to_time(value) if value.is_a?(Date) or

```

value.is\_a?(String)  
rescue nil  
@@ -116,7 +115,7 @@

```
   def self.string_to_time(value)
     if value.is_a?(DateTime)

```

- 

```
     return Time.mktime(value.year, value.mon, value.day,

```

value.hour, valu  
e.min, value.sec)

- 

```
     return DateTime.new(value.year, value.mon, value.day,

```

value.hour, val  
ue.min, value.sec)  
else  
super  
end

---- END PATCH ----

---

<div class="post-metadata">

**Author:** ![weyus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/7ab992/32.png) [@weyus](https://www.ruby-forum.com/u/weyus)\
**Post date:** [February 29, 2008, 6:04pm UTC](https://www.ruby-forum.com/t/patch-for-ar-sqlserver-adapter-to-allow-for-1970-datetimes/130492/2 "2008-02-29T18:04:18Z")

</div>

Wes,

Obie F. addressed this specifically in “The Rails Way.” You  
can override the mapping without having to dig into the adapter itself  
if you like. Drop the following into a \*.rb file and require it in  
your environment.rb:

require ‘date’  
class ActiveRecord::ConnectionAdapters::Column  
def self.string\_to\_time(string)  
return string unless string.is\_a?(String)  
time\_array = ParseDate.parsedate(string)[0…5]  
begin  
Time.send(Base.default\_timezone, \*time\_array)  
rescue  
DateTime.new(\*time\_array) rescue nil  
end  
end  
end

Obviously having this self contained and out of a gem (that you might  
update in the future!) has its advantages.

As for why Time instead of DateTime… performance. Time is running  
on the bare steel (in C) whereas DateTime is comparatively slower as a  
pure Ruby implementation. That’s why the workaround above defers to  
Time if possible.

On Feb 28, 1:27 pm, Wes G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![weyus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/7ab992/32.png) [@weyus](https://www.ruby-forum.com/u/weyus)\
**Post date:** [March 4, 2008, 5:51pm UTC](https://www.ruby-forum.com/t/patch-for-ar-sqlserver-adapter-to-allow-for-1970-datetimes/130492/3 "2008-03-04T17:51:21Z")

</div>

Thanks - this is good info.

I don’t agree with favoring Time since it clashes with the expectation  
of what SQL Server datetimes can hold. Isn’t the rule “make it right,  
then make it fast?” As it stands, we’re crippling the datetime range of  
SQL Server because of Ruby performance issues.

Perhaps the adapter should support both type mappings, and default to  
the DateTime mapping, and provide a configurable switch that can be set  
to favor the Time mapping. That way, the functionality of the datetime  
column is intact by default and people who only deal with dates \> 1970  
can still get the performance boost if they want it.

Wes

---

<div class="post-metadata">

**Author:** ![weyus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/7ab992/32.png) [@weyus](https://www.ruby-forum.com/u/weyus)\
**Post date:** [March 4, 2008, 9:51pm UTC](https://www.ruby-forum.com/t/patch-for-ar-sqlserver-adapter-to-allow-for-1970-datetimes/130492/4 "2008-03-04T21:51:21Z")

</div>

Trust me, I feel the pain. I’m… well, let’s just say my b’day lies  
outside the range that Date supports and I constantly run into issues  
trying to display how old I am.  
🙂

Hopefully the implementation of DateTime will improve soon so that it  
can become the default.

On Mar 4, 11:51 am, Wes G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
