2010-12-01 19 views
1

Cela doit être une chose facile à faire, mais je pense que l'implémentation du fuseau horaire de Rail me dégoûte ...Portée ActiveRecord pour rechercher des enregistrements créés aujourd'hui?

Comment puis-je créer une portée dans Rails 3 (et ruby ​​1.9.2) pour interroger pour les enregistrements créés aujourd'hui?

Actuellement, je fais ceci:

scope :today, lambda { 
    where("created_at >= ? and created_at <= ?", 
      Date.today.beginning_of_day, Date.today.end_of_day) 
    } 

Et il ne semble pas fonctionner comme il se doit. Je veux "aujourd'hui" représenter la période de 24 heures de 12h à 23h59 pour le fuseau horaire local d'un utilisateur. Ai-je besoin de convertir la date en UTC ou quelque chose?

Répondre

3

Vous devez considérer le fuseau horaire de l'utilisateur. C'est-à-dire, début de journée et fin de journée dans le fuseau horaire de l'utilisateur. Pour cela, commencez par analyser l'heure actuelle dans le fuseau horaire de l'utilisateur. Vous pouvez définir la zone au fuseau horaire de l'utilisateur et faire le calcul ou vous pouvez analyser l'heure directement en utilisant une variation du code suivant.

timezone = current_user.timezone # Mountain Time (US & Canada) 
users_current_time = ActiveSupport::TimeZone[timezone].parse(Time.now.to_s) 

users_current_time.beginning_of_day et users_current_time.end_of_day devrait générer la plage de moment (que vous app convertir en UTC et tirer la requête, si UTC est vos applications fuseau horaire)

Si vous voulez faire avec les étendues uniquement, alors je vous suggère de définir le Time.zone = current_user.timezonebefore_filter de toutes les actions et de l'utiliser dans la portée. This railscast donne une idée juste de la façon de s'y prendre.

1

Si vous utilisez mysql, alors je pense que vous voulez juste faire correspondre le jour, pas le bon moment? Autrement dit, vous voulez tous les enregistrements à partir du 1er décembre. Entre 12h00 et 23h59 le 1er décembre est implicite si vous effectuez une recherche sur la date.

scope :today, lambda { 
    where("created_at = ?", 
      Time.now.strftime("%Y-%d-%m") 
    } 

Quelque chose comme ça devrait fonctionner

+0

Je me demandais - Est-ce que cela retournera vrai pour un format DateTime entier? Si oui, j'ai résolu ce problème avec des solutions prolixes pendant des années. –

+0

Il va retourner une requête SQL comme: "... O WH created_at = '2010-12-01' ..." que MySQL puis analyse en faire correspondre tout le 1er décembre – brycemcd

+0

format strtime est faux, devrait être YEAR-MONTH- JOUR, comme dans "% Y-% m-% d" – mguymon

0

Que pensez-vous de cela?

scope :today, lambda { 
    where("created_at >= ? and created_at <= ?", 
      Date.today.beginning_of_day.utc, Date.today.end_of_day.utc) 
    }