2011-03-24 20 views
17

Tengo una configuración de zona horaria predeterminada para la aplicación de rieles. Y una instancia del objeto Date.Rieles: obtenga #beginning_of_day en la zona horaria

¿Cómo puedo hacer que date # date_of_day para devolver el comienzo del día en la zona horaria especificada, pero no en mi zona horaria local.

¿Hay algún otro método para obtener el comienzo del día en la zona horaria especificada para la fecha especificada?

date = Date.new(2014,10,29) 

zone = ActiveSupport::TimeZone.new('CET') 
date.foo(zone) # should return "Wed, 29 Oct 2014 00:00:00 CET +01:00" 

zone = ActiveSupport::TimeZone.new('UTC') 
date.foo(zone) # should return "Wed, 29 Oct 2014 00:00:00 UTC +00:00" 
+1

¿No es el comienzo del día siempre 00:00 independientemente de la zona horaria? – Ant

+2

Siempre es 00:00, pero 00:00 siempre es diferente en diferentes zonas horarias. El resultado de #beginning_of_day conoce la zona horaria. Y parece que elige la zona horaria local en lugar de la predeterminada: Time.zone. –

+0

Probé algunas cosas en este hilo de publicación y resulta en una respuesta incorrecta para las zonas horarias al este de UTC. Voy a publicar una "respuesta", ya que un comentario no formateará el código. – mcr

Respuesta

19
+2

Hace para mí ahora en 4.1, tanto 'Time.now.beginning_of_day' y' Date.today.beginning_of_day' devuelven la hora correcta con mi aplicación timezone –

9

Date#beginning_of_day siempre devolverá 00:00.

Pero según tengo entendido, quiere saber la hora en otra zona horaria, mientras que en la zona horaria actual es el comienzo del día.

So. Descubramos el comienzo del día en su lugar actual. Imagínese que es París, Francia:

bd = DateTime.now.in_time_zone('Paris').beginning_of_day 
# or just 
bd = DateTime.now.in_time_zone(1).beginning_of_day 
#=> Thu, 24 Mar 2011 00:00:00 WET +01:00 

Ahora vamos a conocer a qué hora es en Moscú:

moscow_time = bd.in_time_zone("Moscow") # or in_time_zone(3) 
#=> Thu, 24 Mar 2011 02:00:00 AST +03:00 
london_time = bd.in_time_zone("London") 
#=> Wed, 23 Mar 2011 23:00:00 GMT +00:00 
kyiv_time = bd.in_time_zone("Kyiv") 
#=> Thu, 24 Mar 2011 01:00:00 EET +02:00 

Por forma diferente now día:

# You even shouldn't call now, because it by default will be 00:00 
date = DateTime(2011, 1, 3).in_time_zone("-10") 
# or 
date = DateTime.new(2011,1,3,0,0,0,"-10") 
# and same way as above 
moscow_time = date.in_time_zone("Moscow") # or in_time_zone(3) 

y convertir Date a DateTime

date = Date.new(2011,1,3).to_datetime.change(:offset => "EST") 
+0

¿Es posible hacer esto para una fecha personalizada, no solo hoy? –

+0

sí, por supuesto, 3 de enero de 2011: 'bd = DateTime.new (2011, 1, 3) .in_time_zone ('Paris'). Beginning_of_day' y así sucesivamente – fl00r

+0

Y ahora, tengo un objeto Date ... Desafortunadamente es no DateTime. Si lo hago #to_datetime, obtengo beginning_of en la zona horaria incorrecta. –

36
DateTime.now.in_time_zone(Time.zone).beginning_of_day 
1
may2 = Date.new(2012,5,2) 
midnight = Time.zone.local(may2.year,may2.month,may2.day).beginning_of_day 

Mier 02 de Mayo de 2012 00:00:00 GMT +00: 00

midnight = Time.zone.local(may2.year,may2.month,may2.day).in_time_zone("Moscow").beginning_of_day 

=> Mier 02 de Mayo de 2012 00:00:00 MSK 04: 00

midnight = Time.zone.local(may2.year,may2.month,may2.day).in_time_zone("Alaska").beginning_of_day 

=> mar. , 01 de mayo de 2012 00:00:00 AKDT -08: 00

AVISO, es el DÍA MAL.

Lo que se necesita es una forma de construir un TimeWithZone en la zona horaria correcta.

Time.zone="Alaska" 
midnight = Time.zone.local(may2.year,may2.month,may2.day) 

No me gusta esto, porque por lo que puedo ver, acabo de modificar el sistema de noción de lo que la zona en que estoy. La idea es cambiar de base de datos de búsquedas para que coincida con la zona del cliente ... Por lo tanto, tengo que ahorrar zona y restaurarlo:

foo = Time.zone; Time.zone="Alaska"; midnight = Time.zone.local(may2.year,may2.month,may2.day); Time.zone = foo 

Parece que debería ser capaz de llamar a TimeWithZone.new(), pero yo no encontrar la manera.

0
ActiveSupport::TimeZone['Europe/London'].parse('30.07.2013') # 2013-07-29 23:00:00 UTC 
ActiveSupport::TimeZone['Asia/Magadan'].parse('30.07.2013') # 2013-07-29 12:00:00 UTC 
0

Como se mencionó Leonid Shevtsov, Date.beginning_of_day no hace honor a Time.zone en ActiveSupport 2.3

Una alternativa utilicé, si su pegada usando Rails 4.0 o ActiveSupport 2.3, y hay que utilizar una fecha de encargo:

date = Date.new(2014,10,29) 
date.to_time.change(hour: 0, min: 0, sec: 0).in_time_zone #.beginning_of_day 
date.to_time.change(hour: 23, min: 59, sec: 59).in_time_zone #.end_of_day 

resultados:

2.0.0-p247 :001 > date = Date.new(2014,10,29) 
=> Wed, 29 Oct 2014 

2.0.0-p247 :002 > date.to_time.change(hour: 0, min: 0, sec: 0) 
=> 2014-10-29 00:00:00 -0500 

2.0.0-p247 :003 > date.to_time.change(hour: 0, min: 0, sec: 0).in_time_zone 
=> Wed, 29 Oct 2014 05:00:00 UTC +00:00 

2.0.0-p247 :004 > date.to_time.change(hour: 23, min: 59, sec: 59) 
=> 2014-10-29 23:59:59 -0500 

2.0.0-p247 :005 > date.to_time.change(hour: 23, min: 59, sec: 59).in_time_zone 
=> Thu, 30 Oct 2014 04:59:59 UTC +00:00 

Mi ámbito fracasado modelo original utilizando .beginning_of_day a .end_of_day falló en el trabajo:

scope :on_day, ->(date) { where(created_at: date.beginning_of_day..date.end_of_day) } 

Y, esto es lo que se fija, ya que no pude actualizar a los carriles 4,0

scope :on_day, ->(date) { where(created_at: date.to_time.change(hour: 0, min: 0, sec: 0).in_time_zone..date.to_time.change(hour: 23, min: 59, sec: 59).in_time_zone) } 
2

Dejar de tomar la respuesta de Peder, esto es lo que hice para la zona horaria PST:

DateTime.now.in_time_zone("Pacific Time (US & Canada)").beginning_of_day 
0

sé que este post es viejo, pero ¿qué pasa:

Time.zone.parse("12am")