<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>acidache (acidache)</title>
    <link>https://ruby-china.org/acidache</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>分享 多时区对应的解决案</title>
      <description>&lt;p&gt;前段时间，接到了一个 ROR 项目 (之前完全没有接触过 ROR)。。。其中，客户要求提供同时对应多国的时区以及夏令时的功能。(要求很高大上，估计就客户他们国家的人自己玩)
即 服务器比如搭建在中国，客户端 (WEB) 可能是在日本，中国，美国等等，全世界各个角落来访问服务器。&lt;/p&gt;

&lt;p&gt;ROR 本身支持了多时间和夏令时的对应，查了各种网站，几乎搜索到的只有 &lt;strong&gt;config.time_zone&lt;/strong&gt; 和  &lt;strong&gt;config.active_record.default_timezone&lt;/strong&gt; 的设定
但是这个的设定都是针对固定某个时区的，无法实现基于用户信息中所含有时区信息来自动切换时区来处理各种请求。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;为了实现同时服务不同时区的用户，我们使用了一下的解决思路：
                       local时间                     utc时间
客户端(WEB)  请求   ---------&amp;gt;   ROR服务器接收后※１    ---------&amp;gt;     各种处理(对DB访问等)
客户端(WEB)  回复   &amp;lt;---------   ROR服务器准备发送※2  &amp;lt;---------     处理结果(从DB中读取数据等)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;为了实现上面的思路，修改了以下内容。
1.&lt;strong&gt;config.time_zone&lt;/strong&gt; 和  &lt;strong&gt;config.active_record.default_timezone&lt;/strong&gt; 的默认设置都注释掉。&lt;/p&gt;

&lt;p&gt;这样子会使得 DB 直接使用 UTC&lt;/p&gt;

&lt;p&gt;2.在&lt;strong&gt;application_controller.rb&lt;/strong&gt;中，追加一个 before_action 动作，来做基于用户的时区来设置 ROR 的时区，来保证了 ROR 服务器回复客户端时会回复 local 时间&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt; &lt;span class="c1"&gt;#代码示例&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;
&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zone&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;local&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;★★★ &lt;strong&gt;需要注意的是，上面的设定只能成功改变通过 ActiveRecord 的 API 来取得 DB 的数据时间时，会按照上面设定的时区自动做转化。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;★★★ &lt;strong&gt;直接使用 SQL 语句查询出来的记录会保持数据库里面的 UTC 时间&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;3.为了给不同的 WEB 端提供统一的时间服务，ROR 服务器在 WEB 端用户登录请求的回复内容中，回复该用户登录时的 local 时间，
然后在 WEB 端，登录后的动作都基于这个收到的 local 时间来执行，来保证 WEB 端与 ROR 服务器的时间的统一性。&lt;/p&gt;

&lt;p&gt;上面只是大致提供了一个思路，实际项目时，也还会遇到各种各种的 case，需要具体情况在分析了。&lt;/p&gt;

&lt;p&gt;写在最后，作为一个才接触 rails 半年的小白，在 Ruby China 中找到了很多思路和灵感，于是自己也想着分享点自己和小伙伴们这半年的一点心得。
上面的时区转换，找了很久也没有找到合适的例子，因此将目前我们的做法分享出来，应该还有更好的实现方法，我就抛砖引玉吧。&lt;/p&gt;

&lt;p&gt;如果有什么不明点和指摘，请留言交流~  &lt;/p&gt;</description>
      <author>acidache</author>
      <pubDate>Tue, 24 Jan 2017 15:22:38 +0800</pubDate>
      <link>https://ruby-china.org/topics/32206</link>
      <guid>https://ruby-china.org/topics/32206</guid>
    </item>
  </channel>
</rss>
