Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 9149

Show
Ignore:
Timestamp:
03/30/08 22:24:35 (3 months ago)
Author:
gbuesing
Message:

Bundling abbreviated version of TZInfo gem 0.3.8: only the classes and zone definitions required to support Rails time zone features are included. If a recent version of the full TZInfo gem is installed, this will take precedence over the bundled version

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/activesupport/CHANGELOG

    r9108 r9149  
    11*SVN* 
     2 
     3* Bundling abbreviated version of TZInfo gem 0.3.8: only the classes and zone definitions required to support Rails time zone features are included. If a recent version of the full TZInfo gem is installed, this will take precedence over the bundled version [Geoff Buesing] 
    24 
    35* TimeWithZone#marshal_load does zone lookup via Time.get_zone, so that tzinfo/Olson identifiers are handled [Geoff Buesing] 
  • trunk/activesupport/lib/active_support/time_with_zone.rb

    r9108 r9149  
     1require 'tzinfo' 
    12module ActiveSupport 
    23  # A Time-like class that can represent a time in any time zone. Necessary because standard Ruby Time instances are  
  • trunk/activesupport/lib/active_support/values/time_zone.rb

    r9107 r9149  
    11class TimeZone 
     2  # Keys are Rails TimeZone names, values are TZInfo identifiers 
    23  MAPPING = { 
    34    "International Date Line West" => "Pacific/Midway", 
     
    4142    "Casablanca"                   => "Africa/Casablanca", 
    4243    "Monrovia"                     => "Africa/Monrovia", 
    43     "UTC"                          => "UTC", 
     44    "UTC"                          => "Etc/UTC", 
    4445    "Belgrade"                     => "Europe/Belgrade", 
    4546    "Bratislava"                   => "Europe/Bratislava", 
     
    9495    "Karachi"                      => "Asia/Karachi", 
    9596    "Tashkent"                     => "Asia/Tashkent", 
    96     "Chennai"                      => "Asia/Calcutta", 
    97     "Kolkata"                      => "Asia/Calcutta", 
    98     "Mumbai"                       => "Asia/Calcutta", 
    99     "New Delhi"                    => "Asia/Calcutta", 
     97    "Chennai"                      => "Asia/Kolkata", 
     98    "Kolkata"                      => "Asia/Kolkata", 
     99    "Mumbai"                       => "Asia/Kolkata", 
     100    "New Delhi"                    => "Asia/Kolkata", 
    100101    "Kathmandu"                    => "Asia/Katmandu", 
    101102    "Astana"                       => "Asia/Dhaka", 
     
    180181    "(UTC#{formatted_offset}) #{name}" 
    181182  end 
    182  
    183   begin # the following methods depend on the tzinfo gem 
    184     require_library_or_gem "tzinfo" unless Object.const_defined?(:TZInfo) 
    185     raise LoadError unless TZInfo.const_defined?(:TimeOrDateTime) 
    186183     
    187     # Method for creating new ActiveSupport::TimeWithZone instance in time zone of +self+ from given values. Example: 
    188     # 
    189     #   Time.zone = "Hawaii"                      # => "Hawaii" 
    190     #   Time.zone.local(2007, 2, 1, 15, 30, 45)   # => Thu, 01 Feb 2007 15:30:45 HST -10:00 
    191     def local(*args) 
    192       time = Time.utc_time(*args) 
    193       ActiveSupport::TimeWithZone.new(nil, self, time) 
    194     end 
    195  
    196     # Method for creating new ActiveSupport::TimeWithZone instance in time zone of +self+ from number of seconds since the Unix epoch. Example: 
    197     # 
    198     #   Time.zone = "Hawaii"        # => "Hawaii" 
    199     #   Time.utc(2000).to_f         # => 946684800.0 
    200     #   Time.zone.at(946684800.0)   # => Fri, 31 Dec 1999 14:00:00 HST -10:00 
    201     def at(secs) 
    202       utc = Time.at(secs).utc rescue DateTime.civil(1970).since(secs) 
    203       utc.in_time_zone(self) 
    204     end 
    205      
    206     # Method for creating new ActiveSupport::TimeWithZone instance in time zone of +self+ from parsed string. Example: 
    207     # 
    208     #   Time.zone = "Hawaii"                      # => "Hawaii" 
    209     #   Time.zone.parse('1999-12-31 14:00:00')    # => Fri, 31 Dec 1999 14:00:00 HST -10:00 
    210     # 
    211     # If upper components are missing from the string, they are supplied from TimeZone#now: 
    212     # 
    213     #   Time.zone.now                 # => Fri, 31 Dec 1999 14:00:00 HST -10:00 
    214     #   Time.zone.parse('22:30:00')   # => Fri, 31 Dec 1999 22:30:00 HST -10:00 
    215     def parse(str, now=now) 
    216       time = Time.parse(str, now) rescue DateTime.parse(str) 
    217       ActiveSupport::TimeWithZone.new(nil, self, time) 
    218     end 
    219      
    220     # Returns an ActiveSupport::TimeWithZone instance representing the current time 
    221     # in the time zone represented by +self+. Example: 
    222     # 
    223     #   Time.zone = 'Hawaii'  # => "Hawaii" 
    224     #   Time.zone.now         # => Wed, 23 Jan 2008 20:24:27 HST -10:00 
    225     def now 
    226       Time.now.utc.in_time_zone(self) 
    227     end 
    228  
    229     # Return the current date in this time zone. 
    230     def today 
    231       tzinfo.now.to_date 
    232     end 
    233  
    234     # Adjust the given time to the simultaneous time in the time zone represented by +self+. Returns a  
    235     # Time.utc() instance -- if you want an ActiveSupport::TimeWithZone instance, use Time#in_time_zone() instead. 
    236     def utc_to_local(time) 
    237       tzinfo.utc_to_local(time) 
    238     end 
    239      
    240     # Adjust the given time to the simultaneous time in UTC. Returns a Time.utc() instance. 
    241     def local_to_utc(time, dst=true) 
    242       tzinfo.local_to_utc(time, dst) 
    243     end 
    244  
    245     # Available so that TimeZone instances respond like TZInfo::Timezone instances 
    246     def period_for_utc(time) 
    247       tzinfo.period_for_utc(time) 
    248     end 
    249  
    250     # Available so that TimeZone instances respond like TZInfo::Timezone instances 
    251     def period_for_local(time, dst=true) 
    252       tzinfo.period_for_local(time, dst) 
    253     end 
    254      
    255     def tzinfo 
    256       @tzinfo ||= TZInfo::Timezone.get(MAPPING[name]) 
    257     end 
    258      
    259   rescue LoadError # Tzinfo gem is not available 
    260     # re-raise LoadError only when a tzinfo-dependent method is called: 
    261     %w(local at parse now today utc_to_local local_to_utc period_for_utc period_for_local tzinfo).each do |method| 
    262       define_method(method) {|*args| raise LoadError, "TZInfo version >= 0.2 is required for TimeZone##{method}(). `gem install tzinfo` and try again."} 
    263     end 
     184  # Method for creating new ActiveSupport::TimeWithZone instance in time zone of +self+ from given values. Example: 
     185  # 
     186  #   Time.zone = "Hawaii"                      # => "Hawaii" 
     187  #   Time.zone.local(2007, 2, 1, 15, 30, 45)   # => Thu, 01 Feb 2007 15:30:45 HST -10:00 
     188  def local(*args) 
     189    time = Time.utc_time(*args) 
     190    ActiveSupport::TimeWithZone.new(nil, self, time) 
     191  end 
     192 
     193  # Method for creating new ActiveSupport::TimeWithZone instance in time zone of +self+ from number of seconds since the Unix epoch. Example: 
     194  # 
     195  #   Time.zone = "Hawaii"        # => "Hawaii" 
     196  #   Time.utc(2000).to_f         # => 946684800.0 
     197  #   Time.zone.at(946684800.0)   # => Fri, 31 Dec 1999 14:00:00 HST -10:00 
     198  def at(secs) 
     199    utc = Time.at(secs).utc rescue DateTime.civil(1970).since(secs) 
     200    utc.in_time_zone(self) 
     201  end 
     202   
     203  # Method for creating new ActiveSupport::TimeWithZone instance in time zone of +self+ from parsed string. Example: 
     204  # 
     205  #   Time.zone = "Hawaii"                      # => "Hawaii" 
     206  #   Time.zone.parse('1999-12-31 14:00:00')    # => Fri, 31 Dec 1999 14:00:00 HST -10:00 
     207  # 
     208  # If upper components are missing from the string, they are supplied from TimeZone#now: 
     209  # 
     210  #   Time.zone.now                 # => Fri, 31 Dec 1999 14:00:00 HST -10:00 
     211  #   Time.zone.parse('22:30:00')   # => Fri, 31 Dec 1999 22:30:00 HST -10:00 
     212  def parse(str, now=now) 
     213    time = Time.parse(str, now) rescue DateTime.parse(str) 
     214    ActiveSupport::TimeWithZone.new(nil, self, time) 
     215  end 
     216   
     217  # Returns an ActiveSupport::TimeWithZone instance representing the current time 
     218  # in the time zone represented by +self+. Example: 
     219  # 
     220  #   Time.zone = 'Hawaii'  # => "Hawaii" 
     221  #   Time.zone.now         # => Wed, 23 Jan 2008 20:24:27 HST -10:00 
     222  def now 
     223    Time.now.utc.in_time_zone(self) 
     224  end 
     225 
     226  # Return the current date in this time zone. 
     227  def today 
     228    tzinfo.now.to_date 
     229  end 
     230 
     231  # Adjust the given time to the simultaneous time in the time zone represented by +self+. Returns a  
     232  # Time.utc() instance -- if you want an ActiveSupport::TimeWithZone instance, use Time#in_time_zone() instead. 
     233  def utc_to_local(time) 
     234    tzinfo.utc_to_local(time) 
     235  end 
     236   
     237  # Adjust the given time to the simultaneous time in UTC. Returns a Time.utc() instance. 
     238  def local_to_utc(time, dst=true) 
     239    tzinfo.local_to_utc(time, dst) 
     240  end 
     241 
     242  # Available so that TimeZone instances respond like TZInfo::Timezone instances 
     243  def period_for_utc(time) 
     244    tzinfo.period_for_utc(time) 
     245  end 
     246 
     247  # Available so that TimeZone instances respond like TZInfo::Timezone instances 
     248  def period_for_local(time, dst=true) 
     249    tzinfo.period_for_local(time, dst) 
     250  end 
     251   
     252  def tzinfo 
     253    @tzinfo ||= TZInfo::Timezone.get(MAPPING[name]) 
    264254  end 
    265255 
  • trunk/activesupport/lib/active_support/vendor.rb

    r8546 r9149  
    1919  $:.unshift "#{File.dirname(__FILE__)}/vendor/memcache-client-1.5.0" 
    2020end 
     21 
     22begin 
     23  gem 'tzinfo', '~> 0.3.8' 
     24rescue Gem::LoadError 
     25  $:.unshift "#{File.dirname(__FILE__)}/vendor/tzinfo-0.3.8" 
     26end 
  • trunk/activesupport/Rakefile

    r9054 r9149  
    8686  rubyforge.add_release(PKG_NAME, PKG_NAME, "REL #{PKG_VERSION}", *packages) 
    8787end 
     88 
     89 
     90require 'lib/active_support/values/time_zone' 
     91 
     92namespace :tzinfo do 
     93  desc "Update bundled tzinfo gem. Only copies the subset of classes and definitions required to support Rails time zone features." 
     94  task :update => ['tzinfo:copy_classes', 'tzinfo:copy_definitions'] do 
     95    Rake::Task['tzinfo:cleanup_tmp'].invoke 
     96  end 
     97   
     98  task :unpack_gem do 
     99    mkdir_p "tmp" 
     100    cd "tmp" 
     101    sh "gem unpack --version #{ENV['VERSION'] || "'> 0'"} tzinfo" 
     102    cd ".." 
     103  end 
     104   
     105  task :copy_classes => :unpack_gem do 
     106    mkdir_p "#{destination_path}/tzinfo" 
     107    cp "#{tmp_path}/lib/tzinfo.rb", destination_path 
     108    comment_requires_for_excluded_classes!('tzinfo.rb') 
     109    files = FileList["#{tmp_path}/lib/tzinfo/*.rb"] 
     110    files.each do |file| 
     111      filename = File.basename(file) 
     112      unless excluded_classes.include? filename.sub(/.rb$/, '') 
     113        cp "#{tmp_path}/lib/tzinfo/#{filename}", "#{destination_path}/tzinfo" 
     114        comment_requires_for_excluded_classes!("tzinfo/#{filename}") 
     115      end 
     116    end 
     117  end 
     118   
     119  task :copy_definitions => :unpack_gem do 
     120    definitions_path = "#{destination_path}/tzinfo/definitions/" 
     121    mkdir_p definitions_path 
     122    TimeZone::MAPPING.values.each do |zone| 
     123      subdir = nil 
     124      if /\// === zone 
     125        subdir = zone.sub(/\w+$/, '') 
     126        mkdir_p "#{definitions_path}/#{subdir}" 
     127      end 
     128      cp "#{tmp_path}/lib/tzinfo/definitions/#{zone}.rb", "#{definitions_path}/#{subdir}" 
     129    end 
     130  end 
     131 
     132  task :cleanup_tmp do 
     133    rm_rf "tmp" 
     134  end 
     135   
     136  def comment_requires_for_excluded_classes!(file) 
     137    lines = open("#{destination_path}/#{file}") {|f| f.readlines} 
     138    updated = false 
     139     
     140    new_lines = [] 
     141    lines.each do |line| 
     142      if Regexp.new("require 'tzinfo/(#{excluded_classes.join('|')})'") === line 
     143        updated = true 
     144        new_lines << "# #{line}" 
     145      else 
     146        new_lines << line 
     147      end 
     148    end 
     149     
     150    if updated 
     151      open("#{destination_path}/#{file}", "w") {|f| f.write(new_lines.join)} 
     152    end 
     153  end 
     154   
     155  def version 
     156    ENV['VERSION'] ||= get_unpacked_version 
     157  end 
     158   
     159  def get_unpacked_version 
     160    m = (FileList["tmp/tzinfo-*"].to_s.match /\d+\.\d+\.\d+/) 
     161    m ? m[0] : raise(LoadError, "TZInfo gem must be installed locally. `gem install tzinfo` and try again") 
     162  end 
     163   
     164  def tmp_path 
     165    "tmp/tzinfo-#{version}" 
     166  end 
     167   
     168  def destination_path 
     169    "lib/active_support/vendor/tzinfo-#{version}" 
     170  end 
     171   
     172  def excluded_classes 
     173    %w(country country_index_definition country_info country_timezone tzdataparser) 
     174  end 
     175end 
  • trunk/activesupport/test/abstract_unit.rb

    r9071 r9149  
    2424unless defined? uses_tzinfo 
    2525  def uses_tzinfo(test_name, &block) 
    26     uses_gem('tzinfo', test_name, '>= 0.2.0', &block) 
     26    yield #TZInfo is now bundled 
    2727  end 
    2828end