Pregunta Rails. ¿Cómo almacenar la hora del día (para el horario)?


Estoy escribiendo una aplicación que realiza un seguimiento de las clases de la escuela.

Necesito almacenar el horario. Por ejemplo: de lunes a viernes desde 8: a.m.-11:00 a.m..

Estaba pensando en utilizar una columna de cadena simple, pero voy a necesitar hacer cálculos de tiempo más tarde.

Por ejemplo, necesito almacenar una representación de 8am, como start_at: 8am end_at: 11am

Asi que ¿Cómo debo guardar el tiempo?? ¿Qué tipo de datos debo usar? ¿Debo almacenar el tiempo de inicio y el número de segundos o minutos y luego calcular desde allí? ¿O hay una forma más fácil?

Yo uso MySQL para producción y SQLite para desarrollo.


32
2017-08-15 16:30


origen


Respuestas:


Hace poco hice una aplicación que tenía que abordar este problema. Decidí almacenar open_at y closed_at en segundos a partir de la medianoche en un simple modelo de horario comercial. ActiveSupport incluye esta útil herramienta para averiguar el tiempo en segundos desde la medianoche:

Time.now.seconds_since_midnight

De esta manera puedo hacer una consulta simple para averiguar si un lugar está abierto:

BusinessHour.where("open_at > ? and close_at < ?", Time.now.seconds_since_midnight, Time.now.seconds_since_midnight)

Cualquier consejo para mejorar esto sería apreciado =)


19
2018-03-12 00:06



Si está utilizando Postgresql puede usar un time tipo de columna que es solo la hora del día y sin fecha. A continuación, puede consultar

Event.where("start_time > '10:00:00' and end_time < '12:00:00'")

Tal vez MySQL tiene algo similar


10
2017-11-26 23:05



Mira la gema 'tod' para Rails 4 o Time_of_Day for Rails 3. Ambos resuelven el problema de almacenar tiempo en una base de datos mientras usan un modelo de registro activo.

SQL tiene un tipo de datos de tiempo pero Ruby no. Active Record corrige esta diferencia representando atributos de tiempo usando la clase de tiempo de Ruby en la fecha canónica 2000-01-01. Todos los atributos de tiempo se asignan arbitrariamente a las mismas fechas. Si bien los atributos se pueden comparar entre sí sin problemas (las fechas son las mismas), surgen errores cuando intenta compararlos con otras instancias de tiempo. Simplemente usar Time.parse en una cadena como "10:05" agrega la fecha de hoy a la salida.

Lailson Bandeira creó una solución creada para este problema, la joya Time_of_Day para Rails 3. Lamentablemente, la gema ya no se mantiene. Usa la gema 'tod' de Jack Christensen. Funciona a las mil maravillas.


8
2017-09-10 04:21



Almacenaba la hora de inicio y la duración dentro de la base de datos, usando dos columnas enteras.

Al recuperar ambos valores, puede convertir la hora inicial como en (suponiendo que ya conoce el día:

# assuming date is the date of the day, datetime will hold the start time
datetime = date.change({:hour => your_stored_hour_value , :min => 0 , :sec => 0 })

# calculating the end time
end_time = datetime + your_stored_duration.seconds

De lo contrario, eche un vistazo a Crónico. La gema hace que el tiempo de manipulación sea un poco más fácil. Tenga en cuenta que changemétodo es parte de los rieles, y no está disponible en Ruby simple.

La documentación sobre DateTime por Ruby llano se puede encontrar aquí.

Además, haga lo que haga, no empiece a almacenar sus fechas / horas en formato de 12 horas, puede usar I18nen Rails para convertir el tiempo:

I18n.l Time.now, :format => "%I.%m %p",  :locale => :"en"
I18n.l Time.now + 12.hours, :format => "%I.%m %p",  :locale => :"en"

También puede obtener de esta notación, que puede almacenar su duración en horas, si lo desea, puede convertirlas fácilmente mediante:

your_stored_value.hours

si está almacenado como un entero, eso es.


2
2017-08-15 17:18



Esta joya de rubíconvierte la hora del día en segundos desde la medianoche y viceversa. El valor de los segundos se almacena en la base de datos y se puede usar para cálculos y validaciones.

Definir los atributos de la hora del día:

class BusinessHour < ActiveRecord::Base
  time_of_day_attr :opening, :closing
end

Convierte la hora del día en segundos desde la medianoche cuando se estableció una cadena:

business_hour = BusinessHour.new(opening: '9:00', closing: '17:00')
business_hour.opening
 => 32400
business_hour.closing
 => 61200

Para convertir de nuevo a la hora del día:

TimeOfDayAttr.l(business_hour.opening)
 => '9:00'
TimeOfDayAttr.l(business_hour.closing)
 => '17:00'

También puede omitir minutos a la hora completa:

TimeOfDayAttr.l(business_hour.opening, omit_minutes_at_full_hour: true)
 => '9'

2
2018-01-05 11:24



Sugerencia:

No se preocupe por un tipo de datos específico para eso. Una solución simple sería:

  1. En la base de datos, agregue un entero escriba la columna para hora de inicio y otro para hora de finalización. Cada uno almacenará el número de minutos desde la medianoche.
    Ej .: 8:30 am se almacenaría como 510 (8 * 60 + 30)

  2. En la forma, crea un seleccionar campo (menú desplegable) que muestra todos los formatos de tiempo disponibles en el tiempo:
    Ej .: 10 a.m., 10:30 a.m. y así sucesivamente.
    Pero los valores de campo reales que se guardan en la base de datos son sus equivalentes enteros:
    Ej: 600, 630 y así sucesivamente (siguiendo el ejemplo anterior)


1
2018-02-04 06:10



Supongo que estás usando algún tipo de base de datos para esto. Si está utilizando MySQL o Postgresql, puede usar datetime tipo de columna, que Ruby / Rails convertirá automáticamente a / desde un Time objeto al leer / escribir en la base de datos. No estoy seguro de si sqlite tiene algo similar, pero me imagino que probablemente sí.


0
2017-08-15 16:49



Desde el SQLite 3 sitio web,

"SQLite no tiene una clase de almacenamiento reservada para almacenar fechas y / o horas. En cambio, las Funciones de Fecha y Hora incorporadas de SQLite son capaces de almacenar fechas y horas como valores TEXT, REALES o INTEGER:

TEXTO como cadenas ISO8601 ("AAAA-MM-DD HH: MM: SS.SSS"). REAL como números de día julianos, el número de días desde el mediodía en Greenwich el 24 de noviembre de 4714 a. C. de acuerdo con el calendario gregoriano proléptico. INTEGER como Tiempo Unix, el número de segundos desde 1970-01-01 00:00:00 UTC. Las aplicaciones pueden elegir almacenar fechas y horas en cualquiera de estos formatos y convertir libremente entre formatos usando las funciones incorporadas de fecha y hora ".

Luego puede manipular los valores usando las funciones de Fecha y Hora delineadas aquí.


0
2017-08-15 17:05