Skip to content

Instantly share code, notes, and snippets.

@atonse
Created February 12, 2011 22:30
Show Gist options
  • Save atonse/824197 to your computer and use it in GitHub Desktop.
Save atonse/824197 to your computer and use it in GitHub Desktop.
Returns the GMT offset for US Eastern Time based on timestamp for the last 30 years
module DSTCalculations
@@dst_years = [
["4/3/1966", "10/30/1966"],
["4/2/1972", "10/29/1972"],
["4/1/1973", "10/28/1973"],
["4/7/1974", "10/27/1974"],
["4/6/1975", "10/26/1975"],
["4/4/1976", "10/31/1976"],
["4/3/1977", "10/30/1977"],
["4/2/1978", "10/29/1978"],
["4/1/1979", "10/28/1979"],
["4/6/1980", "10/26/1980"],
["4/5/1981", "10/25/1981"],
["4/4/1982", "10/31/1982"],
["4/3/1983", "10/30/1983"],
["4/1/1984", "10/28/1984"],
["4/7/1985", "10/27/1985"],
["4/6/1986", "10/26/1986"],
["4/5/1987", "10/25/1987"],
["4/3/1988", "10/30/1988"],
["4/2/1989", "10/29/1989"],
["4/1/1990", "10/28/1990"],
["4/7/1991", "10/27/1991"],
["4/5/1992", "10/25/1992"],
["4/4/1993", "10/31/1993"],
["4/3/1994", "10/30/1994"],
["4/2/1995", "10/29/1995"],
["4/7/1996", "10/27/1996"],
["4/6/1997", "10/26/1997"],
["4/5/1998", "10/25/1998"],
["4/4/1999", "10/31/1999"],
['4/2/2000', '10/29/2000'],
['4/1/2001', '10/28/2001'],
['4/7/2002', '10/27/2002'],
['4/6/2003', '10/26/2003'],
['4/4/2004', '10/31/2004'],
['4/3/2005', '10/30/2005'],
['4/2/2006', '10/29/2006'],
['3/11/2007', '11/4/2007'],
['3/9/2008', '11/2/2008'],
['3/8/2009', '11/1/2009'],
['3/14/2010', '11/7/2010'],
['3/13/2011', '11/6/2011']
]
def dst_offset(time)
if ((time.year != 1966 && time.year < 1972) || time.year > 2011)
puts 'invalid year' and return nil
end
idx = (time.year == 1966) ? 0 : (time.year - 1971)
years = @@dst_years[idx]
year_dst_start = DateTime.parse(years.first + " 02:00")
year_dst_end = DateTime.parse(years.second + " 02:00")
#puts "time = #{time}, year_dst_start = #{year_dst_start}, year_dst_end = #{year_dst_end}"
(time >= year_dst_start && time < year_dst_end) ? 4 : 5
end
end
class DSTCalculationsTest < ActiveSupport::TestCase
include DSTCalculations
EDT = 4
EST = 5
1972.upto(2011) do |i|
should "return edt for 6/1/#{i}" do
assert_equal EDT, dst_offset(DateTime.civil(i, 6, 1, rand(23), rand(59), 0))
end
end
should 'return est for anytime in march pre-2007' do
2000.upto(2006) do |i|
assert_equal EST, dst_offset(DateTime.civil(i, 3, rand(15) + 15, rand(23), rand(59), 0))
end
end
# Bush switchover
should 'return edt for last 3 weeks in march 2007-onwards' do
2007.upto(2011) do |i|
assert_equal EDT, dst_offset(DateTime.civil(i, 3, 20, 2, 0, 0))
end
end
# time boundaries
should 'return est at 1:59 am on the start boundary' do
assert_equal EST, dst_offset(DateTime.civil(2005, 4, 3, 1, 59, 0))
assert_equal EST, dst_offset(DateTime.civil(2005, 4, 3, 1, 59, 59))
end
should 'return edt at 2:00 am on the start boundary' do
assert_equal EDT, dst_offset(DateTime.civil(2005, 4, 3, 2, 0, 0))
assert_equal EDT, dst_offset(DateTime.civil(2005, 4, 3, 3, 0, 0))
end
should 'return edt at 1:59 am on the end boundary' do
assert_equal EDT, dst_offset(DateTime.civil(2009, 11, 1, 1, 59, 0))
assert_equal EDT, dst_offset(DateTime.civil(2009, 11, 1, 1, 59, 59))
end
should 'return est at 2:00 am on the end boundary' do
assert_equal EST, dst_offset(DateTime.civil(2009, 11, 1, 2, 0, 0))
assert_equal EST, dst_offset(DateTime.civil(2009, 11, 1, 3, 0, 0))
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment