放課後アトリエといろ 第65535話が公開された

# 放課後アトリエといろ

時の為政者によって封印されてしまった幻の名作、放課後アトリエといろ[第65535話が特別公開されました](https://twitter.com/hanabana_h04/status/1196403961567166466)。
さあさっそく読むんだ。
そして本屋で単行本の1巻から4巻までを買い占めて編集部に再開のプレッシャーを掛けるんだ。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">今から約10年前、私まだ高校生の時に漫画家デビューした作品『放課後アトリエといろ』は雑誌改変の都合などで打ち切りになったのですが<br>今回skeb経由で画像の様なリクエストをいただきまして特別読み切りとして復活致しました。(続く→) <a href="https://t.co/was8bZb49W">pic.twitter.com/was8bZb49W</a></p>&mdash; 華々つぼみ@ちびちゅき！⑥巻 発売中 (@hanabana_h04) <a href="https://twitter.com/hanabana_h04/status/1196403961567166466?ref_src=twsrc%5Etfw">2019年11月18日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">おあぁぁぁぁ(絶命)<a href="https://twitter.com/hashtag/%E6%94%BE%E8%AA%B2%E5%BE%8C%E3%82%A2%E3%83%88%E3%83%AA%E3%82%A8%E3%81%A8%E3%81%84%E3%82%8D?src=hash&amp;ref_src=twsrc%5Etfw">#放課後アトリエといろ</a> <a href="https://t.co/dxtbNpSR79">pic.twitter.com/dxtbNpSR79</a></p>&mdash; ラナ・クアール (@rana_kualu) <a href="https://twitter.com/rana_kualu/status/1196380735176761344?ref_src=twsrc%5Etfw">2019年11月18日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">作者が一番うれしいのはお褒めの言葉だいや手紙だみたいなのをたまに見るけど、本当に一番なのはコレじゃないんかね。<br>いや知らんけど。 <a href="https://t.co/ziExc4RC5M">pic.twitter.com/ziExc4RC5M</a></p>&mdash; ラナ・クアール (@rana_kualu) <a href="https://twitter.com/rana_kualu/status/1196406927263092736?ref_src=twsrc%5Etfw">2019年11月18日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


あ、言いたいことはもう終わったので帰っていいですよ。


でもここで終わると不思議なことに何故か消されてしまうので、ここから下にはなんか適当におまけでも置いときます。


# [Bug #78827 Wrong timestamp](https://bugs.php.net/bug.php?id=78827)

さて問題です。
以下の出力はどうなるでしょう。

```php
$today = strtotime('last Wednesday');

var_dump(
    (strtotime('last Wednesday') - $today) / 86400,
    (strtotime('last Wednesday + 1 day') - $today) / 86400,
    (strtotime('last Wednesday + 2 day') - $today) / 86400,
    (strtotime('last Wednesday + 3 day') - $today) / 86400,
    (strtotime('last Wednesday + 4 day') - $today) / 86400,
    (strtotime('last Wednesday + 5 day') - $today) / 86400,
    (strtotime('last Wednesday + 6 day') - $today) / 86400,
    (strtotime('last Wednesday + 7 day') - $today) / 86400,
    (strtotime('last Wednesday + 8 day') - $today) / 86400,
    (strtotime('last Wednesday + 9 day') - $today) / 86400,
);
```


## Expected result

まず`$today`は"先週の水曜日、0時0分0秒"になります。
実行したのが木曜であれば昨日、金曜であれば一昨日、そして今日が水曜であれば7日前になります。

ではvar_dumpの行を見ていきましょう。

まず`last Wednesday`の行ですが、ここは同じ値を引いてるだけなので当然0になります。

次に`last Wednesday + 1 day`ですが、ここは"先週の水曜日から+1日、0時0分0秒"となります。
実行したのが木曜であれば今日、金曜であれば昨日のことで、そして今日が水曜であれば6日前になります。
単に1日ずらしただけなので、当然ながら`$today`とのずれは必ず1日です。
ということで`(strtotime('last Wednesday + 1 day') - $today) / 86400`の答えは、何曜日に実行したとしても必ず1です。

同じく`last Wednesday + 2 day`の答えは必ず2、`last Wednesday + 3 day`の答えは必ず3、となります。
そんなかんじで続いていって、一番下の`last Wednesday + 9 day`の答えは必ず9です。
![20191120-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/cb4ef1ce-3751-d5f5-c073-d466465abdad.png)
当然ですね。


## Actual result

水曜日に実行するとこうなります。
![20191120-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/5e6c6728-dad4-da08-bb14-454453864de3.png)
なんでだよ。

・水曜日以外に`strtotime('last Wednesday + 6 day')`を計算すると、6日後の値になる。
・水曜日以外に`strtotime('last Wednesday + 7 day')`を計算すると、7日後の値になる。
・水曜日に`strtotime('last Wednesday + 6 day')`を計算すると、6日後の値になる。
・水曜日に`strtotime('last Wednesday + 7 day')`を計算すると、14日後の値になる。

書式の曜日が実行した曜日と同じ場合のみ、7日以上の日を足すと何故か値がずれるというバグです。

あまり使わないような書き方をしたうえで、さらに特定の曜日にしか発生しないということで、万一これを踏んでしまったら原因の特定が非常に困難になりそうなバグですね。

あまり使わないというのはつまり、普通は`last Wednesday + 7 day`じゃなくて`next Wednesday`って書くでしょうということですが。


## next Wednesday

このバグチケには載ってないのですが、実は`next`でも同じバグが起こります。

```php
$today = strtotime('next Wednesday');

var_dump(
    (strtotime('next Wednesday') - $today) / 86400,
    (strtotime('next Wednesday - 1 day') - $today) / 86400,
    (strtotime('next Wednesday - 2 day') - $today) / 86400,
    (strtotime('next Wednesday - 3 day') - $today) / 86400,
    (strtotime('next Wednesday - 4 day') - $today) / 86400,
    (strtotime('next Wednesday - 5 day') - $today) / 86400,
    (strtotime('next Wednesday - 6 day') - $today) / 86400,
    (strtotime('next Wednesday - 7 day') - $today) / 86400,
    (strtotime('next Wednesday - 8 day') - $today) / 86400,
    (strtotime('next Wednesday - 9 day') - $today) / 86400,
);
```

水曜日以外に実行すると`[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]`ですが、水曜日に実行すると`[0, -8, -9, -10, -11, -12, -13, -14, -15, -16]`になります。
こちらは`-1`で起こるので、より深刻ですね。


# [Bug #78496 date_create rolls a day back on year 0000 timestamp](https://bugs.php.net/bug.php?id=78496)

問題です。
以下の出力はどうなるでしょう。

```php
$timestamp = strtotime('0000-02-20 00:00:00 UTC');
echo gmdate('Y-m-d H:i:s', $timestamp);
echo date_create('@' . $timestamp)->format('Y-m-d H:i:s');
```

## Expected result

当然ですが、どちらも"0000-02-20 00:00:00"になりますよね。

## Actual result

![20191120-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/75d93c73-c9e3-c6b5-f5fc-3e11c83ab4bd.png)

なんでだよ。

0年についてはdate_createが正しく計算されないというバグがあります。
[西暦0年](https://ja.wikipedia.org/wiki/0%E5%B9%B4)は存在しないとかいうツッコミが聞こえてきそうですが、[ISO 8601](https://ja.wikipedia.org/wiki/ISO_8601)では"0000"年は紀元前1年、"-0001"年は紀元前2年を表します。
めっちゃわかりにくい。


# date_create

[date_create](https://www.php.net/manual/ja/function.date-create.php)関数のヘルプには『DateTime::__construct() のエイリアス』と書かれているのですが、これ嘘です。

```php
var_dump(date_create('2020/01/32')); // false
var_dump(new DateTime('2020/01/32')); // Fatal error: Uncaught Exception: DateTime::__construct(): Failed to parse time string
```

書式が理解できない場合、`date_create`はfalseを返しますが`DateTime::__construct()`は例外を起こします。



# [Bug #78452 diff makes wrong in hour for Asia/Tehran](https://bugs.php.net/bug.php?id=78452)

さて問題です。
以下の出力はどうなるでしょう。

```php
date_default_timezone_set('Asia/Tokyo');
$date1 = new \DateTime('2019-11-05 11:00:00');
$date2 = new \DateTime('2019-11-01 12:00:00');
echo $date1->diff($date2)->format('%H');

date_default_timezone_set('America/New_York');
$date1 = new \DateTime('2019-11-05 11:00:00');
$date2 = new \DateTime('2019-11-01 12:00:00');
echo $date1->diff($date2)->format('%H');
```

## Expected result

今回出力しているのは時間の差分なので、月が違うことは影響しません。
東京は当然ですがそのまま23ですね。
ニューヨークは夏時間切り替えを挟むのでどういう計算になるのかよくわからないのですが、時間差を求める場合は23でいいのですかね？

## Actual result

![78452.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/883ca077-4bc5-9157-3008-3ded2b9541ff.png)
なんでだよ。

夏時間の切り替えをまたぐと何故かマイナスになることがあります。
正解がどの値かはわかりませんが、少なくとも-1は明らかに間違いですね。

夏時間を考えてない勘違いバグ報告は[わりと](https://bugs.php.net/bug.php?id=77741)[よくある](https://bugs.php.net/bug.php?id=77788)のですが、このチケットについては間違いなくバグです。


# [Bug #78504 Add warnings to DateTime object with incompatible timezone info](https://bugs.php.net/bug.php?id=78504)

さて問題です。
以下の出力はどうなるでしょう。

```php
$tz = new DateTimeZone('Asia/Tokyo');
$ts = strtotime('2020-01-1 00:00:00');

$dt1 = DateTime::CreateFromFormat("YmdHis", date('YmdHis', $ts), $tz);
$dt2 = DateTime::CreateFromFormat("U", date('U', $ts), $tz);

var_dump(
    $dt1->format("Y-m-d H:i:s"),
    $dt2->format("Y-m-d H:i:s"),
);
```

## Expected result

当然、両方とも`2020-01-01 00:00:00`ですね。

## Actual result

前者は`2020-01-01 00:00:00`、後者は`2019-12-31 15:00:00`です。
なんでだよ。

実はパラメータをタイムスタンプで渡した場合、引数のタイムゾーンは無視されてUTC扱いされます。

これは[マニュアルに書かれている](https://www.php.net/manual/ja/datetime.createfromformat.php)のですが、あまりにわかりにくいですね。
従って、この挙動はPHP8か9あたりで変更になる可能性があります。


# and

さて問題です。
以下の出力はどうなるでしょう。

```php
$diff = DateInterval::createFromDateString('1 year and 2 months');
```

## Expected result

1年2ヶ月差のDateIntervalオブジェクト。

## Actual result

PHP7.2.17以降、そして7.3.4以降[エラーになります](https://3v4l.org/YgaPE)。

[ChangeLog](https://www.php.net/ChangeLog-7.php#7.3.4)には全く書かれていません。
おそらく[50020のバグ](https://bugs.php.net/bug.php?id=50020)修正と一緒に入り込んだものではないかと思いますが確証はありません。

何が問題かって単に'and'という文字列に対応してないということなので、'1 year 2 months'にすれば[問題なく動作します](https://3v4l.org/inHU0)。
元々対応してなかったのにたまたま動いていたというやつなので、使う方が悪いといえばそうなのですが、でもサイレントに挙動が変わるとびくっとなりますね。



# まとめ

公開されたとか言ってたけど、続きが読みたくてどうしようもなくて我慢できなかったから[描いてもらった](https://twitter.com/rana_kualu/status/1196406927263092736)んですけどね。
さあみんなも[どんどん依頼する](https://skeb.jp/@hanabana_h04)のだ。