【Excel】 日時情報の正体とよくある計算ミス

# Tips「日時情報の正体」

知らないと罠にはまる日時情報のお話

Excel内部では、日時データはすべて[1900年(or1904年)からの経過日数+1日](https://support.microsoft.com/ja-jp/kb/214330)として保持・計算しており、
[書式によって](https://support.microsoft.com/ja-jp/kb/883199)日付形式で**表現**している。

**日付の正体は数値**である。

![0faf940e233ec888431676af6b534f25.gif](https://qiita-image-store.s3.amazonaws.com/0/103957/ed13e1b7-7b2a-2bda-50b7-7e38320be29e.gif)

**1900年を1として扱う計算方式の場合**

| シリアル値 | 書式：数値(0.00) | [書式：yyyy/m/d h:mm (日時)]| [書式：h:mm (時)]|
|--:|--:|:--|:--|
|1|1.00|1900/1/1 0:00|0:00|
|1.25|1.25|1900/1/1 6:00|6:00|
|1.5|1.50|1900/1/1 12:00|12:00|
|2|2.00|1900/1/2 0:00|0:00|
|367|367.00|1901/1/1 0:00|0:00|

シリアル値の整数部：1900年からの経過日数+1日
小数部：時刻

![696d2d7123da37d9d99842190668d492.gif](https://qiita-image-store.s3.amazonaws.com/0/103957/92f72b69-07c0-4987-cd44-e06894eef118.gif)

※Excelでは1900年はうるう年として計算される
> Microsoft が Windows 版の Excel を開発する際、当時シェアが大きかった Lotus 1-2-3 からの移行を容易にするためこれとの互換性を持たせるようにしたいと考えました。ところが Lotus 1-2-3 の日付データの仕様を調べたところ、閏年の扱いについておかしな仕様になっている事がわかったのです。
> (中略)
ですから 1900 年は閏年では無いのですが、Lotus 1-2-3 は 1900 年を閏年として扱っていたのです。
> そして Lotus 1-2-3 の日付のシリアル値は 1900 年 1 月 1 日を 1 としていました。
> [Microsoft Excel の 1900 年 2 月 29 日問題　まとめ - Hebikuzure’s Tech Diary](http://d.hatena.ne.jp/hebikuzure/20100423/1272037288)


また、時間計算も上記のシリアル値によって行われる。

###さまざまな書式で表した時間
セルの書式設定を変えることにより、同じ値でも様々な形式で表示することができる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103957/e98dcad4-7c67-b56a-c718-a91bf0edd34a.png)

<!--
|        | 0.000000 | h:mm | [h]:mm | [mm]:ss | yyyy/m/d hh:mm|
|-------:|------:|:-----:|--------:|-------------:|---------:|
| 1.5日間 |1.500000 |  12:00 | 36:00 | 2160:00 | 1900/1/1 12:00 |
|   1日間 |1.000000 |   0:00 | 24:00 | 1440:00 | 1900/1/1 00:00 | 
|  12時間 |0.500000 |  12:00 | 12:00 |  720:00 | 1900/1/0 12:00 |
|   3時間 |0.125000 |   3:00 |  3:00 |  180:00 | 1900/1/0 03:00 |
|   1時間 |0.041667 |   1:00 |  1:00 |   60:00 | 1900/1/0 01:00 |
|  10分間 |0.006944 |   0:10 |  0:10 |   10:00 | 1900/1/0 00:10 |  
|   1分間 |0.000694 |   0:01 |  0:01 |   01:00 | 1900/1/0 00:01 |
|   1秒間 |0.000012 |   0:00 |  0:00 |   00:01 | 1900/1/0 00:00 |
-->

- [数値の日付または時刻として書式設定 - support.office.com](https://support.office.com/ja-jp/article/%E6%95%B0%E5%80%A4%E3%81%AE%E6%97%A5%E4%BB%98%E3%81%BE%E3%81%9F%E3%81%AF%E6%99%82%E5%88%BB%E3%81%A8%E3%81%97%E3%81%A6%E6%9B%B8%E5%BC%8F%E8%A8%AD%E5%AE%9A%E3%81%97%E3%81%BE%E3%81%99%E3%80%82-418bd3fe-0577-47c8-8caa-b4d30c528309)
- [日付をお好みの形式に設定する - support.office.com](https://support.office.com/ja-jp/article/%E6%97%A5%E4%BB%98%E3%82%92%E3%81%8A%E5%A5%BD%E3%81%BF%E3%81%AE%E5%BD%A2%E5%BC%8F%E3%81%AB%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B-8e10019e-d5d8-47a1-ba95-db95123d273e)
- [Excel で 24 時間を越える時間の合計を計算する方法 - support.office.com](https://support.microsoft.com/ja-jp/kb/879837)


時間の比較および計算では内部的には以下のような処理が行われる。

## 計算例

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103957/68ebb032-0f7a-d79b-b1e1-074f6ab5cde5.png)


###【時刻比較】昼12時より朝6時は早いか？
日時情報の実体は1900年(or1904年)からの**経過日数**+1日であるため、大小関係は以下のようになる。

```math
\mbox{過去の日付} < \mbox{未来の日付}\\\\
\mbox{過去の時間} < \mbox{未来の時間}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103957/65285495-d7ac-1593-5949-03d4d1603de6.png)

```:行われる計算のイメージ
  12:00 > 6:00 [書式：h:mm]
= 1900/1/0 12:00 > 1900/1/0 6:00 [書式：yyyy/m/d h:mm]
= 0.5 > 0.25 
= TRUE
```

###【時間計算】朝6時から昼12時までの時間を求める

Excelは日時情報を1900年(or1904年)からの経過日数+1日として保持しているため、時間計算を引き算によって行うことができる。

※小数計算になるので、複雑な計算をすると誤差が発生するおそれがあるので注意。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103957/ef78a0c3-57c7-7062-54d3-06ae1782d6f0.png)

```:行われる計算のイメージ
  12:00 - 6:00 [書式：[h]:mm]
= 1900/1/0 12:00 - 1900/1/0 6:00 [書式：yyyy/m/d h:mm]
= 0.5 - 0.25 
= 0.25
= 1900/1/0 6:00 [書式：yyyy/m/d h:mm]
= 6:00 [書式：[h]:mm]　(日付情報が書式により省略されている)
```

## 誤った計算例
###【時間計算】6時間から12時間を引く
この計算は、シリアル値に対応する日時が存在しないため、行うことができない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103957/bc76fbea-66da-fbcb-d921-1daafdbb902c.png)

```:行われる計算のイメージ
  6:00 - 12:00
= 0.25 - 0.5 
= -0.25
= ########## [書式：[h]:mm]　(対応する日時が存在しないため書式エラー)
```

###【給与計算】6時間 時給1000円で働いたときの給与
この計算は、Excel内部のシリアル値を無視した計算なので、意図した結果とならない。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103957/a16a2dd4-9938-4a02-0729-98527fde31f8.png)

```:行われる計算のイメージ
  6:00 * 1000
= 0.25 * 1000 
= 250
```
見かけ上`6:00`や`6時00分`と**表現**されているだけで、実際に保持している値は`0.25`（=0.25日間）。
「1日間 = 24時間」なので、期待した結果を得るためには、以下の計算を行う必要がある。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103957/6f80a98d-a93f-b062-b2f7-22ee0df565df.png)

```:行われる計算のイメージ
  6:00 * 24 * 1000 
= 0.25 * 24 * 1000 
= 6 * 1000
= 6000
```

使いたい時間単位に合わせて、数式に以下の数字をそれぞれ掛ければ求める計算結果を得ることができる。

### 【早見表】時間単位変換用係数
| 目的の計算単位 | 係数 | 説明 |
|:----:|----:|:------|
| 日 |     1 | 1day = 1day |
| 時 |    24 | 1day = 24h |
| 分 |  1440 | 1day = 24h * 60m |
| 秒 | 86400 | 1day = 24h * 60m * 60s|

###【期間集計】8月1日~3日の売上
次の計算は、書式により省略された時刻情報について考慮されていないため、意図した結果とならない。

```:まちがい
=SUMIFS([[集計対象]],[[日付列]],">="[[集計開始日]],[[日付列]],"<="&[[集計終了日]])
```

下図では、8月1日～3日の売上金額がC2～C27セルに記録されている。

- C2～C27セルを単純にSUMで合計したC28セルの数値
- C2～C27セルの内「2017年8月～8月3日」のみの売上金額を合計したF4セルの数値

この2つの計算結果は同じ値になっていなければならないハズなのにズレている。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103957/e3941d9d-fb7b-f3c2-952c-25c0706ca455.png)

理由は、`H2`セルに表示されている`2017/8/3`は書式情報が省略された`2017/8/3 0:00`というデータなので、8月3日の売上が殆ど集計されていないから。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103957/2c0ee1e7-3124-3744-60a1-d40b6fbd81ad.png)

正しく集計できる数式は以下。

```:正解
=SUMIFS([[集計対象]],[[日付列]],">="[[集計開始日]],[[日付列]],"<"&[[集計終了日]]+1)
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103957/f946b1b5-0aac-169e-e4b6-62c12fb13c4b.png)

`[[日付列]],"<"&[[集計終了日]]+1`とすることで、8月3日0:00の24時間後である**8月4日0:00より前**の期間までを集計することにより、8月3日23時59分59.9999秒のデータも正しく集計できる。



#おわりに

Excelの書式機能は便利で強力ですが、見かけの値と実際の値に予期せぬギャップが生じやすく、思わぬ計算ミスを招くことが多々あります。
日時や小数が影響する計算は特に気をつけて処理して、なるべく電卓で再計算することをオススメいたします。。

Excelの罠についてよくまとまっているQiita記事を見つけたので、此方も是非ご一読を。
[「電卓使って再計算しろ！」→「Excelなんだから間違うはずないでしょ！」と言いたいけど言えないExcel落とし穴 - Qiita](http://qiita.com/tomikiya/items/a2fff372dfec09d620fd)

# その他 参考リンク

以下、参考情報

- [Excel の 1900 年を基準とした日付方式と 1904 年を基準とした日付方式の違いについて - support.microsoft.com](https://support.microsoft.com/ja-jp/kb/214330)

- [[XL] 1900 年から計算する日付システムと 1904 年から計算する日付システム - support.microsoft.com](https://support.microsoft.com/ja-jp/kb/180162)
- [「1904年」に何があったのか？（第17回） - ITpro](http://itpro.nikkeibp.co.jp/pc/article/NPC/20070626/275901/)