<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Segment7: Timezones 1, Rails 0</title>
    <link>http://blog.segment7.net/articles/2006/07/03/timezones-1-rails-0</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>The Blog</description>
    <item>
      <title>Timezones 1, Rails 0</title>
      <description>&lt;p&gt;For &lt;a href="http://trackmap.robotcoop.com"&gt;Trackmap&lt;/a&gt; I need to take the time a picture was taken and a user supplied time zone and convert that to a correctly offset time.  Since Flickr won't give me a time zone (cameras don't record them) I ask the user.  If they say Mountain time I need to create a time that is correct for the server's clock (in my case Pacific Time).

&lt;h3&gt;Rails TimeZone&lt;/h3&gt;

&lt;p&gt;When I originally wrote the code back in November and December of 2005 I noticed that Rails provides the handy &lt;a href="http://api.rubyonrails.org/classes/TimeZone.html"&gt;TimeZone&lt;/a&gt; class which worked great!  Rails gave me handy offsets that I could use to adjust times correctly.

&lt;p&gt;Then April rolled around, my clocks switched to daylight savings time, and Rails' TimeZone class broke.  TimeZone thought the offset for Pacific time was -8 hours instead of -7 hours giving inaccurate conversions.  I filed a &lt;a href="http://dev.rubyonrails.org/ticket/4551"&gt;ticket&lt;/a&gt;, but it was closed WONTFIX (the breakage &lt;a href="http://dev.rubyonrails.org/ticket/4561"&gt;remains undocumented&lt;/a&gt;).  I was, however, pointed at the &lt;a href="http://www.agilewebdevelopment.com/plugins/show/129"&gt;TZInfo Timezone plugin&lt;/a&gt;.  Since April I haven't had much time to work on Trackmap, so I left it broken.

&lt;h3&gt;TZInfo Timezone Plugin&lt;/h3&gt;

&lt;p&gt;On Friday I switched over to the plugin and found it provides incorrect UTC offsets as a misfeature:

&lt;pre&gt;&lt;samp&gt;&gt;&gt; tzt = TimeZone['Pacific Time (US &amp; Canada)']
=&gt; #&lt;TzinfoTimezone:0x24704e4 @name="Pacific Time (US &amp; Canada)", @utc_offset=-28800&gt;
&gt;&gt; tzt.utc_offset
=&gt; -28800
&gt;&gt; Time.now.gmtoff
=&gt; -25200&lt;/samp&gt;&lt;/pre&gt;

&lt;p&gt;While the TZinfo Timezone plugin will convert times between known time zones, it doesn't provide a way of interpreting a user-input time so you get a correctly offset time, making it only half of a fix for Rails' TimeZone.

&lt;h3&gt;Interpreting Times&lt;/h3&gt;

&lt;p&gt;To handle user-input times you must use TZInfo::Timezone#period_for_utc or TZInfo::Timezone#period_for_local to retrieve the correct UTC offset.  You can retrieve the TZInfo::Timezone object from TzinfoTimezone#tzinfo (which is all the utility the plugin provides).

&lt;p&gt;Correct conversions require some work.  I chose to do it this way:

&lt;ol&gt;
&lt;li&gt;Create a Time using the user-supplied time
&lt;li&gt;Get the local TZInfo::TimezonePeriod for the timestamp
&lt;ul&gt;
&lt;li&gt;If a TimezonePeriod doesn't exist for the given time, get the utc period
&lt;li&gt;If the TimezonePeriod is ambiguous, choose standard time
&lt;/ul&gt;
&lt;li&gt;Use TimezonePeriod#to_utc to adjust the Time to a UTC Time
&lt;/ol&gt;

&lt;p&gt;A TimezonePeriod won't exist during the standard time to daylight savings time switch, the user probably chose the wrong time zone.  The TimezonePeriod is ambiguous during the daylight savings time to standard time switch since the user's clock traverses the same time period twice.  I chose to have strange behavior over failing.  If the user notices and emails me I can say they probably fat-fingered something.

&lt;h3&gt;Rails Strikes Back&lt;/h3&gt;

&lt;p&gt;Having time interpretation finished I thought I was done.  My database has &lt;a href="http://www.postgresql.org/docs/8.0/static/datatype-datetime.html"&gt;timestamp with time zone&lt;/a&gt; columns so the database and Rails should just figure things out.  Turns out &lt;a href="http://dev.rubyonrails.org/ticket/4492"&gt;Rails still can't handle timestamp with time zone&lt;/a&gt; despite having a patch in the bug tracking database for three months.

&lt;p&gt;Instead of applying the patch (which I'd have to do twice, once on my laptop and once online, and for every Rails upgrade until it gets checked in), I adapted it into a 75 line extension to the PostgreSQL connection adapter.  Maybe I'll make a plugin out of it while I'm waiting.

&lt;p&gt;I'd like to think I was unlucky and the patch just got &lt;a href="http://lists.rubyonrails.org/pipermail/rails-core/2006-June/001586.html"&gt;lost in the shuffle&lt;/a&gt;, but a look at the bug database makes me think that lost tickets happen frequently.  One quarter of Rails' defect tickets are open (1098 out of 4034) so I don't see how anybody can figure out what tickets are invalid, valid, duplicate, fixed but not closed, or outright bogus.  Furthermore, the amount of bugmail generated must be overwhelming.

&lt;p&gt;The Rails core team should do what &lt;a href="http://www.mozilla.org"&gt;Mozilla&lt;/a&gt; did back in its early days and organize a bug day.  Get a bunch of people on IRC to crawl through the open tickets to validate, cross-reference, prioritize and categorize bugs.  (Mozilla even made it a weekly event with prizes!)  Having a clean bug database will prevent useful patches from falling on the floor and rotting to the point that their authors must re-write them.
</description>
      <pubDate>Mon, 03 Jul 2006 17:17:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:e39ab79f-708d-4dab-82e1-070c1d9c3161</guid>
      <author>drbrain@segment7.net (Eric Hodel)</author>
      <link>http://blog.segment7.net/articles/2006/07/03/timezones-1-rails-0</link>
      <category>Hacking</category>
      <category>Rails</category>
      <category>Trackmap</category>
    </item>
    <item>
      <title>"Timezones 1, Rails 0" by Eric Hodel</title>
      <description>&lt;p&gt;It should get fixed, but it &lt;a href="http://dev.rubyonrails.org/ticket/4551" rel="nofollow"&gt;won&amp;#8217;t be&lt;/a&gt;.  I don&amp;#8217;t know why they want to keep around something so broken that it is useless.&lt;/p&gt;</description>
      <pubDate>Fri, 21 Jul 2006 10:44:53 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:b12e04cf-126e-4156-936a-835dd7c0f316</guid>
      <link>http://blog.segment7.net/articles/2006/07/03/timezones-1-rails-0#comment-285</link>
    </item>
    <item>
      <title>"Timezones 1, Rails 0" by patrick</title>
      <description>&lt;p&gt;Thanks for this post&amp;#8230;I&amp;#8217;ve been trying to use the rails TimeZone class and it&amp;#8217;s been driving me nuts why it keeps giving me the wrong time&amp;#8230;&lt;/p&gt;


	&lt;p&gt;Surely tons of people should be having this problem and core should fix it???&lt;/p&gt;</description>
      <pubDate>Fri, 21 Jul 2006 07:08:41 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:d1b51fa7-d2d3-41ca-bd25-c3c835c6c248</guid>
      <link>http://blog.segment7.net/articles/2006/07/03/timezones-1-rails-0#comment-284</link>
    </item>
    <item>
      <title>"Timezones 1, Rails 0" by Eric Hodel</title>
      <description>&lt;p&gt;At the time Mozilla was still part of Netscape/AOL, so they gave away things like tshirts and mozilla dinosaur  plushies.  You had to do a ton of work to get a plushie, though.&lt;/p&gt;</description>
      <pubDate>Tue, 04 Jul 2006 00:22:42 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:371d7f50-6a49-4140-9047-99d7df0b1f97</guid>
      <link>http://blog.segment7.net/articles/2006/07/03/timezones-1-rails-0#comment-268</link>
    </item>
    <item>
      <title>"Timezones 1, Rails 0" by court3nay</title>
      <description>&lt;p&gt;I think corporate sponsorship would really work for this..!  Something like $8k in prizes was donated for railsday&amp;#8230;&lt;/p&gt;</description>
      <pubDate>Mon, 03 Jul 2006 22:28:02 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:832dfa32-64dd-4109-8a77-1ffd95f71ba2</guid>
      <link>http://blog.segment7.net/articles/2006/07/03/timezones-1-rails-0#comment-265</link>
    </item>
  </channel>
</rss>
