質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

2回答

7434閲覧

時刻文字列を任意のタイムゾーン間で変換する

退会済みユーザー

退会済みユーザー

総合スコア0

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

2クリップ

投稿2018/09/27 09:09

編集2018/09/27 10:20

'2018-09-25 15:00:00' のような文字列を特定のタイムゾーン文字列として読み込んで
別のタイムゾーン文字列として出力する方法はありますか?

強引にオフセットの加減をすればできなくはないのですが
タイムゾーンの名前だけでうまく変換できないでしょうか

たとえばUTCとして読み込んでローカルのタイムゾーンに変換する場合
Time.utc.parse('2018-09-25 15:00:00').local()
みたいな感じでかきたいんですが
Rails のマニュアルの読み方がわからなくてそれらしいメソッドを組み合わせてもなかなかうまくいきません

追記:

Rails のマニュアルのタイムゾーン関連のメソッド一覧はどうやって調べればいいんでしょうか

たとえば

utc_to_local(time)

Adjust the given time to the simultaneous time in the time zone represented by self. Returns a Time.utc() instance – if you want an ActiveSupport::TimeWithZone instance, use DateAndTime::Zones#in_time_zone instead.

とかいてあるんですが Time.utc() instance というのが
Time.class のページをみにいっても utc なんて項目はないし
どこをみればいいのかさっぱりわかりません

追記:

utc_time = ActiveSupport::TimeZone.new('UTC').parse(2018-09-27 12:00:00);
puts utc_time
puts Time.zone.utc_to_local(utc_time)
だと
2018-09-27 12:00 UTC
2018-09-27 21:00 UTC
となって時刻はあってるんですがタイムゾーンが変換されない…

simulate... return utc instance ってこういう意味だったんですね…
タイムゾーンも変更するにはどうすればいいんでしょうか

追記:

その説明にかわりに DateAndTime::Zones#in_time_zone ってかいてありました

puts utc_time.in_time_zone(Time.zone)

としたところ

2018-09-27 21:00:00 +0900

になってやりたいことができそうです
試してないですがたぶん Time.zone のかわりに ActiveSupport::Timezone.new(...) をいれれば任意のタイムゾーンに変換できるってことですよね…

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

たとえば、このリファレンスを見てみましょう。
https://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html

やりたい事としてparse関連っぽいので、parseの説明を見てみます。
こんな感じの事が書いてあります。

ruby

1Time.zone = 'Hawaii' # => "Hawaii" 2Time.zone.parse('1999-12-31 14:00:00') # => Fri, 31 Dec 1999 14:00:00 HST -10:00

Time.zoneって何もんだよという事で、rails consoleで試します。

ruby

1>> Time.zone.class 2=> ActiveSupport::TimeZone

ActiveSupport::TimeZoneのインスタンスが作れれば、やりたい事が出来そうだと分かりました。
タイムゾーンの一覧は、ActiveSupport::TimeZone.allで分かります。

という事で、こういう風にすれば良さそうだと思いました。
回答として合っているでしょうか?

ruby

1>> ActiveSupport::TimeZone.new("Tokyo").parse("2018-09-27 18:22:35") 2=> Thu, 27 Sep 2018 18:22:35 JST +09:00 3 4>> ActiveSupport::TimeZone.new("Arizona").parse("2018-09-27 18:22:35") 5=> Thu, 27 Sep 2018 18:22:35 MST -07:00 6 7>> time = ActiveSupport::TimeZone.new("Arizona").parse("2018-09-27 18:22:35") 8=> Thu, 27 Sep 2018 18:22:35 MST -07:00 9>> time.class 10=> ActiveSupport::TimeWithZone

投稿2018/09/27 09:31

mingos

総合スコア4025

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/09/27 09:52

ずっとそのページもみてたんですが使い方がわからなくて… 変換前のタイムゾーンクラスを先に作ってからパーズするんですね… ありがとうございます
guest

0

こんにちは。

リンクを貼るだけになってしまいますが、jnchito さんの以下の投稿

  • RubyとRailsにおけるTime, Date, DateTime, TimeWithZoneの違い

https://qiita.com/jnchito/items/cae89ee43c30f5d6fa2c

で紹介されている、ActiveSupport::TimeWithZone が便利ではないかと思います

参考になれば幸いです。


追記

以下、使用例です。

shell

1$ bundle exec rails c 2Loading development environment (Rails 5.2.0) 3[1] pry(main)> Time.zone = 'Eastern Time (US & Canada)' 4=> "Eastern Time (US & Canada)" 5[2] pry(main)> d1 = Time.zone.local(2018,9,27,18,30,55) 6=> Thu, 27 Sep 2018 18:30:55 EDT -04:00 7[3] pry(main)> Time.zone = 'Asia/Tokyo' 8=> "Asia/Tokyo" 9[4] pry(main)> d2 = Time.zone.local(2018,9,27,18,30,55) 10=> Thu, 27 Sep 2018 18:30:55 JST +09:00 11[5] pry(main)> d1 12=> Thu, 27 Sep 2018 18:30:55 EDT -04:00 13[6] pry(main)> d2 14=> Thu, 27 Sep 2018 18:30:55 JST +09:00 15[7] pry(main)> d1.utc 16=> 2018-09-27 22:30:55 UTC 17[8] pry(main)> d2.utc 18=> 2018-09-27 09:30:55 UTC 19[9] pry(main)> d1.class 20=> ActiveSupport::TimeWithZone 21[10] pry(main)> d2.class 22=> ActiveSupport::TimeWithZone

投稿2018/09/27 09:18

編集2018/09/27 10:02
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/09/27 09:26

この記事も読みました ただいずれも1度環境変数やconfigの値にタイムゾーンの値をセットしてから 入力出力を行うみたいなメソッドみたいで スレッドセーフとかそいのへんのことがよくわかってないので なんとなく一瞬でも環境がきりかわるとちょっと怖いかなって思うんです それが他の非同期リクエストに影響を与えないのであれば問題ないんですが… なるべくインスタンス内だけの変換ですませたいんですが Rails にはそういうメソッドは用意されてないんでしょうか
jun68ykt

2018/09/27 10:07

なるほどですね。 使用例を追記しましたが、Time.zone に希望のタイムゾーンを直接代入したあとで、 Time.zone.local などでインスタンスを作れば、そのインスタンスがタイムゾーンの情報を保持していますが、これでは、katingさんの要件は満たせてないでしょうか?
退会済みユーザー

退会済みユーザー

2018/09/27 10:15

そうですね mingosさんが回答してくださってるみたいに timezone インスタンスの parse を呼べば任意のタイムゾーンは作れそうです local に関しては何も考えずに Time.zone.parse を呼べばよかったんですが local じゃない任意のタイムゾーンとして読むにはどうしたらいいかがわからなかったので Timezoneインスタンスを作ればよかったんですね
jun68ykt

2018/09/27 10:22

そうですね。 ちなみに私自身は、Timezoneインスタンスを作るときに jnchito さんの投稿に > TimeWithZoneクラスのインスタンスはnewではなく、以下のような方法で取得するのが望ましい。 とあるとおり、 new ではインスタンスを作ったことはないです。
退会済みユーザー

退会済みユーザー

2018/09/27 10:31

> > TimeWithZoneクラスのインスタンスはnewではなく、以下のような方法で取得するのが望ましい。 これは理由があったりするんでしょうか 逆に先程もかいたとおり他の非同期リクエストに影響を与えそうなので ローカルインスタンスを作ってしまったほうがいいかなと思ってるんですが… 単一リクエスト内で完結することが保証されてるのであれば new で無駄なメモリを作らないにこしたことはないんですけどね… Rails のこともよくわかってないので仕様のわからないグローバルな変更はあまりしたくないという感じでした
jun68ykt

2018/09/27 11:57

そういうそうご事情があるのでしたら、 jnchito さんの投稿にも、 > TimeWithZoneクラスのインスタンスはnewではなく、以下のような方法で取得するのが望ましい。 と「望ましい」と書いてあるに留まっておりますし、また、 原文のAPIドキュメント https://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html に、 You shouldn't ever need to create a TimeWithZone instance directly via new. と書いてあるところをどう解釈するかですが、解釈のひとつとして、 「(たとえば Don't create a TimeWithZone instance directly via new. という感じで)強く禁止しているわけでもない」 と解釈することも個人の自由だと思いますので、katingさんの使用目的上 new でインスタンス生成するほうがよいと考えられるのであれば、それはそれで何ら問題はないと思います。
退会済みユーザー

退会済みユーザー

2018/09/27 12:20

なるほどー 原文にもあるのですね とりあえず週末に入って時間ができたらその理由について読み進めたいと思います 何度も返信ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問