Dans Ruby, comment puis-je obtenir l'heure actuelle dans un fuseau horaire donné? Je connais le décalage par rapport à UTC et je souhaite obtenir l'heure actuelle dans le fuseau horaire avec ce décalage.
Une solution plus simple et plus légère:
Time.now.getlocal('-08:00')
Bien documenté ici .
Mise à jour 2017.02.17: Si vous avez un fuseau horaire et que vous souhaitez en faire un décalage que vous pouvez utiliser avec #getlocal, y compris l'heure d'été, procédez comme suit:
require 'tzinfo'
timezone_name = 'US/Pacific'
timezone = TZInfo::Timezone.get(timezone_name)
offset_in_hours = timezone.current_period.utc_total_offset_rational.numerator
offset = '%+.2d:00' % offset_in_hours
Time.now.getlocal(offset)
Si vous voulez faire cela pour des moments autres que #now
, vous devriez étudier le classe Ruby Time , en particulier Time#gm
et Time#local
, et le Ruby TZInfo classes }, en particulier TZInfo::Timezone.get
et TZInfo::Timezone#period_for_local
J'utiliserais le ActiveSupport gem:
require 'active_support/time'
my_offset = 3600 * -8 # US Pacific
# find the zone with that offset
zone_name = ActiveSupport::TimeZone::MAPPING.keys.find do |name|
ActiveSupport::TimeZone[name].utc_offset == my_offset
end
zone = ActiveSupport::TimeZone[zone_name]
time_locally = Time.now
time_in_zone = zone.at(time_locally)
p time_locally.rfc822 # => "Fri, 28 May 2010 09:51:10 -0400"
p time_in_zone.rfc822 # => "Fri, 28 May 2010 06:51:10 -0700"
Pour un décalage UTC de x heures, l'heure actuelle peut être calculée à l'aide d'ActiveSupport dans Rails, comme l'ont dit les autres:
utc_offset = -7
zone = ActiveSupport::TimeZone[utc_offset].name
Time.zone = zone
Time.zone.now
ou au lieu des deux lignes
DateTime.now.in_time_zone(zone)
Ou, si vous n'avez pas de Rails, vous pouvez également utiliser new_offset
pour convertir un DateTime de localisation vers un autre fuseau horaire.
utc_offset = -7
local = DateTime.now
local.new_offset(Rational(utc_offset,24))
gem install tzinfo
Ensuite
require 'tzinfo'
tz = TZInfo::Timezone.get('US/Pacific')
Time.now.getlocal(tz.current_period.offset.utc_total_offset)
Une méthode plus simple consiste simplement à transmettre le décalage (sous forme entière) au hachage ActiveSupport :: TimeZone:
ActiveSupport::TimeZone[-8]
=> #<ActiveSupport::TimeZone:0x7f6a955acf10 @name="Pacific Time (US & Canada)", @tzinfo=#<TZInfo::TimezoneProxy: America/Los_Angeles>, @utc_offset=nil, @current_period=#<TZInfo::TimezonePeriod: #<TZInfo::TimezoneTransitionInfo: #<TZInfo::TimeOrDateTime: 1320570000>,#<TZInfo::TimezoneOffsetInfo: -28800,0,PST>>,#<TZInfo::TimezoneTransitionInfo: #<TZInfo::TimeOrDateTime: 1331460000>,#<TZInfo::TimezoneOffsetInfo: -28800,3600,PDT>>>>
J'ai essayé un gem install active_support
, il a installé actifsupport-3.00, ce qui m'a donné une erreur:
"Tzinfo n'est pas installé dans votre application. Ajoutez-le à votre Gemfile et lancez l'installation en bundle"
tzinfo
est un joyau utilisé par ActiveSupport - c’était un peu plus propre, il n’a aucune dépendance externe - l’inconvénient est qu’il semble laisser tout ressembler à UTC, donc si vous voulez que votre fuseau horaire ressemble correct, gem install activerecord
installera tout ce dont vous avez besoin. J'inclus cette réponse principalement à titre de référence pour les autres qui rencontrent le même problème/la même vulnérabilité.
(utilisez gem install tzinfo
) pour installer la gemme
require 'tzinfo'
zone = TZInfo::Timezone.get('US/Eastern')
puts zone.now
il existe différentes manières d’obtenir les fuseaux horaires, mais vous pouvez voir une liste en utilisant
TZInfo::Timezone.all
now = Time.now
now.in_time_zone('Eastern Time (US & Canada)')
or
now.in_time_zone('Asia/Manila')