2013-02-28 3 views
-1

레일에서 나는 activerecord에 대해 아래의 구성을 가지고 있습니다.활성 레코드의 default_timezone 변경

config.active_record.default_timezone = :utc 

지금, 나는 로컬 시간대를 사용하려면, 그래서 그것을 변경 : 문제는

config.active_record.default_timezone = :local 

, 나는에 날짜/날짜 열에서 기존의 모든 데이터를 이동해야합니다 현지 시간대. 이것을 달성하는 가장 좋은 방법은 무엇입니까? 내가 예를 들어, 로컬 시간대에 통합 할 필요가 있기 때문에


내가이 일을 왜

은 다음과 같습니다 기반으로합니다 그룹 => 'DATE (created_at)', DATE (created_at) BY GROUP UTC이지만, 현지 시간대로 하루를 집계하고 싶습니다.

특정 datetime 열을 마이그레이션하기 위해 마이그레이션 파일을 작성하는 방법을 알고있었습니다. 하지만 많은 칼럼이 있으므로 더 나은 솔루션을 찾고 있습니다.

+0

당신이 나타내는 정보를 저장 한 어떤 시간대 주어진 사용자는 무엇입니까? 아래에 명시된 바와 같이, 달리 명시되지 않는 한 로컬 시간대로 전환하면 모든 값이 서버의 시간대로 설정됩니다. – Chris

+0

@Chris 사용자는 서버와 동일한 시간대로 제한됩니다. – xdazz

답변

1

이 여기에 위험하지만, 내가 마이그레이션 할 거라고 것입니다 :

class MigrateDateTimesFromUTCToLocal < ActiveRecord::Migration 

    def self.up 
    # Eager load the application, in order to find all the models 
    # Check your application.rb's load_paths is minimal and doesn't do anything adverse 
    Rails.application.eager_load! 

    # Now all the models are loaded. Let's loop through them 
    # But first, Rails can have multiple models inheriting the same table 
    # Let's get the unique tables 
    uniq_models = ActiveRecord::Base.models.uniq_by{ |model| model.table_name } 

    begin 
     # Now let's loop 
     uniq_models.each do |model| 
     # Since we may be in the middle of many migrations, 
     # Let's refresh the latest schema for that model 
     model.reset_column_information 

     # Filter only the date/time columns 
     datetime_columns = model.columns.select{ |column| [ :datetime, :date, :time].include? column.type } 

     # Process them 
     # Remember *not* to loop through model.all.each, or something like that 
     # Use plain SQL, since the migrations for many columns in that model may not have run yet 
     datetime_columns.each do |column| 
      execute <<-SQL 
      UPDATE #{model.table_name} SET #{column.name} = /* DB-specific date/time conversion */ 
      SQL 
     end 

     rescue 
     # Probably time to think about your rescue strategy 
     # If you have tested the code properly in Test/Staging environments 
     # Then it should run fine in Production 
     # So if an exception happens, better re-throw it and handle it manually 
     end 

    end 
    end 
end 
+0

고마워,이 사람은 좋아 보인다. – xdazz

0

데이터베이스의 데이터를 변경해야합니까? 대신 현지 시간대로 날짜를 표시 할 수 있습니까? 도움이 되니? Convert UTC to local time in Rails 3

+0

': group =>'DATE (created_at) '','GROUP BY DATE (created_at)'는'UTC'를 기반으로 현지 시간대에서 집계해야하지만, 어느 날 현지 시간대로. – xdazz

+0

어떤 데이터베이스를 사용하고 있습니까? Postgres에는 일련의 시간대 기능이 있습니다 (http://www.postgresql.org/docs/9.2/static/functions-datetime.html, 섹션 : 9.9.3 AT TIME ZONE 참조). 이렇게하면 쿼리를 수행 할 때 시간대를 지정할 수 있습니다. –

1

나의 첫 번째 충고는 이것을하지 않을 것을 강력히 권장한다. 당신은 자신을 상처의 세계로 여는 중입니다. 말했다, 여기 당신이 원하는 무엇인가 :

central_time_zone = ActiveSupport::TimeZone.new("Central Time (US & Canada)") 
walrus.update_column(:married_at, married_at_utc.in_time_zone(central_time_zone)) 

또는 당신이 그것을 떠날 수와 레일이 현재의 시간대를 사용합니다 : 당신은, 날짜 시간 #의 in_time_zone에 원하는 시간대 전달과 같이 할 수있다

class ShootMyFutureSelfInTheFootMigration 
    def up 
    Walrus.find_each do |walrus| 
     married_at_utc = walrus.married_at 
     walrus.update_column(:married_at, married_at_utc.in_time_zone) 
    end 
    end 

    def down 
    Walrus.find_each do |walrus| 
     married_at_local = walrus.married_at 
     walrus.update_column(:married_at, married_at_local.utc) 
    end 
    end 
end 

. 이 위치는 현재 위치가 아니라 서버 위치입니다. 따라서 아이슬란드와 상하이에 사용자가 있지만 서버가 캘리포니아에있는 경우 '로컬'시간대는 모두 미국 태평양 표준시입니다.

+0

답장을 보내 주셔서 감사합니다. 질문에 몇 가지 정보를 추가했습니다. – xdazz

+0

레일 마이그레이션을 원할 경우 update_column은 얻을 수있는만큼 효율적입니다.변경하려는 필드 만 선택하여 메모리 사용량을 줄일 수 있지만이 옵션을 한 번 실행하면되므로 시간이 크게 걱정할 필요가 없습니다. – Chris

+0

그러나 나열해야하는 열이 많습니다. 마이그레이션해야하는 모든 Datatime 열을 감지 할 수있는 다른 솔루션을 찾고 있습니다. – xdazz

0

많은 다른 사람들이 말한 것처럼, 당신은 아마 이것을 원하지 않을 것입니다.

그룹화하기 전에 시간을 다른 영역으로 변환 할 수 있습니다. 모두 데이터베이스에 있습니다. 예를 들어, 포스트 그레스, 산지 표준시로 변환과 :

SELECT COUNT(id), DATE(created_at AT TIME ZONE 'MST') AS created_at_in_mst 
FROM users GROUP BY created_at_in_mst; 
관련 문제