## 概要
Stataで日付データを扱う際は、単純な数値として処理すると正しい計算ができない。文字列から日付型への変換と、適切なフォーマット指定が必要となる。
## よくある間違い:数値としての日付計算
日付を`YYYYMMDD`形式の数値として入力し、そのまま引き算すると誤った結果になる。
```stata
clear all
input x y
20260204 20260102
end
format x y %8.0f
gen z = x - y
list
```
```
+---------------------------+
| x y z |
|---------------------------|
1. | 20260204 20260102 102 |
+---------------------------+
```
2026年2月4日と2026年1月2日の差は33日だが、単純な引き算では102という無意味な値になる。
## 正しい方法:date()関数による変換
### 基本的な使い方
文字列データを`date()`関数で日付型に変換する。
```stata
clear all
input str10 x str10 y
"20260204" "20260102"
end
list
```
```
+---------------------+
| x y |
|---------------------|
1. | 20260204 20260102 |
+---------------------+
```
`date()`関数で日付型に変換する。第2引数で日付の並び順を指定する。
```stata
gen x_date = date(x, "YMD")
gen y_date = date(y, "YMD")
list x_date y_date
```
```
+-----------------+
| x_date y_date |
|-----------------|
1. | 24141 24108 |
+-----------------+
```
変換直後の値は、1960年1月1日からの経過日数として格納される。人間が読める形式にするにはフォーマットを適用する。
```stata
format x_date %tdCCYY-NN-DD
format y_date %tdCCYY-NN-DD
list x_date y_date
```
```
+-------------------------+
| x_date y_date |
|-------------------------|
1. | 2026-02-04 2026-01-02 |
+-------------------------+
```
### 日数差の計算
日付型同士の引き算で正しい日数差が得られる。
```stata
gen z_days = x_date - y_date
list
```
```
+--------------------------------------------------------+
| x y x_date y_date z_days |
|--------------------------------------------------------|
1. | 20260204 20260102 2026-02-04 2026-01-02 33 |
+--------------------------------------------------------+
```
## date()関数の第2引数
`date()`関数の第2引数は、元の文字列の日付の並び順を指定する。
| 引数 | 意味 | 例 |
|------|------|-----|
| `"YMD"` | 年-月-日 | "20260204", "2026/02/04" |
| `"DMY"` | 日-月-年 | "04-02-2026" |
| `"MDY"` | 月-日-年 | "Feb 4, 2026", "02/04/2026" |
区切り文字(`/`、`-`、スペースなど)は自動的に認識される。
```stata
clear all
input str12 date1 str12 date2 str15 date3
"2026/02/04" "04-02-2026" "Feb 4, 2026"
end
list
```
```
+---------------------------------------+
| date1 date2 date3 |
|---------------------------------------|
1. | 2026/02/04 04-02-2026 Feb 4, 2026 |
+---------------------------------------+
```
```stata
gen d1 = date(date1, "YMD")
gen d2 = date(date2, "DMY")
gen d3 = date(date3, "MDY")
format d1 d2 d3 %tdCCYY-NN-DD
list d1 d2 d3
```
```
+--------------------------------------+
| d1 d2 d3 |
|--------------------------------------|
1. | 2026-02-04 2026-02-04 2026-02-04 |
+--------------------------------------+
```
異なる形式の文字列から、すべて同じ日付に変換できる。
## 日付フォーマットの種類
よく使用されるフォーマット指定:
| フォーマット | 表示例 |
|-------------|--------|
| `%td` | 04feb2026 |
| `%tdCCYY-NN-DD` | 2026-02-04 |
| `%tdCCYY/NN/DD` | 2026/02/04 |
| `%tdDD-Mon-CCYY` | 04-Feb-2026 |
| `%tdMon_DD,_CCYY` | Feb 04, 2026 |
## 実用例:年齢計算
今日の日付は`c(current_date)`で取得できる。
```stata
clear all
set obs 1
gen today = date(c(current_date), "DMY")
format today %tdCCYY-NN-DD
gen birth = date("1990-05-15", "YMD")
format birth %tdCCYY-NN-DD
gen age_days = today - birth
gen age_years = int(age_days / 365.25)
list
```
```
+-----------------------------------------------+
| today birth age_days age_ye~s |
|-----------------------------------------------|
1. | 2026-02-04 1990-05-15 13049 35 |
+-----------------------------------------------+
```
## まとめ
- 日付を数値として計算してはいけない
- `date()`関数で文字列から日付型に変換する
- 第2引数(`"YMD"`、`"DMY"`、`"MDY"`)で元データの並び順を指定する
- `format`で表示形式を設定する
- 日付型同士の引き算で日数差が計算できる