◉RORK LABEN
●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SONNET 4.5 — Claude API での提供終了は 11/30、残り23日。API 連携を足したアプリは移行先の確認を●SDK 58 — React Native 0.88 に更新されました。Android のリリース版で R8 が既定オンになり、iOS は SceneDelegate を生成します●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SONNET 4.5 — Claude API での提供終了は 11/30、残り23日。API 連携を足したアプリは移行先の確認を●SDK 58 — React Native 0.88 に更新されました。Android のリリース版で R8 が既定オンになり、iOS は SceneDelegate を生成します●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…
記事一覧/Rork入門
◈ Rork入門/2026-11-07初級

日記アプリの連続記録が、朝9時まで昨日のままになる。日付キーを UTC で作っていた

Rork で作った日記・習慣アプリで、午前0時から9時までの記録が前日扱いになり、連続日数が途切れる不具合の原因と直し方です。Node 22 で時刻を変えて動かした結果と、AI にそのまま渡せる指示文を載せました。

Rork613初心者25日付3連続記録トラブルシューティング104タイムゾーン3

朝7時に日記を書いたのに、アプリの画面には「昨日の記録」と出てしまい、連続日数のカウントが 12 から 1 に戻ってしまう——日記や習慣の記録アプリを AI に作らせた方から、こうした相談をいただくことがあります。

普段は動いているのに、ときどきだけ間違えるのです。この種の不具合は、画面を何度見直しても見つかりません。私自身、最初は画面側の表示を疑って、遠回りをしました。原因はたいてい、画面ではなく「日付をどう文字にしているか」の一行にあります。

まず、起きている現象を確かめます

日本のスマートフォンで起きるのは、午前0時から午前9時までの記録です。この時間帯だけ、アプリが「昨日」と判断してしまいます。9時を過ぎると何事もなかったように直るため、夜に確かめると再現しません。

原因の一行は、AI が書きがちな次の形です。

// 日付キー("2026-11-07" のような文字)を作る関数。よく生成される形
const dateKey = (d) => d.toISOString().slice(0, 10);

toISOString() は、端末の時刻ではなく世界標準時(UTC)に直した文字を返します。日本は UTC より 9 時間進んでいるので、日本時間の午前 8 時 59 分は、UTC ではまだ前の日の 23 時 59 分です。

Node 22 で、同じ瞬間を3通りに直してみました

端末の時刻設定を日本時間にして、下のスクリプトを動かしました。

// dk.mjs — 同じ瞬間を日付キーに直す 3 つの書き方
const pad = (n) => String(n).padStart(2, "0");
const keyUtc = (d) => d.toISOString().slice(0, 10);
const keyLocal = (d) => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
const keyIntl = (d, tz) => new Intl.DateTimeFormat("sv-SE", { timeZone: tz }).format(d);
 
const samples = ["2026-11-07T00:20:00+09:00", "2026-11-07T08:59:00+09:00",
                 "2026-11-07T09:00:00+09:00", "2026-11-07T23:50:00+09:00"];
for (const s of samples) {
  const d = new Date(s);
  console.log(s.slice(11, 16), "utc:", keyUtc(d), "local:", keyLocal(d), "intl:", keyIntl(d, "Asia/Tokyo"));
}

TZ=Asia/Tokyo node dk.mjs の出力は次のとおりでした。

00:20 utc: 2026-11-06 local: 2026-11-07 intl: 2026-11-07
08:59 utc: 2026-11-06 local: 2026-11-07 intl: 2026-11-07
09:00 utc: 2026-11-07 local: 2026-11-07 intl: 2026-11-07
23:50 utc: 2026-11-07 local: 2026-11-07 intl: 2026-11-07

午前 0 時 20 分と 8 時 59 分で、utc の列だけが 11 月 6 日になっています。9 時ちょうどで 11 月 7 日に切り替わる、という挙動が、先ほどの相談とそのまま重なります。

連続日数が途切れるのは、「昨日」の求め方も同じ形だからです

日付キーだけ直しても、連続日数がまだずれることがあります。「昨日のキー」を作る行が、次のようになっている場合です。

// 昨日のキー。UTC のキーから 24 時間を引いている
const bad = (d) => keyUtc(new Date(d.getTime() - 86400000));
// 端末の暦で一日戻す書き方
const yesterdayKey = (d) => { const y = new Date(d); y.setDate(y.getDate() - 1); return keyLocal(y); };

11 月 7 日の午前 0 時 20 分で試すと、yesterdayKey は 2026-11-06 を返しました。bad は 2026-11-05 を返しています。UTC のキーがすでに一日ずれているところへ、さらに 24 時間を引くので、二日分戻ってしまうのです。「今日の記録はあるのに、昨日が空」と判断され、連続日数が 1 に戻ります。

時刻を 24 時間で引く書き方は、夏時間のある地域でも一日がずれることがあります。setDate のように暦の上で一日戻す書き方なら、その心配は減ります。

直す方針は、日付キーの作り方を一か所に決めることです

手を入れる場所は多くありません。

  • 日付キーを作る関数を、アプリの中で一つだけにします。
  • その関数は、端末の暦(getFullYear などの組み合わせ)か、Intl.DateTimeFormat に時間帯を明示して作ります。
  • toISOString().slice(0, 10) は、日付キーには使いません。サーバーへ時刻そのものを送るときの形式として使うものです。

端末の暦と Intl のどちらを選ぶかは、「利用者が海外に出たら、日付の切り替わりはどこの時刻を基準にしたいか」で決めます。旅行先でも自分の生活の暦で数えたいなら端末の暦、日本時間で固定したいなら Asia/Tokyo を明示します。

日付の文字は、一か所の関数で、時間帯を決めてから作ります。 この線引きを、私は記録系アプリの最初の指示に入れるようにしています。

AI にそのまま渡せる指示文です

すでに作ったアプリを直すときは、次のように頼むと、探す範囲が絞れます。

日付キー(YYYY-MM-DD の文字)を作っている箇所をすべて探して、
共通の関数 toDateKey に一本化してください。
toDateKey は端末の暦(ローカルの年月日)で作り、toISOString().slice(0, 10) は使わないでください。
「昨日」「今日」の判定も、この関数と setDate(getDate() - 1) だけで行ってください。
直したあと、午前0時20分・午前8時59分・午前9時ちょうど・午後11時50分の4つの時刻で
連続日数が途切れないことを、テストコードで確かめてください。

最後の一文は省かないでください。画面を目で見るだけでは、午前 9 時までの挙動を確かめにくいと、いま思えば当たり前のことに、私は後から気づきました。

確かめたこと、確かめていないこと

ここまでの出力は、Node 22.23 で、時間帯を日本時間と世界標準時に切り替えて動かした結果です。世界標準時のまま動かすと、local の列も utc と同じ 11 月 6 日になりました。つまり端末の暦を使う書き方は、端末の設定に素直に従います。

一方で、実機の iPhone や Android で、Rork が出した画面と組み合わせて動かした確認は、この記事ではしていません。アプリの中で日付を扱う場所が複数ある場合は、上の指示文で一本化したあとに、ご自身の端末で朝の時間帯に一度だけ試していただければと思います。

同じ「記録の境目」の話は、家計簿アプリの最初の指示に足す三行でも月の境目として触れています。指示を小さく足していく進め方は機能を一つずつ足すプロンプトの書き方にまとめました。

個人開発で日替わりの表示や記録を扱っていると、日付の切り替わりは避けて通れない箇所なのだと思います。まずは手元のアプリで toISOString を検索して、日付キーに使っている行がないかを探すところから始めていただければと思います。

シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

◈ Rork 入門2026-10-29
家計簿アプリの最初の指示で、あとから効く3つの一行。金額は整数の円、月はローカル日付、入力は先に整える
家計簿のような記録アプリを AI に作らせる最初の指示に、金額の持ち方・月の境目・入力欄の整え方を一行ずつ足すだけで、月末の集計ずれを防げます。Node 22 で動かして確かめた挙動と、そのまま使える関数を載せています。
◈ Rork 入門2026-03-21
Rork でアプリがビルドできないとき、最初に切り分ける 8 つの症状
Rork でアプリがビルドできない、白い画面のまま進まない、ホットリロードが効かない。そんな症状を「どの層の問題か」から切り分ける FAQ です。依存関係の競合、Expo モジュール未解決、シミュレーター、生成フリーズ、Fix Now の使いどころまで 8 問で整理します。
◈ Rork 入門2026-10-29
一覧が空なのにエラーが出ないとき、直してと頼む前に Rork の Logs パネルを開きます
Rork のプレビューで一覧が空なのに赤いエラーが出ないとき、同じ修正依頼を重ねる前に Logs パネルへ値を出させて原因を三つに分ける手順を、依頼文の型とあわせてお伝えします。