GAS(Google Apps Script)の日付は、Utilities.formatDate(日付, "Asia/Tokyo", "yyyy/MM/dd HH:mm:ss") のように第2引数のタイムゾーンを明示して整形すれば、プロジェクトの設定に左右されません。 書式は Java の SimpleDateFormat の規則に従うため、大文字と小文字で意味が変わります。年は小文字の yyyy、月は大文字の MM、日は小文字の dd、24時間制の時は大文字の HH です。

この記事では、書式文字の早見表と用途別パターン30本、取り違えやすい文字の対比、ずれる原因の3層での切り分け、日付の計算・比較・曜日の日本語化のコード、表示方法の選び方をまとめました。

確認環境(確認日 2026-10-05):書式の出力例は、Utilities.formatDate が従う SimpleDateFormat を OpenJDK 21(ロケールは英語)で実行した結果です。Date の計算・比較・解釈は Node.js 22.22.2(GAS の V8 ランタイムと同じ V8 エンジン)で、環境変数 TZ を切り替えて実行しました。GAS のメソッドの引数・戻り値と設定項目は、Google Apps Script 公式リファレンス(末尾の参考)の記載です。

この記事の結論

function formatNow() {
  const now = new Date();
  const text = Utilities.formatDate(now, "Asia/Tokyo", "yyyy/MM/dd HH:mm:ss");
  console.log(text); // 例: 2026/10/05 15:07:03
}
  • 第2引数に "Asia/Tokyo" を書く。スクリプトやシートのタイムゾーン設定が違っていても、日本時間で整形されます。
  • 書式は yyyy・MM・dd・HH・mm・ss。YYYY(週基準の年)・mm(分)・DD(年内の通算日)・hh(12時間制)は別の意味です。
  • ずれたときは3層で切り分ける:スクリプトのタイムゾーン、スプレッドシートのタイムゾーン、new Date(文字列) の解釈。
  • 日付の比較は getTime() の数値で行う。Date 同士の === は、同じ時刻でも false になります。

formatDateの書式文字の早見表

基準の日時は 2026年10月5日(月)15時7分3秒045ミリ秒、タイムゾーンは Asia/Tokyo です。

書式文字 意味 出力 補足
yyyy 年(4桁) 2026 暦の年。通常はこちらを使う
yy 年(下2桁) 26
MM 月(2桁) 10 1月は 01
M 月(桁そろえなし) 10 1月は 1
MMM 月(英語の短縮) Oct
MMMM 月(英語) October
dd 日(2桁) 05
d 日(桁そろえなし) 5
HH 時(24時間制 0〜23、2桁) 15
H 時(24時間制、桁そろえなし) 15 9時は 9
hh 時(12時間制 1〜12、2桁) 03 a と組み合わせる
h 時(12時間制、桁そろえなし) 3
mm 分(2桁) 07 月ではない
ss 秒(2桁) 03
SSS ミリ秒(3桁) 045
E 曜日(英語の短縮) Mon 日本語にする方法は後述
EEEE 曜日(英語) Monday
u 曜日の番号(1=月曜 … 7=日曜) 1
a 午前・午後の印 PM
Z タイムゾーン(RFC 822) +0900
XXX タイムゾーン(ISO 8601) +09:00 X だけなら +09
z タイムゾーン(略称) JST zzzz は Japan Standard Time
D 年内の通算日 278 日(dd)ではない
w 年内の週番号 41
G 紀元 AD
'文字' 文字をそのまま出す 英字を出すときは一重引用符で囲む

英字はすべて書式文字として扱われるため、T などをそのまま書くと「Illegal pattern character 'T'」という例外になります。'T' のように一重引用符で囲みます。漢字(年・月・日・時・分・秒)は囲まなくてもそのまま出ます。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「GAS日付フォーマット早見表|formatDateの書式とずれる原因」

用途別パターン30本

第3引数にそのまま貼れる書式です。出力は基準の日時(2026年10月5日(月)15時7分3秒045、Asia/Tokyo)のものです。

No. 用途 書式 出力
1 標準の日付 yyyy/MM/dd 2026/10/05
2 ISO形式の日付 yyyy-MM-dd 2026-10-05
3 ファイル名用の日付 yyyyMMdd 20261005
4 日本語の日付 yyyy年M月d日 2026年10月5日
5 日本語の日付(桁そろえ) yyyy年MM月dd日 2026年10月05日
6 月日だけ M/d 10/5
7 月日だけ(桁そろえ) MM/dd 10/05
8 年を2桁に yy/MM/dd 26/10/05
9 年月 yyyy/MM 2026/10
10 年月(日本語) yyyy年M月 2026年10月
11 ドット区切り yyyy.MM.dd 2026.10.05
12 時分 HH:mm 15:07
13 時分秒 HH:mm:ss 15:07:03
14 時分(日本語) H時m分 15時7分
15 12時間制 h:mm a 3:07 PM
16 区切りなしの時分 HHmm 1507
17 日付と時分 yyyy/MM/dd HH:mm 2026/10/05 15:07
18 日付と時分秒 yyyy/MM/dd HH:mm:ss 2026/10/05 15:07:03
19 データベース向け yyyy-MM-dd HH:mm:ss 2026-10-05 15:07:03
20 ミリ秒つき yyyy-MM-dd HH:mm:ss.SSS 2026-10-05 15:07:03.045
21 ISO 8601(時差つき) yyyy-MM-dd'T'HH:mm:ssXXX 2026-10-05T15:07:03+09:00
22 ISO 8601(ミリ秒・時差つき) yyyy-MM-dd'T'HH:mm:ss.SSSXXX 2026-10-05T15:07:03.045+09:00
23 ファイル名用の日時 yyyyMMdd_HHmmss 20261005_150703
24 一意な番号用 yyyyMMddHHmmssSSS 20261005150703045
25 日本語の日時 yyyy年M月d日 H時m分s秒 2026年10月5日 15時7分3秒
26 曜日つき(英語) yyyy/MM/dd (E) 2026/10/05 (Mon)
27 メールのヘッダー形式 EEE, d MMM yyyy HH:mm:ss Z Mon, 5 Oct 2026 15:07:03 +0900
28 英語の日付 MMM d, yyyy Oct 5, 2026
29 タイムゾーン名つき yyyy/MM/dd HH:mm:ss z 2026/10/05 15:07:03 JST
30 週番号 yyyy-'W'ww 2026-W41

表計算ソフトに貼れるタブ区切り版です。

用途  書式  出力
標準の日付   yyyy/MM/dd  2026/10/05
ISO形式の日付    yyyy-MM-dd  2026-10-05
ファイル名用の日付   yyyyMMdd    20261005
日本語の日付  yyyy年M月d日   2026年10月5日
時分  HH:mm   15:07
日付と時分秒  yyyy/MM/dd HH:mm:ss 2026/10/05 15:07:03
ISO 8601(時差つき)  yyyy-MM-dd'T'HH:mm:ssXXX    2026-10-05T15:07:03+09:00
ファイル名用の日時   yyyyMMdd_HHmmss 20261005_150703
日本語の日時  yyyy年M月d日 H時m分s秒    2026年10月5日 15時7分3秒
メールのヘッダー形式  EEE, d MMM yyyy HH:mm:ss Z  Mon, 5 Oct 2026 15:07:03 +0900

No.21 の XXX は、第2引数のタイムゾーンに応じた時差を付けます。'Z' と引用符で囲むと、時刻は日本時間のまま文字の Z が付き(2026-10-05T15:07:03Z)、9時間ずれた別の時刻を表す文字列になります。UTC の Z 表記が必要なときは、第2引数を "UTC" にしたうえで 'Z' を付けます。

取り違えやすい書式文字の対比表

大文字と小文字を取り違えても例外にはならず、それらしい別の値が出るため、気づきにくい部分です。

取り違え 書いた書式 出力 正しい書式 出力
年を大文字にした YYYY/MM/dd(2026年12月27日) 2027/12/27 yyyy/MM/dd 2026/12/27
月を小文字にした yyyy/mm/dd(10月5日 15時07分) 2026/07/05 yyyy/MM/dd 2026/10/05
日を大文字にした yyyy/MM/DD(10月5日) 2026/10/278 yyyy/MM/dd 2026/10/05
時を小文字にした hh:mm(15時07分) 03:07 HH:mm 15:07
時を小文字にした(0時30分) hh:mm 12:30 HH:mm 00:30

YYYYは週基準の年で、年末年始に1年ずれる

Y は「その日が属する週の年」です。年末の数日が翌年の第1週に入ると、12月なのに翌年の数字が出ます。実行結果(ロケールは英語。週の始まりは日曜)は次のとおりです。

日付 曜日 yyyy/MM/dd YYYY/MM/dd
2024-12-28 Sat 2024/12/28 2024/12/28
2024-12-29 Sun 2024/12/29 2025/12/29
2024-12-31 Tue 2024/12/31 2025/12/31
2025-01-01 Wed 2025/01/01 2025/01/01
2025-12-27 Sat 2025/12/27 2025/12/27
2025-12-28 Sun 2025/12/28 2026/12/28
2026-12-26 Sat 2026/12/26 2026/12/26
2026-12-27 Sun 2026/12/27 2027/12/27
2026-12-31 Thu 2026/12/31 2027/12/31
2027-01-01 Fri 2027/01/01 2027/01/01

1年のうち年末の数日だけ結果が変わるので、ふだんの動作確認では見つかりません。どの日から切り替わるかは週の数え方(ロケール)で変わるため、年には小文字の yyyy を使う、と決めておくのが確実です。

mmは分、DDは年内通算日、hhは12時間制

  • mm は分です。上の表では 15時07分の「07」が月の位置に出ています。分が 00 のときは月が 00 になります。
  • DD は1月1日からの通算日です。1月中は日と同じ数字になるため、2月以降に初めて違いが表に出ます。
  • hh は 1〜12 で表す時です。午前中は HH と同じ数字になり、午後と0時台で違いが出ます。12時間制で使うときは h:mm a のように a を添えます。

シートの表示形式は別の規則

スプレッドシートの表示形式(setNumberFormat に渡す書式)は、formatDate とは別の規則です。Google Sheets API の「Date and number formats」では、m・mm は直前が時、または直後が秒なら分、それ以外は月と説明されています。月を明示する M・MM も用意されています。

目的 Utilities.formatDate の書式 シートの表示形式
年-月-日 yyyy-MM-dd yyyy-mm-dd(公式の例)または yyyy-MM-dd
曜日 E・EEEE(英語) ddd・dddd
午前・午後 a am/pm または a/p
24時間と12時間の切り替え HH と hh を書き分ける am/pm の有無で切り替わる

日付がずれる原因を3層で切り分ける

「9時間ずれる」「1日前になる」は、次の3つのどこかで起きています。上から順に確かめます。

層 設定・コードの場所 確かめるコード 公式の説明
1. スクリプトのタイムゾーン appsscript.json の timeZone Session.getScriptTimeZone() マニフェストの timeZone は、スクリプトのタイムゾーンを "America/Denver" のような ZoneId で指定する
2. スプレッドシートのタイムゾーン スプレッドシート側の設定 SpreadsheetApp.getActive().getSpreadsheetTimeZone() スプレッドシートのタイムゾーンを返す(戻り値は String)
3. new Date(文字列) の解釈 コード new Date("2026-10-05").toISOString() 文字列の形で UTC かローカルかが変わる(下の実行結果)

3つを一度に表示する確認用の関数です。

function checkTimeZones() {
  const now = new Date();
  console.log("スクリプト:", Session.getScriptTimeZone());
  console.log("シート    :", SpreadsheetApp.getActive().getSpreadsheetTimeZone());
  console.log("Date      :", now.toString());
  console.log("日本時間  :", Utilities.formatDate(now, "Asia/Tokyo", "yyyy/MM/dd HH:mm:ss Z"));
}

層1:スクリプトのタイムゾーン

appsscript.json の timeZone が日本以外になっていると、Utilities.formatDate(d, Session.getScriptTimeZone(), ...) と書いた箇所がその地域の時刻で出ます。

{
  "timeZone": "Asia/Tokyo",
  "runtimeVersion": "V8"
}

同じ瞬間(日本時間 2026/10/05 15:07:03)を、第2引数だけ変えて整形した結果です。

第2引数 出力(yyyy/MM/dd HH:mm:ss Z)
"Asia/Tokyo" 2026/10/05 15:07:03 +0900
"JST" 2026/10/05 15:07:03 +0900
"GMT+9" 2026/10/05 15:07:03 +0900
"UTC" 2026/10/05 06:07:03 +0000
"America/New_York" 2026/10/05 02:07:03 -0400
"Asia/Tokyoo"(つづり違い) 2026/10/05 06:07:03 +0000

つづりを間違えたタイムゾーン名は、例外にならず +0000 の時刻になりました(OpenJDK 21 での結果)。9時間ずれているときは、まず第2引数の文字列を確かめます。

層2:スプレッドシートのタイムゾーン

スプレッドシートには、スクリプトとは別にタイムゾーンの設定があります。セルの日付を getValue で取り出して整形するときは、シート側のタイムゾーンを第2引数に渡すと、セルに見えているとおりの日付になります。

function formatCellDate() {
  const ss = SpreadsheetApp.getActive();
  const sheet = ss.getSheetByName("予定");
  if (sheet === null) throw new Error("シート「予定」が見つかりません");

  const value = sheet.getRange("A2").getValue();          // 日付のセルは Date で返る
  if (!(value instanceof Date)) throw new Error("A2 は日付ではありません: " + value);

  const tz = ss.getSpreadsheetTimeZone();
  console.log(Utilities.formatDate(value, tz, "yyyy/MM/dd"));
  console.log(sheet.getRange("A2").getDisplayValue());     // 画面に見えている文字列
}
シートから取りたいもの メソッド 戻り値
計算や比較に使う日付 getValue()・getValues() Date(日付のセルの場合)
画面に見えているとおりの文字 getDisplayValue()・getDisplayValues() String
セルの見た目を変える setNumberFormat("yyyy-mm-dd") Range

2つの設定が違っていないかは、先ほどの checkTimeZones で並べて表示すると分かります。違っていた場合は、ss.setSpreadsheetTimeZone("Asia/Tokyo") でシート側をそろえられます。

層3:new Date(文字列)の解釈

文字列から Date を作るとき、ハイフン区切りの日付だけの形は UTC の0時、それ以外はローカル時刻の0時として解釈されます。実行環境のタイムゾーンを切り替えて実行した結果です(右の値は UTC での表示)。

TZ= Asia/Tokyo
new Date("2026-10-05")             => 2026-10-05T00:00:00.000Z
new Date("2026-10-05T00:00:00")    => 2026-10-04T15:00:00.000Z
new Date("2026/10/05")             => 2026-10-04T15:00:00.000Z
new Date("2026-10-05T00:00:00+09:00") => 2026-10-04T15:00:00.000Z
new Date(2026, 9, 5)               => 2026-10-04T15:00:00.000Z
new Date("2026年10月5日")             => Invalid Date
getDate of "2026-10-05"            => 5

TZ= America/New_York
new Date("2026-10-05")             => 2026-10-05T00:00:00.000Z
new Date("2026-10-05T00:00:00")    => 2026-10-05T04:00:00.000Z
new Date("2026/10/05")             => 2026-10-05T04:00:00.000Z
new Date("2026-10-05T00:00:00+09:00") => 2026-10-04T15:00:00.000Z
new Date(2026, 9, 5)               => 2026-10-05T04:00:00.000Z
new Date("2026年10月5日")             => Invalid Date
getDate of "2026-10-05"            => 4
書き方 解釈 向いている場面
new Date("2026-10-05") UTC の0時(日本時間では9時) UTC で日付を扱うとき
new Date("2026/10/05") ローカル時刻の0時 実行環境のタイムゾーンが決まっているとき
new Date(2026, 9, 5) ローカル時刻の0時(月は0始まり) 年・月・日を数値で持っているとき
new Date("2026-10-05T00:00:00+09:00") 時差を明示。環境に左右されない APIやCSVから受け取った文字列
new Date("2026年10月5日") 無効な日付 数字を取り出してから数値で渡す

時差つきの文字列(+09:00)だけが、どのタイムゾーンでも同じ瞬間になりました。 外部から受け取った「2026-10-05」を日本の日付として扱うときは、new Date(text + "T00:00:00+09:00") と時差を足してから渡します。

日付の計算と比較のコード

GAS の日付計算は JavaScript の Date で行います。次のコードは Node.js 22(TZ=Asia/Tokyo)で実行したもので、表示用の fmt 関数だけ Node.js 向けです。GAS では fmt の中身を Utilities.formatDate(d, "Asia/Tokyo", "yyyy-MM-dd HH:mm:ss") に置き換えます。

const fmt = (d) => d.toLocaleString("sv-SE", { timeZone: "Asia/Tokyo" });
const base = new Date(2026, 9, 5, 15, 7, 3); // 2026/10/05 15:07:03(月は0始まり)

// 1) 日・月・時間の加減算
const addDays = (d, n) => { const x = new Date(d); x.setDate(x.getDate() + n); return x; };
const addHours = (d, n) => new Date(d.getTime() + n * 60 * 60 * 1000);
const addMonths = (d, n) => {            // 月末を越えないように丸める
  const x = new Date(d); const day = x.getDate();
  x.setDate(1); x.setMonth(x.getMonth() + n);
  const last = new Date(x.getFullYear(), x.getMonth() + 1, 0).getDate();
  x.setDate(Math.min(day, last)); return x;
};
console.log("7日後      ", fmt(addDays(base, 7)));
console.log("30日前     ", fmt(addDays(base, -30)));
console.log("3時間後    ", fmt(addHours(base, 3)));
console.log("1か月後    ", fmt(addMonths(base, 1)));
const jan31 = new Date(2026, 0, 31);
const naive = new Date(jan31); naive.setMonth(naive.getMonth() + 1);
console.log("1/31 に setMonth(+1)", fmt(naive));
console.log("1/31 に addMonths(1)", fmt(addMonths(jan31, 1)));

// 2) 月初・月末
const firstDay = (d) => new Date(d.getFullYear(), d.getMonth(), 1);
const lastDay = (d) => new Date(d.getFullYear(), d.getMonth() + 1, 0);
console.log("月初       ", fmt(firstDay(base)));
console.log("月末       ", fmt(lastDay(base)));
console.log("2028年2月末", fmt(lastDay(new Date(2028, 1, 1))));

// 3) 差の日数(時刻を落としてから割る)
const startOfDay = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
const diffDays = (a, b) => Math.round((startOfDay(b) - startOfDay(a)) / 86400000);
console.log("10/5 から 12/31 まで", diffDays(base, new Date(2026, 11, 31)), "日");
console.log("10/5 23:59 から 10/6 00:01 まで", diffDays(new Date(2026, 9, 5, 23, 59), new Date(2026, 9, 6, 0, 1)), "日");

// 4) 比較
const a = new Date(2026, 9, 5, 9, 0), b = new Date(2026, 9, 5, 18, 0), c = new Date(2026, 9, 5, 9, 0);
console.log("a < b            ", a < b);
console.log("a === c          ", a === c);
console.log("a == c           ", a == c);
console.log("getTime で比較   ", a.getTime() === c.getTime());
const sameDay = (x, y) => startOfDay(x).getTime() === startOfDay(y).getTime();
console.log("同じ日か(a, b)   ", sameDay(a, b));
console.log("同じ日か(a, 翌日)", sameDay(a, addDays(a, 1)));

// 5) 曜日の日本語化
const WEEK = ["日", "月", "火", "水", "木", "金", "土"];
console.log("getDay()         ", base.getDay(), "→", WEEK[base.getDay()] + "曜日");
console.log(`${base.getMonth() + 1}月${base.getDate()}日(${WEEK[base.getDay()]})`);

// 6) 無効な日付の検出
const bad = new Date("2026年10月5日");
console.log("無効な日付       ", String(bad), isNaN(bad.getTime()));

実行結果:

7日後       2026-10-12 15:07:03
30日前      2026-09-05 15:07:03
3時間後     2026-10-05 18:07:03
1か月後     2026-11-05 15:07:03
1/31 に setMonth(+1) 2026-03-03 00:00:00
1/31 に addMonths(1) 2026-02-28 00:00:00
月初        2026-10-01 00:00:00
月末        2026-10-31 00:00:00
2028年2月末 2028-02-29 00:00:00
10/5 から 12/31 まで 87 日
10/5 23:59 から 10/6 00:01 まで 1 日
a < b             true
a === c           false
a == c            false
getTime で比較    true
同じ日か(a, b)    true
同じ日か(a, 翌日) false
getDay()          1 → 月曜日
10月5日(月)
無効な日付        Invalid Date true
やりたいこと 書き方 気をつける点
n日後 setDate(getDate() + n) 月や年をまたいでも自動で繰り上がる
nか月後 日を1にしてから月を足し、月末で丸める 1/31 に setMonth(+1) だけだと 3/3 になる
月末 new Date(年, 月 + 1, 0) 翌月の「0日」が当月の末日
日数の差 時刻を落としてから引き、86400000 で割る 23:59 と翌 00:01 の差は2分でも「1日」と数えられる
前後の比較 a < b 大小比較はそのまま使える
同じ時刻か a.getTime() === c.getTime() Date 同士の === と == は false
同じ日か 時刻を落とした getTime 同士を比べる 整形した文字列(yyyyMMdd)同士を比べる方法でもよい

曜日を日本語にする

formatDate の E は英語(Mon)で出るため、日本語の曜日は getDay() の番号で配列から引きます。GAS でそのまま使える形です。

function formatWithJapaneseWeekday(date) {
  const WEEK = ["日", "月", "火", "水", "木", "金", "土"];
  const tz = "Asia/Tokyo";
  const u = Number(Utilities.formatDate(date, tz, "u"));   // 1=月曜 … 7=日曜
  return Utilities.formatDate(date, tz, "yyyy/MM/dd") + "(" + WEEK[u % 7] + ")";
}
// 2026年10月5日 → "2026/10/05(月)"

getDay() は実行環境のタイムゾーンで曜日を決めます。上の関数は、曜日の番号も formatDate の u で日本時間として取り出しているので、スクリプトのタイムゾーン設定が違っていても日付と曜日が食い違いません(u は月曜が1、日曜が7。7 を 7 で割った余り 0 が配列の「日」に当たります)。

formatDateとほかの表示方法の選び方

方法 タイムゾーンの指定 書式の自由度 日本語の曜日・和暦 動く場所
Utilities.formatDate 第2引数で指定(必須) 書式文字で自由に組める 曜日は英語。配列で置き換える GAS のみ
toLocaleDateString("ja-JP", {...}) オプション timeZone で指定 部品の有無と桁を選ぶ 対応(weekday、和暦) JavaScript 全般
Intl.DateTimeFormat オプション timeZone で指定 dateStyle/timeStyle、部品の指定 対応 JavaScript 全般
シートの表示形式(setNumberFormat) シートのタイムゾーンに従う シート独自の書式 シートのロケールに従う セルの見た目だけを変える

toLocaleDateString と Intl.DateTimeFormat の出力例(Node.js 22 で実行。timeZone に "Asia/Tokyo" を指定):

const d = new Date("2026-10-05T15:07:03+09:00");
const o = { timeZone: "Asia/Tokyo" };
console.log(d.toLocaleDateString("ja-JP", o));
console.log(d.toLocaleDateString("ja-JP", { ...o, year: "numeric", month: "2-digit", day: "2-digit" }));
console.log(d.toLocaleDateString("ja-JP", { ...o, year: "numeric", month: "long", day: "numeric", weekday: "long" }));
console.log(d.toLocaleDateString("ja-JP", { ...o, weekday: "short" }));
console.log(d.toLocaleDateString("ja-JP-u-ca-japanese", { ...o, era: "long", year: "numeric", month: "long", day: "numeric" }));
console.log(new Intl.DateTimeFormat("ja-JP", { ...o, dateStyle: "full", timeStyle: "short" }).format(d));
2026/10/5
2026/10/05
2026年10月5日月曜日
月
令和8年10月5日
2026年10月5日月曜日 15:07

条件から選ぶ判断表

条件 選ぶもの
ログ・ファイル名・メール本文など、決まった形の文字列が欲しい Utilities.formatDate(第2引数を明示)
セルの値は日付のまま、見た目だけ変えたい シートの表示形式(setNumberFormat)
セルに見えているとおりの文字が欲しい getDisplayValue()
日本語の曜日や和暦を、部品の指定だけで出したい toLocaleDateString または Intl.DateTimeFormat(timeZone を指定)
並べ替えや比較に使う 整形せず Date のまま(getTime の数値)
外部のAPIへ渡す yyyy-MM-dd'T'HH:mm:ssXXX(時差つき)

セルに日付を書き込むときは、整形した文字列ではなく Date のまま setValue に渡し、見た目は表示形式で整えると、シート側で並べ替えや日付の計算がそのまま使えます。

確かめて分かったこと

  • YYYY で年がずれる日は毎年違いました。 2024年は12月29日から、2025年は12月28日から、2026年は12月27日から翌年の数字になります(ロケールが英語の場合)。
  • mm を月の位置に書くと、実行した時刻の「分」が月として出ます。 15時07分なら 07、12時00分なら 00 になります。
  • つづりを間違えたタイムゾーン名は、例外にならず UTC 相当の時刻になりました。 「9時間ずれる」原因の候補として、第2引数の文字列も確かめる価値があります。
  • 'Z' と引用符で囲むと、時刻は変換されずに Z の文字だけが付きます。 UTC を表したいなら第2引数も "UTC" にします。
  • new Date("2026-10-05") と new Date("2026/10/05") は、区切り文字が違うだけで9時間違う瞬間になりました(TZ=Asia/Tokyo)。前者は UTC、後者はローカル時刻として解釈されます。
  • シートの表示形式の mm は、前後の書式で月にも分にもなります。 大文字の MM はシートの表示形式でも月を表すので、月には MM と書いておくと formatDate と同じ読み方になります。

よくある質問

Q. Utilities.formatDateとは何ですか? A. Date を、指定したタイムゾーンと書式で文字列にする GAS のメソッドです。引数は (date, timeZone, format) の3つで、戻り値は String。書式は Java の SimpleDateFormat の規則に従います。

Q. GASで日付が9時間ずれるときは? A. 第2引数のタイムゾーンを "Asia/Tokyo" と明示します。"GMT" や "UTC" を渡している、タイムゾーン名のつづりが違う、appsscript.json の timeZone が日本以外、のいずれかで9時間の差が出ます。

Q. yyyyとYYYYの違いは何ですか? A. yyyy は暦の年、YYYY はその日が属する週の年です。年末の数日は YYYY だと翌年の数字になるため、日付の年には yyyy を使います。

Q. スプレッドシートの日付が1日ずれるときは? A. スクリプトとスプレッドシートのタイムゾーンを並べて確認し、セルの日付は ss.getSpreadsheetTimeZone() を第2引数にして整形します。文字列から作った日付なら、new Date に渡す文字列へ +09:00 を付けます。

Q. 曜日を日本語で表示するには? A. 曜日の番号で ["日","月","火","水","木","金","土"] から引きます。formatDate の E は英語で出るため、u(月曜が1)や getDay()(日曜が0)の番号を使います。

まとめ

  • Utilities.formatDate(日付, "Asia/Tokyo", "yyyy/MM/dd HH:mm:ss") と第2引数を明示すれば、設定に左右されない。
  • 書式は yyyy・MM・dd・HH・mm・ss。YYYY は週基準の年、mm は分、DD は年内通算日、hh は12時間制。
  • 英字をそのまま出すときは一重引用符で囲む('T')。UTC の Z 表記は、第2引数を "UTC" にして 'Z'。
  • ずれは3層で切り分ける:スクリプトのタイムゾーン、スプレッドシートのタイムゾーン、new Date(文字列) の解釈。
  • 文字列から日付を作るときは時差(+09:00)を付けると、どの環境でも同じ瞬間になる。
  • 比較は getTime() の数値で、月の加算は月末で丸める。
  • セルには Date のまま書き込み、見た目は表示形式で整える。シートの表示形式は formatDate とは別の規則。

参考・出典

  • Google Apps Script リファレンス「Class Utilities(formatDate)」 https://developers.google.com/apps-script/reference/utilities/utilities
  • Java SE 8 API「SimpleDateFormat」 https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html
  • Google Apps Script リファレンス「Class Session(getScriptTimeZone)」 https://developers.google.com/apps-script/reference/base/session
  • Google Apps Script リファレンス「Class Spreadsheet(getSpreadsheetTimeZone)」 https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet
  • Google Apps Script リファレンス「Class Range(getValue・getDisplayValue・setNumberFormat)」 https://developers.google.com/apps-script/reference/spreadsheet/range
  • Google Apps Script「Manifest structure(timeZone)」 https://developers.google.com/apps-script/manifest
  • Google Sheets API「Date and number formats」 https://developers.google.com/workspace/sheets/api/guides/formats

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「GAS日付フォーマット早見表|formatDateの書式とずれる原因」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?