web-dev-qa-db-fra.com

ruby obtenir le temps dans un fuseau horaire donné

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.

30
ashweta

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

35
Jim Meyer

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"
15
glenn jackman

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))
9
0x4a6f4672
gem install tzinfo

Ensuite

require 'tzinfo'

tz = TZInfo::Timezone.get('US/Pacific')
Time.now.getlocal(tz.current_period.offset.utc_total_offset)
5
chadoh

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>>>>
3
NudeCanalTroll

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
1
Kem Mason
now = Time.now
now.in_time_zone('Eastern Time (US & Canada)') 
or 
now.in_time_zone('Asia/Manila') 
0
jpwynn