From eschwartz at comverge.com Tue Oct 4 14:09:25 2011 From: eschwartz at comverge.com (Eric Schwartz) Date: Tue, 4 Oct 2011 18:09:25 +0000 Subject: [TZInfo-users] DST start/stop times? Message-ID: I need to program a device that tracks DST by setting start/stop times, but I don't see a way to get at that information from TZInfo... am I missing something or is there no way other than iterating over every day to figure out when DST starts and ends each year? -=Eric -- Eric Schwartz Software Engineer, Comverge, Inc w: 720.253.0277 m: 630.447.9675 e: eschwartz at comverge.com From phil.ross at gmail.com Tue Oct 4 19:13:03 2011 From: phil.ross at gmail.com (Philip Ross) Date: Wed, 5 Oct 2011 00:13:03 +0100 Subject: [TZInfo-users] DST start/stop times? In-Reply-To: References: Message-ID: Hi Eric, On 4 October 2011 19:09, Eric Schwartz wrote: > I need to program a device that tracks DST by setting start/stop times, but I don't see a way to get at that information from TZInfo... am I missing something or is there no way other than iterating over every day to figure out when DST starts and ends each year? Your best bet would be to use the period_for_utc method. For a given date and time, this method will return a TimezonePeriod object that will give you the UTC offset at that time and when the period starts and ends (i.e. the previous and next daylight savings transitions). You can find the previous or next TimezonePeriod by either subtracting a second from the start time or adding a second to the end time and calling period_for_utc again. The following example will print all the daylight savings and standard time periods for New York in the years 2011 to 2020: zone = TZInfo::Timezone.get('America/New_York') start_year = 2011 end_year = 2020 period = zone.period_for_utc(Time.utc(start_year, 1, 1)) while period offset_hours = period.utc_total_offset / 3600 offset_mins = period.utc_total_offset % 3600 offset_sign = period.utc_total_offset >= 0 ? '+' : '' offset = "#{offset_sign}#{offset_hours}:#{offset_mins.to_s.rjust(2, '0')}" puts "GMT#{offset} #{period.abbreviation} " + "from #{period.utc_start} #{period.utc_end ? "until #{period.utc_end}" : ''}" # If this period has an end time (i.e. daylight savings hasn't been abolished), # add a second to the end time and find the next period. period = period.utc_end && period.utc_end.year <= end_year ? zone.period_for_utc(period.utc_end + Rational(1,86400)) : nil end Kind regards, Phil From eschwartz at comverge.com Wed Oct 5 11:11:28 2011 From: eschwartz at comverge.com (Eric Schwartz) Date: Wed, 5 Oct 2011 15:11:28 +0000 Subject: [TZInfo-users] DST start/stop times? In-Reply-To: References: Message-ID: Thanks; that was exactly what I needed. In my Copious Free Time(tm), I would be inclined to wrap that up into a method along these lines def TZInfo::Timezone#period_for_dst(year=Time.now.year) # stuff end if that's a patch you might be interested in. No worries if not; I can understand wanting to keep such a widely-used library lean. -=Eric -- Eric Schwartz Software Engineer, Comverge, Inc w: 720.253.0277 m: 630.447.9675 e: eschwartz at comverge.com On Oct 4, 2011, at 5:13 PM, Philip Ross wrote: > Hi Eric, > > On 4 October 2011 19:09, Eric Schwartz wrote: >> I need to program a device that tracks DST by setting start/stop times, but I don't see a way to get at that information from TZInfo... am I missing something or is there no way other than iterating over every day to figure out when DST starts and ends each year? > > Your best bet would be to use the period_for_utc method. For a given > date and time, this method will return a TimezonePeriod object that > will give you the UTC offset at that time and when the period starts > and ends (i.e. the previous and next daylight savings transitions). > > You can find the previous or next TimezonePeriod by either subtracting > a second from the start time or adding a second to the end time and > calling period_for_utc again. > > The following example will print all the daylight savings and standard > time periods for New York in the years 2011 to 2020: > > zone = TZInfo::Timezone.get('America/New_York') > start_year = 2011 > end_year = 2020 > > period = zone.period_for_utc(Time.utc(start_year, 1, 1)) > > while period > offset_hours = period.utc_total_offset / 3600 > offset_mins = period.utc_total_offset % 3600 > offset_sign = period.utc_total_offset >= 0 ? '+' : '' > offset = "#{offset_sign}#{offset_hours}:#{offset_mins.to_s.rjust(2, '0')}" > > puts "GMT#{offset} #{period.abbreviation} " + > "from #{period.utc_start} #{period.utc_end ? > "until #{period.utc_end}" : ''}" > > # If this period has an end time (i.e. daylight savings hasn't been > abolished), > # add a second to the end time and find the next period. > period = period.utc_end && period.utc_end.year <= end_year ? > zone.period_for_utc(period.utc_end + Rational(1,86400)) : > nil > end > > > Kind regards, > > Phil > _______________________________________________ > TZInfo-users mailing list > TZInfo-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/tzinfo-users From phil.ross at gmail.com Sun Oct 9 11:18:15 2011 From: phil.ross at gmail.com (Philip Ross) Date: Sun, 9 Oct 2011 16:18:15 +0100 Subject: [TZInfo-users] DST start/stop times? In-Reply-To: References: Message-ID: Hi Eric, On 5 October 2011 16:11, Eric Schwartz wrote: > Thanks; that was exactly what I needed. In my Copious Free Time(tm), I would be inclined to wrap that up into a method along these lines > > def TZInfo::Timezone#period_for_dst(year=Time.now.year) > ?# stuff > end > > if that's a patch you might be interested in. No worries if not; I can understand wanting to keep such a widely-used library lean. Yes, it seems like something along these lines would be useful, so I'd be interested in a patch if you can find the time. I think methods that returned an array of TimezonePeriod objects between two dates (one method for UTC and another for local time) would be more generally useful than just returning the periods in a year: def TZInfo::Timezone#periods_between_utc(utc_from, utc_to) # stuff end def TZInfo::Timezone#periods_between_local(local_from, local_to, dst = Timezone.default_dst) # stuff end The from and to parameters will have to accept Time, DateTime and Numeric parameters (see TZInfo::TimeOrDateTime). The local time version of the method will have to resolve ambiguous local times (see TZInfo::Timezone#period_for_local). Kind regards, Phil