`
hideto
  • 浏览: 2686402 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

每天一剂Rails良药之tzinfo_timezone

    博客分类:
  • Ruby
阅读更多
Dealing With Time-zones一文中介绍了Rails的TimeZone类,它可以用来转换不同时区的本地时间
今天看看tzinfo_timezone插件,它是对TZInfo库的封装,我们需要首先运行gem install tzinfo来安装tzinfo
该插件安装了一个TimeZone类的replacement类,然后我们使用local_to_utf和utc_to_local方法来替代以前的adjust和unadjust方法
看看代码就清除了,首先是init.rb:
require 'tzinfo_timezone'

# remove the existing TimeZone constant
Object.send(:remove_const, :TimeZone)

# Use TzinfoTimezone as the TimeZone class
Object::TimeZone = TzinfoTimezone

注释已经很清除了,用TzinfoTimezone类来替换TimeZone类
然后就是lib/tzinfo_timezone.rb:
require 'tzinfo'

class TzinfoTimezone
  MAPPING = {
    "International Date Line West" => "Pacific/Midway",
    "Midway Island"                => "Pacific/Midway",
    "Samoa"                        => "Pacific/Pago_Pago",
    "Hawaii"                       => "Pacific/Honolulu",
    "Alaska"                       => "America/Juneau",
    "Pacific Time (US & Canada)"   => "America/Los_Angeles",
    "Tijuana"                      => "America/Tijuana",
    "Mountain Time (US & Canada)"  => "America/Denver",
    "Arizona"                      => "America/Phoenix",
    "Chihuahua"                    => "America/Chihuahua",
    "Mazatlan"                     => "America/Mazatlan",
    "Central Time (US & Canada)"   => "America/Chicago",
    "Saskatchewan"                 => "America/Regina",
    "Guadalajara"                  => "America/Mexico_City",
    "Mexico City"                  => "America/Mexico_City",
    "Monterrey"                    => "America/Monterrey",
    "Central America"              => "America/Guatemala",
    "Eastern Time (US & Canada)"   => "America/New_York",
    "Indiana (East)"               => "America/Indiana/Indianapolis",
    "Bogota"                       => "America/Bogota",
    "Lima"                         => "America/Lima",
    "Quito"                        => "America/Lima",
    "Atlantic Time (Canada)"       => "America/Halifax",
    "Caracas"                      => "America/Caracas",
    "La Paz"                       => "America/La_Paz",
    "Santiago"                     => "America/Santiago",
    "Newfoundland"                 => "America/St_Johns",
    "Brasilia"                     => "America/Argentina/Buenos_Aires",
    "Buenos Aires"                 => "America/Argentina/Buenos_Aires",
    "Georgetown"                   => "America/Argentina/San_Juan",
    "Greenland"                    => "America/Godthab",
    "Mid-Atlantic"                 => "Atlantic/South_Georgia",
    "Azores"                       => "Atlantic/Azores",
    "Cape Verde Is."               => "Atlantic/Cape_Verde",
    "Dublin"                       => "Europe/Dublin",
    "Edinburgh"                    => "Europe/Dublin",
    "Lisbon"                       => "Europe/Lisbon",
    "London"                       => "Europe/London",
    "Casablanca"                   => "Africa/Casablanca",
    "Monrovia"                     => "Africa/Monrovia",
    "Belgrade"                     => "Europe/Belgrade",
    "Bratislava"                   => "Europe/Bratislava",
    "Budapest"                     => "Europe/Budapest",
    "Ljubljana"                    => "Europe/Ljubljana",
    "Prague"                       => "Europe/Prague",
    "Sarajevo"                     => "Europe/Sarajevo",
    "Skopje"                       => "Europe/Skopje",
    "Warsaw"                       => "Europe/Warsaw",
    "Zagreb"                       => "Europe/Zagreb",
    "Brussels"                     => "Europe/Brussels",
    "Copenhagen"                   => "Europe/Copenhagen",
    "Madrid"                       => "Europe/Madrid",
    "Paris"                        => "Europe/Paris",
    "Amsterdam"                    => "Europe/Amsterdam",
    "Berlin"                       => "Europe/Berlin",
    "Bern"                         => "Europe/Berlin",
    "Rome"                         => "Europe/Rome",
    "Stockholm"                    => "Europe/Stockholm",
    "Vienna"                       => "Europe/Vienna",
    "West Central Africa"          => "Africa/Algiers",
    "Bucharest"                    => "Europe/Bucharest",
    "Cairo"                        => "Africa/Cairo",
    "Helsinki"                     => "Europe/Helsinki",
    "Kyev"                         => "Europe/Kiev",
    "Riga"                         => "Europe/Riga",
    "Sofia"                        => "Europe/Sofia",
    "Tallinn"                      => "Europe/Tallinn",
    "Vilnius"                      => "Europe/Vilnius",
    "Athens"                       => "Europe/Athens",
    "Istanbul"                     => "Europe/Istanbul",
    "Minsk"                        => "Europe/Minsk",
    "Jerusalem"                    => "Asia/Jerusalem",
    "Harare"                       => "Africa/Harare",
    "Pretoria"                     => "Africa/Johannesburg",
    "Moscow"                       => "Europe/Moscow",
    "St. Petersburg"               => "Europe/Moscow",
    "Volgograd"                    => "Europe/Moscow",
    "Kuwait"                       => "Asia/Kuwait",
    "Riyadh"                       => "Asia/Riyadh",
    "Nairobi"                      => "Africa/Nairobi",
    "Baghdad"                      => "Asia/Baghdad",
    "Tehran"                       => "Asia/Tehran",
    "Abu Dhabi"                    => "Asia/Muscat",
    "Muscat"                       => "Asia/Muscat",
    "Baku"                         => "Asia/Baku",
    "Tbilisi"                      => "Asia/Tbilisi",
    "Yerevan"                      => "Asia/Yerevan",
    "Kabul"                        => "Asia/Kabul",
    "Ekaterinburg"                 => "Asia/Yekaterinburg",
    "Islamabad"                    => "Asia/Karachi",
    "Karachi"                      => "Asia/Karachi",
    "Tashkent"                     => "Asia/Tashkent",
    "Chennai"                      => "Asia/Calcutta",
    "Kolkata"                      => "Asia/Calcutta",
    "Mumbai"                       => "Asia/Calcutta",
    "New Delhi"                    => "Asia/Calcutta",
    "Kathmandu"                    => "Asia/Katmandu",
    "Astana"                       => "Asia/Dhaka",
    "Dhaka"                        => "Asia/Dhaka",
    "Sri Jayawardenepura"          => "Asia/Dhaka",
    "Almaty"                       => "Asia/Almaty",
    "Novosibirsk"                  => "Asia/Novosibirsk",
    "Rangoon"                      => "Asia/Rangoon",
    "Bangkok"                      => "Asia/Bangkok",
    "Hanoi"                        => "Asia/Bangkok",
    "Jakarta"                      => "Asia/Jakarta",
    "Krasnoyarsk"                  => "Asia/Krasnoyarsk",
    "Beijing"                      => "Asia/Shanghai",
    "Chongqing"                    => "Asia/Chongqing",
    "Hong Kong"                    => "Asia/Hong_Kong",
    "Urumqi"                       => "Asia/Urumqi",
    "Kuala Lumpur"                 => "Asia/Kuala_Lumpur",
    "Singapore"                    => "Asia/Singapore",
    "Taipei"                       => "Asia/Taipei",
    "Perth"                        => "Australia/Perth",
    "Irkutsk"                      => "Asia/Irkutsk",
    "Ulaan Bataar"                 => "Asia/Ulaanbaatar",
    "Seoul"                        => "Asia/Seoul",
    "Osaka"                        => "Asia/Tokyo",
    "Sapporo"                      => "Asia/Tokyo",
    "Tokyo"                        => "Asia/Tokyo",
    "Yakutsk"                      => "Asia/Yakutsk",
    "Darwin"                       => "Australia/Darwin",
    "Adelaide"                     => "Australia/Adelaide",
    "Canberra"                     => "Australia/Melbourne",
    "Melbourne"                    => "Australia/Melbourne",
    "Sydney"                       => "Australia/Sydney",
    "Brisbane"                     => "Australia/Brisbane",
    "Hobart"                       => "Australia/Hobart",
    "Vladivostok"                  => "Asia/Vladivostok",
    "Guam"                         => "Pacific/Guam",
    "Port Moresby"                 => "Pacific/Port_Moresby",
    "Magadan"                      => "Asia/Magadan",
    "Solomon Is."                  => "Asia/Magadan",
    "New Caledonia"                => "Pacific/Noumea",
    "Fiji"                         => "Pacific/Fiji",
    "Kamchatka"                    => "Asia/Kamchatka",
    "Marshall Is."                 => "Pacific/Majuro",
    "Auckland"                     => "Pacific/Auckland",
    "Wellington"                   => "Pacific/Auckland",
    "Nuku'alofa"                   => "Pacific/Tongatapu"
  }

  attr_reader :name, :utc_offset

  # Create a new TzinfoTimezone object with the given name and offset. The
  # offset is the number of seconds that this time zone is offset from UTC
  # (GMT). Seconds were chosen as the offset unit because that is the unit that
  # Ruby uses to represent time zone offsets (see Time#utc_offset).
  def initialize(name, utc_offset)
    @name = name
    @utc_offset = utc_offset
  end

  # Returns the offset of this time zone as a formatted string, of the
  # format "+HH:MM". If the offset is zero, this returns the empty
  # string. If +colon+ is false, a colon will not be inserted into the
  # result.
  def formatted_offset(colon=true)
    utc_offset == 0 ? '' : offset(colon)
  end
  
  # Returns the offset of this time zone as a formatted string, of the
  # format "+HH:MM".
  def offset(colon=true)
    sign = (utc_offset < 0 ? -1 : 1)
    hours = utc_offset.abs / 3600
    minutes = (utc_offset.abs % 3600) / 60
    "%+03d%s%02d" % [ hours * sign, colon ? ":" : "", minutes ]
  end
  
  # Compute and return the current time, in the time zone represented by
  # +self+.
  def now
    tzinfo.now
  end

  # Return the current date in this time zone.
  def today
    now.to_date
  end

  # Adjust the given time to the time zone represented by +self+.
  def utc_to_local(time)
    tzinfo.utc_to_local(time)
  end

  def local_to_utc(time, dst=true)
    tzinfo.local_to_utc(time, dst)
  end

  # Adjust the given time to the time zone represented by +self+.
  # (Deprecated--use utc_to_local, instead.)
  alias :adjust :utc_to_local

  # Compare this time zone to the parameter. The two are comapred first on
  # their offsets, and then by name.
  def <=>(zone)
    result = (utc_offset <=> zone.utc_offset)
    result = (name <=> zone.name) if result == 0
    result
  end

  # Returns a textual representation of this time zone.
  def to_s
    "(GMT#{formatted_offset}) #{name}"
  end

  def tzinfo
    return @tzinfo if @tzinfo
    @tzinfo = MAPPING[name]
    if String === @tzinfo
      @tzinfo = TZInfo::Timezone.get(@tzinfo)
      MAPPING[name] = @tzinfo
    end
    @tzinfo
  end

  @@zones = nil

  class << self
    alias_method :create, :new

    # Return a TzinfoTimezone instance with the given name, or +nil+ if no
    # such TzinfoTimezone instance exists. (This exists to support the use of
    # this class with the #composed_of macro.)
    def new(name)
      self[name]
    end

    # Return an array of all TzinfoTimezone objects. There are multiple
    # TzinfoTimezone objects per time zone, in many cases, to make it easier
    # for users to find their own time zone.
    def all
      unless @@zones
        @@zones = []
        @@zones_map = {}
        [[-39_600, "International Date Line West", "Midway Island", "Samoa" ],
         [-36_000, "Hawaii" ],
         [-32_400, "Alaska" ],
         [-28_800, "Pacific Time (US & Canada)", "Tijuana" ],
         [-25_200, "Mountain Time (US & Canada)", "Chihuahua", "Mazatlan",
                   "Arizona" ],
         [-21_600, "Central Time (US & Canada)", "Saskatchewan", "Guadalajara",
                   "Mexico City", "Monterrey", "Central America" ],
         [-18_000, "Eastern Time (US & Canada)", "Indiana (East)", "Bogota",
                   "Lima", "Quito" ],
         [-14_400, "Atlantic Time (Canada)", "Caracas", "La Paz", "Santiago" ],
         [-12_600, "Newfoundland" ],
         [-10_800, "Brasilia", "Buenos Aires", "Georgetown", "Greenland" ],
         [ -7_200, "Mid-Atlantic" ],
         [ -3_600, "Azores", "Cape Verde Is." ],
         [      0, "Dublin", "Edinburgh", "Lisbon", "London", "Casablanca",
                   "Monrovia" ],
         [  3_600, "Belgrade", "Bratislava", "Budapest", "Ljubljana", "Prague",
                   "Sarajevo", "Skopje", "Warsaw", "Zagreb", "Brussels",
                   "Copenhagen", "Madrid", "Paris", "Amsterdam", "Berlin",
                   "Bern", "Rome", "Stockholm", "Vienna",
                   "West Central Africa" ],
         [  7_200, "Bucharest", "Cairo", "Helsinki", "Kyev", "Riga", "Sofia",
                   "Tallinn", "Vilnius", "Athens", "Istanbul", "Minsk",
                   "Jerusalem", "Harare", "Pretoria" ],
         [ 10_800, "Moscow", "St. Petersburg", "Volgograd", "Kuwait", "Riyadh",
                   "Nairobi", "Baghdad" ],
         [ 12_600, "Tehran" ],
         [ 14_400, "Abu Dhabi", "Muscat", "Baku", "Tbilisi", "Yerevan" ],
         [ 16_200, "Kabul" ],
         [ 18_000, "Ekaterinburg", "Islamabad", "Karachi", "Tashkent" ],
         [ 19_800, "Chennai", "Kolkata", "Mumbai", "New Delhi" ],
         [ 20_700, "Kathmandu" ],
         [ 21_600, "Astana", "Dhaka", "Sri Jayawardenepura", "Almaty",
                   "Novosibirsk" ],
         [ 23_400, "Rangoon" ],
         [ 25_200, "Bangkok", "Hanoi", "Jakarta", "Krasnoyarsk" ],
         [ 28_800, "Beijing", "Chongqing", "Hong Kong", "Urumqi",
                   "Kuala Lumpur", "Singapore", "Taipei", "Perth", "Irkutsk",
                   "Ulaan Bataar" ],
         [ 32_400, "Seoul", "Osaka", "Sapporo", "Tokyo", "Yakutsk" ],
         [ 34_200, "Darwin", "Adelaide" ],
         [ 36_000, "Canberra", "Melbourne", "Sydney", "Brisbane", "Hobart",
                   "Vladivostok", "Guam", "Port Moresby" ],
         [ 39_600, "Magadan", "Solomon Is.", "New Caledonia" ],
         [ 43_200, "Fiji", "Kamchatka", "Marshall Is.", "Auckland",
                   "Wellington" ],
         [ 46_800, "Nuku'alofa" ]].
        each do |offset, *places|
          places.each do |place|
            zone = create(place, offset)
            @@zones << zone
            @@zones_map[place] = zone
          end
        end
        @@zones.sort!
      end
      @@zones
    end

    # Locate a specific time zone object. If the argument is a string, it
    # is interpreted to mean the name of the timezone to locate. If it is a
    # numeric value it is either the hour offset, or the second offset, of the
    # timezone to find. (The first one with that offset will be returned.)
    # Returns +nil+ if no such time zone is known to the system.
    def [](arg)
      case arg
        when String
          all # force the zones to be loaded
          @@zones_map[arg]
        when Numeric
          arg *= 3600 if arg.abs <= 13
          all.find { |z| z.utc_offset == arg.to_i }
        else
          raise ArgumentError, "invalid argument to TzinfoTimezone[]: #{arg.inspect}"
      end
    end

    # A regular expression that matches the names of all time zones in
    # the USA.
    US_ZONES = /US|Arizona|Indiana|Hawaii|Alaska/

    # A convenience method for returning a collection of TzinfoTimezone objects
    # for time zones in the USA.
    def us_zones
      all.find_all { |z| z.name =~ US_ZONES }
    end
  end
end

其中定义了utc_to_local(time)和local_to_utc(time, dst=true)方法来做时区转换
分享到:
评论

相关推荐

    Rails101_by_rails4.0

    《Rails101_by_rails4.0》是一本专注于Rails 4.0.0版本和Ruby 2.0.0版本的自学教程书籍,它定位于中文读者,旨在成为学习Rails框架的参考教材。Rails(Ruby on Rails)是一个采用Ruby语言编写的开源Web应用框架,它...

    rails_apps_composer, 一个 gem,为 Rails 启动应用程序创建 Rails 应用程序模板.zip

    rails_apps_composer, 一个 gem,为 Rails 启动应用程序创建 Rails 应用程序模板 Rails 应用编辑器 Rails 应用程序编辑器 gem 安装一个 命令行 工具来从"食谱"的Collection 组装 Rails 应用程序。"你可以使用 rails_...

    rails_admin_acts_as_list:rails_admin插件以对记录进行排序

    介绍插件,用于对记录进行排序(使用 gem)安装要启用rails_admin_acts_as_list,请将以下内容添加到您的Gemfile : gem 'rails_admin_acts_as_list'gem 'rails_admin' 重要提示: rails_admin_acts_as_list之前必须...

    rails_semantic_logger, Rails 语义记录器用语义记录器替换 Rails 缺省记录器.zip

    rails_semantic_logger, Rails 语义记录器用语义记录器替换 Rails 缺省记录器 Rails 语义记录器 语义记录器用语义记录器替代 Rails 缺省记录器。http://github.com/rocketjob/rails_semantic_logger文档有关完整文档...

    Api-rails5_api_tutorial.zip

    Api-rails5_api_tutorial.zip,了解如何在michael hartl的rails 5教程上构建一个现代api立即在rails应用程序中构建一个api!(Rails 5版本),一个api可以被认为是多个软件设备之间通信的指导手册。例如,api可用于web...

    browser-timezone-rails:Rails引擎,将每个请求的Rails时区设置为浏览器时区

    //= require browser_timezone_rails/set_time_zone 而已! 无需其他配置,因为使用此gem可以完成所有工作,包括设置应用程序控制器以开始使用用户的区域。 怎么运行的 使用现代在cookie中设置浏览器的时区 警告:不...

    inspinia admin - v2.5 Rails_Full_Version

    "inspinia admin - v2.5 Rails_Full_Version" 是一个基于Rails框架构建的后台管理系统的完整版本。这个系统采用流行的Inspinia Admin模板,提供了丰富的功能和自定义选项,旨在帮助开发者快速构建高效、现代且用户...

    InspiniaAdmin 2.6.1 Rails_Full_Version

    在Rails_Full_Version压缩包中,包含了完整的源代码和必要的资源文件,开发者可以通过解压并导入到Rails项目中,按照官方文档进行配置和定制。同时,这个版本可能还包含了升级记录、更改日志和可能的bug修复,以保证...

    rails open_flash_chart

    "Rails Open Flash Chart" 是一个基于Ruby on Rails框架的库,用于在Web应用程序中生成交互式的Flash图表。这个库允许开发者轻松地创建各种统计图表,如折线图、柱状图、饼图等,以便更好地可视化数据。由于Flash在...

    RestFul_Rails_Dev_pdf_v_0.1.zip

    本资料“RestFul_Rails_Dev_pdf_v_0.1.zip”包含了《RESTful Rails Development》的翻译版,将深入探讨如何在Rails中实现RESTful的设计模式。 首先,RESTful设计的核心概念是资源(Resources)。在Rails中,资源...

    agile_web_development_with_rails_3rd_edition.9994652073.pdf

    《敏捷Web开发与Rails》第三版是一本深入探讨Ruby on Rails框架在敏捷软件开发方法论下的应用指南。本书由多位知名作者共同编写,包括Sam Ruby、Dave Thomas、David Heinemeier Hansson等,他们都是在Ruby社区内享有...

    Rails_3_Cheat_Sheets.pdf

    Rails_3_Cheat_Sheets.pdf

    rails3 和 thinking_sphinx安装

    Thinking Sphinx 是一个为 Rails 应用程序提供全文搜索功能的插件,它将数据库中的数据与 Sphinx 搜索引擎紧密结合,提供高效且高度定制化的搜索体验。 在 Rails3 中集成 Thinking Sphinx,首先你需要确保你的系统...

    Ruby-on-Rails-rails.zip

    Ruby_on_Rails_rails.zip Ruby_on_Rails_rails.zip Ruby_on_Rails_rails.zip Ruby_on_Rails_rails.zipRuby_on_Rails_rails.zip Ruby_on_Rails_rails.zip Ruby_on_Rails_rails.zip Ruby_on_Rails_rails.zipRuby_on_...

    rails_best_practices:Rails项目的代码度量工具

    rails_best_practices rails_best_practices是用于检查Rails代码质量的代码度量工具。 它支持以下ORM / ODM: 活动记录 蒙古型 mongomapper 以及以下模板引擎: erb 哈姆 减肥 拉布尔 rails_best_practices...

    inspinia_admin_v2.5_Rails_Full_Version

    该模板包含的文件列表“inspinia_admin_v2.5_Rails_Full_Version”很可能包括以下组成部分: 1. **静态资源**:CSS样式文件、JavaScript脚本和图像资源。这些文件用于构建用户界面,包括响应式布局、图表、表单元素...

    Rails_Recipes_with_Source_Code

    《Rails Recipes with Source Code》是一本专注于Ruby on Rails框架实践技巧和源代码解析的书籍。Rails是基于Ruby语言的Web开发框架,以其“约定优于配置”(Convention over Configuration)的理念和“开发人员的...

    InspiniaAdmin 2.5 Rails_Seed_Project

    InspiniaAdmin 2.5 Rails_Seed_Project是一款基于Bootstrap框架的高级管理模板,专为Ruby on Rails开发者设计,旨在加速Web应用程序的开发过程。这个项目作为种子启动器,提供了完整的后台管理界面,包括丰富的UI...

    inspinia admin - v2.5 Rails_Seed_Project

    Rails_Seed_Project则是Inspinia Admin在Rails环境下的一个种子项目,它的主要目的是快速搭建一个具备基本功能的后台管理系统。通过这个项目,开发者可以快速启动一个新的Rails应用,并且拥有一个预配置的后台界面,...

Global site tag (gtag.js) - Google Analytics