2011-11-02 10 views
12

¿Cómo puedo obtener un objeto de hora de rubí que representa el inicio del día en una fecha determinada en una zona horaria determinada?Obtiene Objeto de tiempo al inicio del día en una zona horaria particular

+0

Solo un comentario ya que no sé nada sobre el manejo de la zona horaria de Ruby: la medianoche no siempre existe, y puede ocurrir dos veces. Brasil cambia sus relojes a medianoche, por ejemplo. Probablemente deberías encontrar el comienzo del día, en cambio. –

+0

Punto de interés. Para mi propósito, el comienzo del día es lo que me interesa. Gracias, Jon. Actualizaré la pregunta. –

+0

¿Cuál es su caso de uso real? (Encontré esta pregunta porque quería obtener la medianoche más reciente en California, como UTC, para el seguimiento de cuotas API). –

Respuesta

6

terminé usando el método #local en el ActiveSupport::TimeZone objeto p Asignar componentes del objeto Date.

# Get example date and time zone... 
date = Date.today 
timezone = ActiveSupport::TimeZone['America/New_York'] 

# Get beginning of day for date in timezone 
timezone.local(date.year, date.month, date.day) 
10
date = Date.today 

date.to_time.in_time_zone('America/New_York').beginning_of_day 

Actualmente salidas => 2011-11-02 00:00:00 -0400

Time.now.in_time_zone('Asia/Shanghai').beginning_of_day 

salidas Actualmente => 2011-11-03 00:00:00 +0800

date = Date.today 

date.to_time.in_time_zone('Asia/Shanghai').beginning_of_day 

salidas Actualmente => 2011-11-02 00:00:00 +0800

+1

Ojalá fuera así de simple. Lamentablemente, no hay garantía de que la hora a la que llegue, después de la conversión de zona horaria, sea en el mismo día. Algunas veces será y algunas veces no dependerá de la zona de inicio y finalización. Supongo que podría comparar el componente de fecha después de la conversión con el valor original y ajustarlo si fuera necesario, pero eso es realmente torpe. Lo que espero es una forma elegante de hacerlo que siempre funcione. Esperemos que haya algo en la API, no creo que sea una locura querer hacer. –

+0

Es posible que no entienda completamente lo que intenta hacer, pero 'date.to_time.in_time_zone ('TIMEZONE'). Beginning_of_day' le da 00:00:00 UTC para la fecha especificada original. –

+1

No te da 0 UTC, te da 0 en la zona horaria, lo cual es preferible. Pero no hace esto antes de convertir zonas horarias con in_time_zone, por lo que la fecha ya no es necesariamente válida. Aquí hay un ejemplo de lo que quiero decir. 'date.to_time.in_time_zone ('Asia/Shanghai'). midnight.in_time_zone (Time.zone) .midnight # => Un día en el pasado. Idealmente, Ruby debería permitirme hacer algo como esto. 'date.to_time (zone)'. –

5

No estoy seguro si esto ayuda, pero esto me pone el tiempo en que mis cuotas de la API de Google restablecen:

# The most recent midnight in California in UTC time 
def last_california_midnight 
    (Time.now.utc - 7.hours).midnight + 7.hours 
end 

lo uso como este con Mongoid, por ejemplo:

def api_calls_today 
    Call.where(updated_at: { '$gte' => last_california_midnight }).count 
end 

Esto funcionará independientemente de la zona horaria en la que se implemente el código, siempre que Mongo esté configurado como UTC.

Cuestiones relacionadas