kintone年齢計算の式まとめ 日付計算でTODAYが使えない問題の解決法【2026年版】
本記事は、kintone(キントーン)の構築・カスタマイズとプラグイン開発の実務経験をもとに、実際のkintone環境で式を1本ずつ通しながら検証した結果をまとめたものです。掲載している式はすべて、この記事のために作った検証アプリで動作と数値を確かめています(検証日:2026年8月23日)。
生年月日から年齢を出したい。入社日から在籍期間を出したい。やりたいことは単純なのに、kintoneの計算式に TODAY() と書くと真っ赤なエラーが出ます。この記事で分かることは次のとおりです。
- kintoneの計算式で使える関数・使えない関数(実際のエラー文つき)
- 「今日」の代わりに使える唯一のフィールドと、その落とし穴
- 45件の境界テストでずれが出なかった年齢の式(+よく紹介される概算式がずれた条件)
- 経過日数・在籍期間・N日後など、日付計算の逆引きレシピ
- 設定だけで「常に今日の値」にする方法
計算フィールドそのものの基本的な使い方はkintone計算フィールドの使い方と計算式の例にまとめてあります。この記事は「日付と年齢の式」に絞って掘ります。
TODAY関数は無い。まずここが出発点
Excelで年齢を出すなら DATEDIF(生年月日, TODAY(), "Y") のような式を書きます。同じ発想でkintoneの計算式に TODAY() と入れると、フォームを保存した瞬間に弾かれます。

「使用できません」という書き方が示すとおり、kintone側で明確に禁止されています。ほかの日付系の関数も同様です。検証アプリで1本ずつ試した結果が次の表です。
| 書いた式 | 結果 | kintoneが返したエラー |
|---|---|---|
TODAY() | 使えない | TODAY関数は使用できません。 |
NOW() | 使えない | NOW関数は使用できません。 |
YEAR(生年月日) | 使えない | YEAR関数は使用できません。 |
DATE_FORMAT(生年月日, "YYYY", "Asia/Tokyo") | 使える | — |
(退職日 - 入社日) / (60*60*24) | 使える | — |
つまり、日付を扱う道具は DATE_FORMAT と四則演算だけ。この2つでどこまでやれるかが勝負になります。
Excelの関数名で当たりを付けるより、先に「利用できる関数」を見たほうが速いです。計算式の設定ダイアログの右上に、公式の一覧へのリンクがあります。
日付フィールドは、式の中では「秒数」になる
年齢の話に入る前に、日付計算の土台を押さえます。計算式の中の日付フィールドは、秒数として扱われます。

1日は 60 * 60 * 24 = 86,400秒。ここから基本の2本が導けます。
- 2つの日付の差(日数):
(退職日 - 入社日) / (60*60*24) - N日後の日付:
入社日 + 60*60*24*90(90日後)
後者は表示形式を「日付」にしておくのがコツです。計算フィールドの設定ダイアログには数値のほかに「日時」「日付」「時刻」「時間」が並んでいて、日付を選べば計算結果がそのまま日付として表示されます。検証アプリでは入社日 2014-04-01 に対して 入社日 + 60*60*24*90 が 2014-06-30 と表示されました。試用期間の満了日や更新期限の自動表示にそのまま使えます。

「今日」の代わりになるのは更新日時だけ
TODAY() が無い以上、「今日」に相当する値をどこかから持ってくる必要があります。kintoneには2つだけ候補があります。作成日時と更新日時です。この2つは計算式の中でフィールドコードとして参照できます。
| 参照するもの | 書き方 | 何を指すか | 年齢に使えるか |
|---|---|---|---|
| 更新日時 | 更新日時 | 最後に保存した日時 | 使える(保存し直すと今日になる) |
| 作成日時 | 作成日時 | レコードを登録した日時 | 使えない(登録時点で固定される) |
| 英語のコード | UPDATED_TIME | — | フィールドコードが存在しないとエラー |
年齢に使えるのは更新日時のほうです。作成日時は登録した瞬間で止まるので、去年登録したレコードは去年の年齢のままになってしまいます。
先に「更新日時」をフォームに置く
ここが最初の関門です。更新日時はkintoneが自動で持っている項目ですが、フォームに配置していない状態で計算式から参照すると、フォームの保存自体ができません。
検証アプリで実際に出たエラー文がこれです。
計算式に含まれるフィールドコード(更新日時)が存在しません。
対処は単純で、フォーム設定の左側から**「更新日時」を1つドラッグして置く**だけ。置いた瞬間から 更新日時 が有効なフィールドコードになり、フォームが保存できるようになります。値は自動入力なので、フォームのいちばん下に置いておけば入力の邪魔にもなりません。

更新日時方式の限界も先に書いておく
更新日時は「最後に保存した日時」です。つまり保存し直さないと今日になりません。レコードを開いただけでは値は動きません。
計算フィールドがそもそも保存時にしか再計算されない仕様なので、これは避けられない制約です(詳しくは計算フィールドの弱点に整理しています)。運用でどう埋めるかは、この記事の後半で扱います。
年齢の式:3つのやり方を実機で比べた
ここが本題です。年齢の出し方には有力な候補が3つあります。結論から言うと、**採用すべきは3番目の「2段構え」**です。

やり方1:365.2425で割る(概算)
ネット上でよく見かけるのがこれです。1年の平均日数で割って切り捨てます。
ROUNDDOWN((更新日時 - 生年月日) / (60*60*24*365.2425), 0)
式が1本で済むのが利点。ただし平均で割っているので、誕生日ちょうどの日にずれることがあります。どの程度ずれるのか、生年月日を1年前から80年前まで振り、それぞれ誕生日の前日・当日・翌日の3パターン=45件で検算しました。
結果は45件中2件がずれ。10年前生まれと18年前生まれの、誕生日当日のレコードだけ1歳少なく出ました。誕生日の前日と翌日は全件正しい値です。
年齢を目安として眺めるだけなら実用範囲でしょう。ただし「今日18歳になった人を抽出する」ような使い方をすると事故ります。
やり方2:DATE_FORMATを式に混ぜる(できない)
「年の差を取って、誕生日が来ていなければ1を引く」という素直な発想を、そのまま1本の式で書くとこうなります。
DATE_FORMAT(更新日時, "YYYY", "Asia/Tokyo") - DATE_FORMAT(生年月日, "YYYY", "Asia/Tokyo")
この式は保存できます。エラーも出ません。それなのに、値は空のままになります。
これがいちばんハマるところでした。DATE_FORMAT(生年月日, "YYYY", "Asia/Tokyo") を単独で計算フィールドに入れると 1992 と数字が表示されるのに、引き算や比較の項として使うと全部空になる。掛け算も IF の条件も同じでした。
| 式 | 結果 |
|---|---|
DATE_FORMAT(生年月日, "YYYY", "Asia/Tokyo") | 1992 |
DATE_FORMAT(生年月日, "MM", "Asia/Tokyo") | 1 |
DATE_FORMAT(更新日時, "YYYY", …) - DATE_FORMAT(生年月日, "YYYY", …) | 空 |
DATE_FORMAT(生年月日, "MM", …) * 100 + DATE_FORMAT(生年月日, "dd", …) | 空 |
IF(DATE_FORMAT(生年月日, "MM", …) < 6, 1, 0) | 空 |
年数 & "年" & 月数 & "ヶ月"(計算フィールドで連結) | 空 |
DATE_FORMAT が返すのは文字列だからです。表示するだけなら数字に見えても、演算の材料には使えません。「保存できたのに空欄」を見たら、まずDATE_FORMATを疑ってください。
なお "YYYYMMdd" のように区切りなしでまとめて取り出す書き方も空になりました。数字として取り出せるのは "YYYY" "MM" "dd" のように1つずつのときだけです。
やり方3:2段構えにする(推奨)
やり方2が使えない理由がはっきりすれば、解決策も見えてきます。DATE_FORMATの結果をいったん別の計算フィールドに出しておき、2段目でそのフィールドを参照するのです。

1段目は、計算フィールドを6つ作ってそれぞれ1つの値だけを取り出します。
| フィールド名 | フィールドコード | 計算式 |
|---|---|---|
| 今年 | y_now | DATE_FORMAT(更新日時, "YYYY", "Asia/Tokyo") |
| 今月 | m_now | DATE_FORMAT(更新日時, "MM", "Asia/Tokyo") |
| 今日 | d_now | DATE_FORMAT(更新日時, "dd", "Asia/Tokyo") |
| 生まれ年 | y_bir | DATE_FORMAT(生年月日, "YYYY", "Asia/Tokyo") |
| 生まれ月 | m_bir | DATE_FORMAT(生年月日, "MM", "Asia/Tokyo") |
| 生まれ日 | d_bir | DATE_FORMAT(生年月日, "dd", "Asia/Tokyo") |
2段目が本体です。年の差を取り、誕生日がまだ来ていなければ1を引きます。
y_now - y_bir - IF(m_now * 100 + d_now < m_bir * 100 + d_bir, 1, 0)
月 * 100 + 日 で「823」のような月日の数字を作り、大小を比べているだけです。同じ45件の境界テストにかけた結果は、ずれ0件。うるう年の2月29日生まれも、誕生日の当日・前日・翌日も、すべて期待どおりの値になりました。

上の一覧が2つの式を並べた結果です。生年月日が 2008-08-23 の行(撮影日がちょうど誕生日)だけ、概算式が1歳少なく出ています。ほかの行は一致します。
1段目のフィールドが6つ増えるのは確かに冗長です。設定ダイアログの「フィールド名を表示しない」「計算式を表示しない」にチェックを入れ、フォームの下のほうにまとめて置いてしまえば、実際の運用で目に入ることはありません。

日付計算の逆引きレシピ
年齢以外もまとめておきます。すべて検証アプリで通した式です。更新日時 を使うものは、フォームに更新日時を置いてから設定してください。
| やりたいこと | 式 | 補足 |
|---|---|---|
| 2つの日付の日数 | (退職日 - 入社日) / (60*60*24) | 表示形式は数値 |
| 今日までの経過日数 | ROUNDDOWN((更新日時 - 入社日) / (60*60*24), 0) | 保存し直すと最新になる |
| N日後の日付 | 入社日 + 60*60*24*90 | 表示形式を「日付」に |
| 年齢(厳密) | y_now - y_bir - IF(m_now * 100 + d_now < m_bir * 100 + d_bir, 1, 0) | 1段目の6フィールドが必要 |
| 在籍年数 | ROUNDDOWN((更新日時 - 入社日) / (60*60*24*365.2425), 0) | 500件の検算でずれなし |
| 在籍の端月数 | ROUNDDOWN((更新日時 - 入社日) / (60*60*24*30.436875), 0) - 在籍年数 * 12 | 同上 |
| 「◯年◯ヶ月」の表示 | 在籍年数 & "年" & 在籍の端月数 & "ヶ月" | 文字列(1行)フィールドの自動計算で書く |
| 曜日 | — | 曜日を返す書式が無く、標準では出せない |
| 営業日ベースの日数 | — | 祝日を持っていないため近似しかできない |
| 月末の日付 | — | 月の日数を求める手段が無い |
文字を混ぜたいときは、計算フィールドではなく文字列(1行)フィールドの自動計算を使うのがポイントです。計算フィールドで & を使うと空になりますが、文字列(1行)フィールドなら 12年4ヶ月 と表示されます。年齢に「歳」を付けたい場合も同じ方法です。
在籍期間の式は、入社日を20年ぶん・各月の1日/15日/28日/29日/30日/31日と振った500件で暦どおりの値と突き合わせて、ずれ0件でした。年数と端月数の2本立てになるのが少し手間ですが、精度は十分です。
つまずきやすい3つのこと

空の日付は「1970年1月1日」として計算される
これは知らないと必ず踏みます。(退職日 - 入社日) / (60*60*24) という式で、退職日が空のレコードは巨大なマイナスになります。

空欄が0(=1970年1月1日)として扱われるためです。回避は IF で分岐させるだけです。
IF(退職日 > 入社日, ROUNDDOWN((退職日 - 入社日) / (60*60*24), 0), ROUNDDOWN((更新日時 - 入社日) / (60*60*24), 0))
退職日が入っていればその日まで、空なら今日まで。空の判定は 退職日 = 0 でも 退職日 = "" でも動きましたが、上のように大小比較で書くほうが意図が読み取りやすいと思います。
退職者の在籍期間が伸び続ける
上の式で在籍日数は止まりますが、更新日時 を使う式は基本的に条件を書かないと止まりません。退職済みの人の在籍期間が23年4ヶ月、24年0ヶ月と増えていくのは、名簿としては不自然です。
パターンごとに IF で止める条件を書き足す形になるので、止めたい計算が増えるほど式は長くなります。
一覧の並び替え・絞り込みは「保存された値」で動く
計算フィールドの値は保存時に確定した実データなので、並び替えや絞り込み、グラフでの集計にはそのまま使えます。裏を返せば、最後に保存した日がレコードごとにバラバラなら、並べても比較になりません。
「40歳以上を抽出」のような絞り込みを正しく動かすには、対象のレコードを定期的に保存し直して値をそろえる必要があります。件数が少なければ手作業でも回りますが、数百件になると現実的ではありません。かんたん一括更新のように一覧から複数レコードをまとめて更新できる仕組みを併用すると、この「そろえる」作業を短縮できます。
設定だけで「常に今日の値」にしたい場合
ここまでの式は、すべて「保存し直せば今日になる」という前提の上に立っています。式を組む手間、1段目のフィールド6つ、止める条件の IF、そして保存し直す運用——これを全部引き受けるかどうかは、対象の件数と更新頻度で決まります。
コードを書かずに、開くたびに今日基準の値を出したい場合は、日付計算に特化したプラグインを足すのが早道です。当社の経過計算アシスト for kintoneは、基準日フィールドと計算パターンを選ぶだけで年齢・経過日数・在籍期間などを自動計算します。

この記事で扱った内容との対応で言うと、次の点が違います。
| この記事の式 | 経過計算アシスト |
|---|---|
| フォームに更新日時を置き、下準備のフィールドを6つ作る | 基準日と計算パターンを選ぶだけ |
| 保存し直すまで値は古いまま | 一覧・詳細を開くたびに今日基準で再計算して表示 |
止めたい計算ごとに IF を書き足す | 停止条件(最大5件・AND/OR)を設定画面で指定 |
| 既存レコードは手作業で保存し直す | 一括再計算ボタンで絞り込み結果をまとめて更新 |
| 年齢・経過日数・在籍期間を自分で組む | 年齢・学年・稼働日・次回記念日など9パターンから選ぶ |

ケース別・どちらで進めるか
- 数十件の名簿で、年齢は目安でよい →
365.2425で割る概算式。式1本で終わります - 年齢で抽出・判定をする(18歳到達、定年など) → 2段構えの厳密な式。誕生日当日でずれません
- 件数が多く、常に今日の値で並べたい → 保存し直す運用が回らないので、プラグインを検討する段階
- 曜日・営業日・月末が必要 → 標準の計算式では出せません。JavaScriptカスタマイズかプラグインへ
まず概算式で始めて、抽出に使いたくなった時点で2段構えに差し替える、という進め方でも問題ありません。1段目のフィールドを足して2段目の式を書き換えるだけで、既存データは保存し直せばそろいます。
まとめ
- kintoneの計算式に
TODAY()NOW()YEAR()は無い。「使用できません」と明示的に弾かれる - 「今日」の代わりに使えるのは
更新日時だけ。先にフォームへ配置しないと保存できない DATE_FORMATは単独なら数字が出るが、式の中で計算・比較には使えない(保存できるのに値が空になる)- 年齢は2段構えが正解。1段目で年・月・日を取り出し、
y_now - y_bir - IF(m_now * 100 + d_now < m_bir * 100 + d_bir, 1, 0)。45件の境界テストでずれなし - よく見る
365.2425の概算式は、誕生日当日に1歳ずれる年がある(45件中2件) - 空の日付は1970年1月1日として計算される。
IFで分岐させる - 文字を混ぜた「◯年◯ヶ月」は文字列(1行)フィールドの自動計算で作る
- 保存し直さないと今日にならない。件数が増えたら経過計算アシストのような仕組みで補う
kintoneの計算式や日付まわりでお困りのことがあれば、お問い合わせからお気軽にご相談ください。関連する話題としてkintone計算フィールドの使い方と計算式の例、kintoneの集計方法まとめもあわせてご覧いただけます。ほかの製品はkintoneプラグイン一覧からどうぞ。


