任意のタイムゾーンを持ったActiveSupport::TimeWithZoneオブジェクトを生成する

# お題

```ruby
Time.zone_default
# => #<ActiveSupport::TimeZone:0x00007fd94cdc6450 @name="UTC", @tzinfo=#<TZInfo::DataTimezone: Etc/UTC>, @utc_offset=nil>
Time.zone
# => #<ActiveSupport::TimeZone:0x00007fd94cdc6450 @name="UTC", @tzinfo=#<TZInfo::DataTimezone: Etc/UTC>, @utc_offset=nil>
Time.zone.now.zone
# => "UTC"
```

(戻すのが面倒だったり忘れたりするから)`Time.zone_default` や `Time.zone` は変更せずに、なんか好きな `ActiveSupport::TimeZone` オブジェクトをしょった `ActiveSupport::TimeWithZone` オブジェクトがほしい。

*activesupport-7.0.1/lib/active_support/core_ext/time/zones.rb* この辺を参考にする

# 案1 Time.use_zone
block内だけタイムゾーンを変更してくれるので便利。

```ruby
Time.use_zone('Tokyo') { Time.zone.now.zone }
# => "JST"
Time.zone.now.zone
# => "UTC"
```

blockなしで呼ぶと **no block given (yield) (LocalJumpError)** が発生するよ。

## 注意点
```ruby
current = Time.zone.now
# => Wed, 26 Jan 2022 05:01:10.768064609 UTC +00:00
Time.use_zone('Tokyo') { current }
# => Wed, 26 Jan 2022 05:01:10.768064609 UTC +00:00

I18n.l current
# => "2022年01月26日(水) 05時01分10秒 +0000"
Time.use_zone('Tokyo') { I18n.l current }
# => "2022年01月26日(水) 05時01分10秒 +0000"

Time.use_zone('Tokyo') { I18n.l Time.zone.now }
# => "2022年01月26日(水) 14時02分08秒 +0900"
```
既に生成された `ActiveSupport::TimeWithZone` オブジェクトが書き変わるわけではない。
まぁよく考えればあたりまえではある気はするけど、うっかりミス注意。

# 案2 Time.find_zone

```ruby
Time.find_zone('Tokyo').now
# => Wed, 26 Jan 2022 13:42:54.862489203 JST +09:00
```

ちょっと長いけど、まぁ素直かな。
気持ち的には`Time.zone('Tokyo').now` って書きたい気もする。

ちなみに `Time.find_zone` と `Time.find_zone!` の違いは

```ruby
Time.find_zone('Saitama')
# => nil
Time.find_zone!('Saitama')
# => activesupport-7.0.1/lib/active_support/core_ext/time/zones.rb:85:in `find_zone!': Invalid Timezone: Saitama (ArgumentError)
```

こんな感じで、知らないタイムゾーン名を渡された時に**nilを返す**か**例外を発生させる**かの違い。(よくあるやつ)

# 案3 ActiveSupport::TimeWithZone#in_time_zone
一旦適当に生成して、後で作りなおすという逆転の発想

```ruby
Time.zone.now.in_time_zone('Tokyo')
# => Wed, 26 Jan 2022 14:38:11.790049006 JST +09:00
```
嫌いじゃないけど、ちょっとチェインが長い気もする。

# 案4 ActiveSupport::TimeZone.new
```ruby
ActiveSupport::TimeZone.new('Tokyo').now
# => Wed, 26 Jan 2022 14:29:50.811455162 JST +09:00
```
`ActiveSupport::TimeZone.new.now` はないわ。`new`と`now`の字面が似すぎて見にくいわ。

実は`.new`は`.[]`を呼んでるだけなので次に紹介する `ActiveSupport::TimeZone.[]` の方がいいかもね。

# 案5 ActiveSupport::TimeZone.[]

```ruby
ActiveSupport::TimeZone['Tokyo'].now
# => Wed, 26 Jan 2022 14:28:14.118789817 JST +09:00
```

うん。これはとても素直。
だけど、見くらべると `Time.find_zone('Tokyo').now` の方が好きかなぁ。
まぁでも文脈に応じてこちらの方がいい事もあるかもね。

# その他

案4や案5の様に`ActiveSupport::TimeZone` オブジェクトを生成する方法は色々あるので `activesupport-7.0.1/lib/active_support/values/time_zone.rb` あたりを見てみるとおもしろいね。

# 番外編: String を parse するんだったら。。。

`String#in_time_zone` という手もある

```ruby
'2022-01-26'.in_time_zone
# => Wed, 26 Jan 2022 00:00:00.000000000 UTC +00:00
'2022-01-26'.in_time_zone('Tokyo')
# => Wed, 26 Jan 2022 00:00:00.000000000 JST +09:00
'2022-01-26'.in_time_zone('Saitama')
# activesupport-7.0.1/lib/active_support/core_ext/time/zones.rb:85:in `find_zone!': Invalid Timezone: Saitama (ArgumentError)
```

:point_down:  これは残念な結果になる。

```ruby
'2022年01月26日'.in_time_zone('Tokyo')
# => <internal:timev>:310:in `initialize': argument out of range (ArgumentError)
```

でもまぁ、内部では `Date._parse` が使われているのでしょうがない。