全国オンライン対応受付 平日 9:00-18:00
お問い合わせ

開発記録 / junka制作記 / Vol.11 junka制作記 Vol.1

記事 03

Google SheetsのDate型に気づかず2日詰まった話

「Sat Dec 30 1899 10:30:00 GMT+0900」

2026-06-07 公開

「Sat Dec 30 1899 10:30:00 GMT+0900」

管理画面に表示されたこの文字列を見て、一瞬思考が止まった。1899年。スプレッドシートに入力したのは今日の10時30分のはずだ。なぜ125年前の日付が表示されているのか。


デバッグの迷子

最初にフロントエンドを疑った。JavaScriptのDateオブジェクトの扱いがまずいのだと思い、表示処理を書き直した。変わらなかった。

次にAPIの形式を疑った。GASからのレスポンスのJSON構造が違うのかと思い、受け取り部分を書き直した。変わらなかった。

1日目が終わった。

2日目の午前中、GASのコンソールにconsole.log()でデータを出力して確認した。GASがスプレッドシートから取得した時刻データが、すでに「Sat Dec 30 1899 10:30:00」という文字列になっていた。原因はGASの中にあった。


問題はここにあった

GoogleスプレッドシートのセルをGASでgetValues()すると、セルの書式に応じて型が変わる。数字は数値として、テキストは文字列として返ってくる。そして日付・時刻として書式設定されたセルは、JavaScriptのDateオブジェクトとして返ってくる。

これ自体は正しい挙動だ。問題は「時刻専用のセル」だった。

スプレッドシートで「10:30」と入力すると、スプレッドシートの内部では「1899年12月30日 10:30:00」という日付として保存される。GoogleスプレッドシートはExcelの時刻の扱いを踏襲しており、時刻だけのデータには「時刻シリアル値の基準日」として1899年12月30日を使っている。GASがこれをDateオブジェクトとして返すと、1899年がついてくる。

日時が複数の列にわたっていて、列によってDate型だったり文字列だったりと混在していた。これが型の不一致を引き起こしていた。


解決策は2行

GASで値を読み出した後、instanceof Dateで型を確認する。

const d = (rows[i][2] instanceof Date) ? rows[i][2] : new Date(rows[i][2]);

Dateオブジェクトであればそのまま使う。そうでなければnew Date()でDateオブジェクトに変換してから扱う。

タイムゾーンの指定も忘れてはいけない。GASのデフォルトタイムゾーンはプロジェクト設定に依存する。明示的にAsia/Tokyoを指定することで時刻がずれる問題を防ぐ。

Utilities.formatDate(d, 'Asia/Tokyo', 'HH:mm')

この2つをセットで書けば、1899年が出てくることはない。


フロント側にも手が必要だった

GASからJSON文字列で時刻を受け取るフロント側でも、同じ問題が潜んでいた。

new Date('Sat Dec 30 1899 10:30:00 GMT+0900')は正しいDateオブジェクトを返す。しかし日付部分「Dec 30 1899」が表示に紛れ込まないよう、時刻だけを取り出す処理が必要だ。フロントのfmtTime()関数でこれを吸収した。

function fmtTime(t) {
  if (!t) return '';
  const s = String(t);
  if (s.includes('T') || s.includes('Dec 30 1899') || s.includes('Sat ')) {
    const d = new Date(s);
    if (!isNaN(d)) return d.getHours().toString().padStart(2,'0') + ':' + d.getMinutes().toString().padStart(2,'0');
  }
  return s;
}

見苦しいコードだが、これが現実だ。125年前の日付が含まれているかどうかを確認するif文が必要になった。


2日を1分にする方法

あとから考えれば、最初にGASのコンソールでデータを確認していれば1分で気づいた。フロントとGASを同時に疑い始めると、原因の切り分けが曖昧になる。

GASを使ったシステムで日付・時刻が絡むとき、「スプレッドシートのセルをGASが何型として読んでいるか」を最初に確認する。それだけで、この種の問題は初日の午前中に終わる。

次にGASでスプレッドシートを扱うときは、日付・時刻列にinstanceof DateチェックとUtilities.formatDate()のAsia/Tokyo指定をセットで書くことが私のルールになった。


*次回は「iPad対応:3列グリッドとタブレットUIの設計」*

*シンプルシステム株式会社 代表 伊藤勝彦*