はじめに
さて今回は、Javaにおける時刻関連の変数名に関する慣習についてまとめたいと思います。
仕事の関連でJavaのソースコードを読んでいた際、慣習的に使われる変数名があることを知ったので、忘れないようにまとめておこうと思った背景です。
例えば、次のような変数名を見かけることがあります。
private Instant createdAt;
private Instant updatedAt;
private Instant deletedAt;これらはいずれも、末尾に「At」が付いています。しかも、見ていたソースだけでなく、色々なところで使われていたので、これは何やら暗黙の慣習があるのかと思い調べてみると、やはりその通りといったところでした。
また、日時を表す名前には、「At」以外にも「Date」、「Time」、「From」、「Until」、「Duration」、「Timeout」など、よく使われる単語があります。
それぞれの意味を理解せずに使用すると、
- 日付だけを保持するのか、時刻まで保持するのか分からない
- タイムゾーンを含む値なのか分からない
- 開始時刻と終了時刻の範囲が曖昧になる
- 予定時刻と、実際に処理された時刻を区別できない
- 開発者間で誤解を招く原因となる
など後々困ったことになりかねないので、正しく理解し、扱えるようになりましょう。
Javaにおける基本的な変数の命名規則
日時の命名を確認する前に、Javaの基本的な命名規則を押さえておきましょう。
Javaのフィールド名や変数名では、先頭を小文字にし、単語の区切りから大文字にするローワーキャメルケースが一般的です。
createdAt
lastLoginAt
paymentDueDate
requestTimeoutOracleのJava命名規則でも、フィールドは小文字から始まる複合語形式とし、内容を推測できる名詞または名詞句を使用することが示されています。
そのため、「created_at」や「CREATED_AT」ではなく、Javaの変数としては「createdAt」と書くのが一般的です。
「At」が表す意味
「At」は、基本的に「ある出来事が発生した特定の時点」を表します。
例えば、「createdAt」は英語の「created at 10:00」のような表現から、作成された時点を意味します。
private Instant createdAt; // 作成された日時
private Instant updatedAt; // 更新された日時
private Instant approvedAt; // 承認された日時通常、「At」を付けた変数は日付だけではなく、年月日と時刻を含む日時を保持します。そのため、「Instant」、「OffsetDateTime」、「ZonedDateTime」、「LocalDateTime」などと組み合わせて使われます。
「At」を使った代表的な変数名
登録・更新・削除に関する日時
| 変数名 | 意味 |
|---|---|
| createdAt | データが作成された日時 |
| updatedAt | データが最後に更新された日時 |
| modifiedAt | データが最後に変更された日時 |
| deletedAt | データが削除された日時 |
| restoredAt | 削除済みデータなどが復元された日時 |
「updatedAt」と「modifiedAt」は、どちらも「変更された日時」として使われます。同じシステム内で両方を使うと違いが分かりにくいため、どちらか一方へ統一するのがおすすめです。
また、「lastUpdatedAt」という名前も使われますが、「updatedAt」だけでも「最後に更新された日時」を表すことが一般的です。複数種類の更新日時があり、最後の更新であることを強調したい場合に「lastUpdatedAt」を使うとよいでしょう。
認証・アクセスに関する日時
| 変数名 | 意味 |
|---|---|
| loginAt | ログインした日時 |
| lastLoginAt | 最後にログインした日時 |
| logoutAt | ログアウトした日時 |
| lastAccessedAt | 最後にアクセスした日時 |
| passwordChangedAt | パスワードを変更した日時 |
| verifiedAt | メールアドレスや本人確認などが完了した日時 |
| lockedAt | アカウントがロックされた日時 |
履歴を1件ずつ保存するログイン履歴であれば「loginAt」、ユーザー情報に最後のログイン日時だけを保持するのであれば「lastLoginAt」が分かりやすい名前です。
処理・通信に関する日時
| 変数名 | 意味 |
|---|---|
| requestedAt | リクエストを受け付けた日時 |
| receivedAt | データやメッセージを受信した日時 |
| sentAt | データやメッセージを送信した日時 |
| processedAt | 処理した日時 |
| completedAt | 処理が完了した日時 |
| failedAt | 処理が失敗した日時 |
| retriedAt | 再試行した日時 |
| cancelledAt | キャンセルされた日時 |
イベント駆動システムでは、次の2つを分けることも重要です。
private Instant occurredAt; // 業務上の出来事が実際に発生した日時
private Instant recordedAt; // システムへ記録された日時例えば、店舗で15時に売上が発生し、通信障害のため15時10分にサーバーへ登録された場合、「occurredAt」は15時、「recordedAt」は15時10分になります。
公開・有効期限に関する日時
| 変数名 | 意味 |
|---|---|
| publishedAt | 実際に公開された日時 |
| unpublishedAt | 公開が終了した日時 |
| expiresAt | 有効期限が切れる予定日時 |
| expiredAt | 実際に期限切れとして処理された日時 |
| activatedAt | 有効化された日時 |
| deactivatedAt | 無効化された日時 |
特に注意したいのが、「expiresAt」と「expiredAt」の違いです。
private Instant expiresAt; // この日時になると期限切れになる
private Instant expiredAt; // 期限切れ処理が実際に行われた「expiresAt」は将来を含む期限、「expiredAt」は実際に起きた結果を表す名前として使い分けられます。バッチ処理が遅れた場合などは、この2つの値が一致しないことがあります。
システム開発では、「予定している時刻」と「実際に起きた時刻」を区別することが重要です。
| 予定・設定 | 実績 | 意味 |
|---|---|---|
| startsAt | startedAt | 開始予定日時/実際の開始日時 |
| endsAt | endedAt | 終了予定日時/実際の終了日時 |
| expiresAt | expiredAt | 期限日時/実際に期限切れとなった日時 |
| scheduledFor | processedAt | 実行予定日時/実際に処理した日時 |
例えば、バッチ処理を午前2時に開始する予定でも、実際には混雑によって午前2時5分に始まる可能性があります。
なお、「scheduledAt」は「実行予定日時」と「予定を登録した日時」のどちらにも読めるため、注意が必要です。以下のように分けると意味が明確になります。
private Instant scheduledFor; // 処理を実行する予定日時
private Instant scheduledAt; // 予定を登録した日時「Date」、「Time」、「DateTime」の使い分け
Date:日付だけを表す
年月日だけが必要で、時刻を持たない値には「Date」を使います。
private LocalDate birthDate; // 生年月日
private LocalDate deliveryDate; // 配送日
private LocalDate dueDate; // 期限日
private LocalDate closingDate; // 締め日例えば誕生日は、通常「2026年8月11日」のような日付に意味があり、「2026年8月11日0時0分」という時点を表すものではありません。そのため、「birthAt」や「LocalDateTime birthDate」ではなく、「LocalDate birthDate」が自然です。
Time:時刻だけを表す
日付を含まず、時刻だけを表す場合は「Time」を使います。
private LocalTime openingTime; // 開店時刻
private LocalTime closingTime; // 閉店時刻
private LocalTime cutoffTime; // 締切時刻ただし、「createdTime」のような名前は、日時全体なのか時刻だけなのか分かりにくくなる場合があります。特定の時点を表すのであれば「createdAt」、時刻だけであれば「creationTimeOfDay」など、意味が明確な名前を選びます。
DateTime:日付と時刻を明示する
「orderDateTime」のように「DateTime」を付ける名前もあります。ただし、型が「LocalDateTime」であれば、変数名にまで「DateTime」を含めると冗長になることがあります。
private LocalDateTime scheduledDateTime;この名前自体は間違いではありませんが、予定された時点を表したいのであれば、次の方が業務上の意味を読み取りやすくなります。
private LocalDateTime scheduledFor;型が表す技術的な情報をそのまま名前にするよりも、「何の日時なのか」を名前で示すことが大切です。
その他よく使われる変数名
期間の開始と終了を表す名前
期間を表す場合は、「start」と「end」、または「from」と「to」などが使われます。
| 命名例 | 意味 |
|---|---|
| startAt / endAt | 処理やイベントの開始日時と終了日時 |
| validFrom / validUntil | 有効期間の開始日時と終了日時 |
| fromDate / toDate | 検索条件などの日付範囲 |
ここで注意したいのが、境界を範囲へ含めるかどうかです。
例えば「validFrom」を範囲に含み、「validUntil」を含まないルールであれば、次のような半開区間になります。
validFrom <= target < validUntil経過時間や時間量を表す名前
「At」は特定の時点を表します。一方、「30分間」「5秒経過」のような時間量には、「Duration」、「Timeout」、「Interval」などを使います。
| 変数名 | 意味 |
|---|---|
| processingDuration | 処理にかかった時間 |
| retryInterval | 再試行の間隔 |
| retentionPeriod | 保存期間 |
| requestTimeout | リクエストを待つ上限時間 |
private Duration requestTimeout;
private Duration retryInterval;
private Duration processingDuration;
private Period warrantyPeriod;「Duration」は秒やナノ秒を基準とする時間量、「Period」は年・月・日を基準とする期間です。
例えば「処理を30秒待つ」は「Duration」が適しています。一方、「保証期間2年」のように暦に基づく期間は「Period」が適しています。
数値で時間を保持するときは単位を名前に含める
時間を「int」や「long」で保持すると、値の単位が分からなくなることがあります。
long timeout = 30;この「30」が30秒なのか、30ミリ秒なのかは、変数名だけでは判断できません。
なので、数値を使う必要がある場合は、単位を変数名へ含めます。
long timeoutMillis = 30_000;
long elapsedSeconds = 15;
long createdAtEpochMillis = 1_786_377_600_000L;ただし、Javaでは可能な限り「Duration」や「Instant」を使用した方が、単位の取り違えを防げます。
Duration timeout = Duration.ofSeconds(30);
Instant createdAt = Instant.now();Tips:変数名とJava型を対応させる
適切な変数名を付けても、型の選択を誤ると日時の意味が曖昧になります。
| 表したいもの | 主なJava型 | 変数名の例 |
|---|---|---|
| 世界共通の時間軸上の一点 | Instant | createdAt、occurredAt |
| UTCからのオフセットを含む日時 | OffsetDateTime | receivedAt |
| 地域のタイムゾーンを含む日時 | ZonedDateTime | meetingStartsAt |
| タイムゾーンを持たない日付と時刻 | LocalDateTime | appointmentStartsAt |
| 日付だけ | LocalDate | birthDate、dueDate |
| 時刻だけ | LocalTime | openingTime |
| 秒・ナノ秒ベースの時間量 | Duration | timeout、elapsedTime |
| 年・月・日ベースの期間 | Period | warrantyPeriod |
| タイムゾーン識別子 | ZoneId | userZoneId |
Instant
「Instant」は、世界共通の時間軸上の特定の時点を表します。タイムゾーンそのものは保持しません。
private Instant createdAt;作成日時、更新日時、ログ、メッセージの発生日時など、システム内部で一意の時点を記録したい場合の有力な選択肢です。画面へ表示するときに、利用者の`ZoneId`を使って日本時間などへ変換します。
OffsetDateTime
「OffsetDateTime」は、「+09:00」のようなUTCからのオフセットを含む日時です。
private OffsetDateTime receivedAt;APIでオフセット付きの日時を受け渡す場合や、受信したオフセットも保持したい場合に利用できます。
ZonedDateTime
「ZonedDateTime」は、「Asia/Tokyo」や「America/New_York」のような地域のタイムゾーンを含む日時です。
private ZonedDateTime meetingStartsAt;地域ごとのタイムゾーンルールを考慮する必要がある会議、交通機関、国際的な予約などに向いています。
LocalDateTime
「LocalDateTime」は日付と時刻を保持しますが、タイムゾーンもUTCオフセットも持ちません。
private LocalDateTime appointmentStartsAt;予約を扱う施設のタイムゾーンが別の項目やシステムの前提によって明確な場合などには利用できます。一方、「LocalDateTime createdAt」だけでは、東京の10時なのかロンドンの10時なのかを判別できません。複数地域で利用するシステムの監査日時やイベント日時では注意が必要です。
命名を決めるときのチェックポイント
日時に関する変数名を決めるときは、次の順番で考えると整理しやすくなります。
- 特定の時点か、日付だけか、時刻だけか、時間量か
- 時点:At
- 日付:Date
- 時刻:Time
- 時間量:Duration、Period、Timeoutなど
- 何に関する日時なのか
- 作成:createdAt
- 支払い完了:paymentCompletedAt
- 配送予定日:deliveryDate
- 予定か実績か
- 開始予定:startsAt
- 実際の開始:startedAt
- タイムゾーンやオフセットが必要か
- 世界共通の時点:Instant
- 地域ルールが必要:ZonedDateTime
- 日付だけ:LocalDate
- 数値なら単位が明確か
- ミリ秒:timeoutMillis
- 秒:elapsedSeconds
- 期間の境界条件が決まっているか
- 開始・終了を範囲に含むか、仕様に明記する
- プロジェクト内で表現が統一されているか
- updatedAtとmodifiedAtを混在させない
- endAtとendsAtを理由なく混在させない
よく使われる変数名の例
| 表したい内容 | 変数名の例 |
|---|---|
| 作成日時 | createdAt |
| 最終更新日時 | updatedAt |
| 論理削除日時 | deletedAt |
| 最終ログイン日時 | lastLoginAt |
| 実際の開始日時 | startedAt |
| 実際の完了日時 | completedAt |
| 開始予定日時 | startsAt |
| 終了予定日時 | endsAt |
| 有効期限 | expiresAt |
| 実際の期限切れ処理日時 | expiredAt |
| イベント発生日時 | occurredAt |
| システム記録日時 | recordedAt |
| 生年月日 | birthDate |
| 配送予定日 | deliveryDate |
| 開店時刻 | openingTime |
| 処理時間 | processingDuration |
| タイムアウト時間 | requestTimeout |
| 再試行間隔 | retryInterval |
| タイムゾーン | zoneId |
最後に
さて今回は、Javaにおける時刻関連の変数名に関する慣習についてまとめました。
Javaでよく見かける「createdAt」や「updatedAt」の「At」は、特定の出来事が発生した「時点」を表すための実務上の命名慣習です。Javaの言語仕様で強制されるルールではありませんが、多くのシステムで利用されているため、意味を知っておくとコードやデータベースの構造を理解しやすくなりますし、開発者間で不要な認識齟齬が無くなります。
最も大切なのは、変数名を見た開発者が「何を表す値なのか」を迷わず判断できることです。日時の種類、業務上の意味、予定と実績、単位、タイムゾーンを整理し、誰が読んでも誤解しにくい名前を付けましょう。
以上!
前回まとめたJava関連の記事も読んでもらえると嬉しいです!
Java以外の勉強記事も是非!




コメント