海外予定の時刻ずれを登録前に発見|GASでタイムゾーン入力をdry-run確認
ツールおじ|GoogleアカウントをAIエージェント化
海外との打ち合わせを予定表へ取り込む時、「10:00」が日本時間なのか現地時間なのか分からないまま登録すると、予定そのものは作れても開始時刻がずれることがあります。
この記事では、日時に時差情報が付いているか、変換先のタイムゾーン名が有効かを先に検査し、変換後の時刻だけをログで確認する無料GASを紹介します。Googleカレンダーへの予定作成・更新は行いません。
準備するシート
スプレッドシートに `TimezonePlan` シートを作り、1行目へ次の3列を用意します。
- A列 `実行`: 確認する行だけ `TRUE`
- B列 `開始日時ISO`: `2026-09-15T10:00:00+09:00` のように時差を含む日時
- C列 `変換先タイムゾーン`: `America/New_York` や `Asia/Tokyo`
日時の末尾が `Z` または `+09:00` のようになっていれば、どの時点を指すかを固定できます。`2026/09/15 10:00` のように時差が分からない入力は、このコードでは止めます。
コピーして使える最小コード
const TIMEZONE_AUDIT_CONFIG = Object.freeze({
DRY_RUN: true,
SHEET_NAME: 'TimezonePlan',
MAX_ROWS: 100,
OUTPUT_FORMAT: 'yyyy-MM-dd HH:mm z'
});
function auditCalendarTimezoneInputFree() {
validateTimezoneAuditConfig_(TIMEZONE_AUDIT_CONFIG);
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName(TIMEZONE_AUDIT_CONFIG.SHEET_NAME);
if (!sheet) {
throw new Error('TimezonePlanシートが見つかりません。');
}
const lastRow = sheet.getLastRow();
if (lastRow < 2) {
throw new Error('確認するデータ行がありません。');
}
const rowCount = Math.min(lastRow - 1, TIMEZONE_AUDIT_CONFIG.MAX_ROWS);
const values = sheet.getRange(2, 1, rowCount, 3).getValues();
const results = [];
values.forEach((row, index) => {
const rowNumber = index + 2;
const enabled = row[0] === true;
const startIso = String(row[1] || '').trim();
const targetTimeZone = String(row[2] || '').trim();
if (!enabled) {
results.push({ row: rowNumber, status: 'SKIP', reason: '実行がTRUEではありません' });
return;
}
const errors = [];
if (!hasExplicitOffset_(startIso)) {
errors.push('開始日時ISOにZまたは±HH:MMの時差情報が必要です');
}
const instant = new Date(startIso);
if (Number.isNaN(instant.getTime())) {
errors.push('開始日時ISOを日時として解釈できません');
}
if (!isValidTimeZone_(targetTimeZone)) {
errors.push('変換先タイムゾーン名が無効です');
}
if (errors.length > 0) {
results.push({ row: rowNumber, status: 'HOLD', errors });
return;
}
results.push({
row: rowNumber,
status: 'OK',
converted: Utilities.formatDate(
instant,
targetTimeZone,
TIMEZONE_AUDIT_CONFIG.OUTPUT_FORMAT
),
targetTimeZone,
action: 'NONE'
});
});
const summary = {
dryRun: TIMEZONE_AUDIT_CONFIG.DRY_RUN,
checkedRows: rowCount,
ok: results.filter((item) => item.status === 'OK').length,
hold: results.filter((item) => item.status === 'HOLD').length,
skipped: results.filter((item) => item.status === 'SKIP').length,
action: 'NONE',
results
};
console.log(JSON.stringify(summary));
return summary;
}
function hasExplicitOffset_(value) {
return /T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,3})?)?(?:Z|[+-]\d{2}:\d{2})$/.test(value);
}
function isValidTimeZone_(timeZone) {
if (!timeZone || !/^[A-Za-z_+-]+\/[A-Za-z0-9_+\/-]+$/.test(timeZone)) {
return false;
}
try {
Utilities.formatDate(new Date(0), timeZone, 'yyyy-MM-dd HH:mm');
return true;
} catch (error) {
return false;
}
}
function validateTimezoneAuditConfig_(config) {
if (config.DRY_RUN !== true) {
throw new Error('安全のためDRY_RUNはtrue固定です。');
}
if (!Number.isInteger(config.MAX_ROWS) || config.MAX_ROWS < 1 || config.MAX_ROWS > 100) {
throw new Error('MAX_ROWSは1〜100の整数にしてください。');
}
}実行前の準備
1. 元データではなく、少量の確認用スプレッドシートを作ります。
2. `TimezonePlan` シートへサンプルを2〜3行入力します。
3. Apps Scriptエディタへコードを貼り付けて保存します。
4. `auditCalendarTimezoneInputFree` を手動実行します。
5. 実行ログで `dryRun: true` と `action: NONE` を確認します。
最初は、同じ時点を `Asia/Tokyo` と `America/New_York` へ変換し、期待する日付と時刻になるかを見比べてください。
ログの見方
- `OK`: 時差付き日時とタイムゾーン名を検証できた行
- `HOLD`: 日時の時差情報がない、日時として読めない、またはタイムゾーン名が無効な行
- `SKIP`: A列の実行が `TRUE` ではない行
- `converted`: 指定したタイムゾーンで表示した確認用時刻
- `action: NONE`: 予定やシートを変更していないことを示す固定値
タイトル、参加者、説明文などは読み込まず、ログにも出しません。実際の予定情報を扱う前に、日時だけのサンプルで確認するためです。
停止条件
- `HOLD` が1件でもある場合は、カレンダー登録処理へ進まない
- 変換後の日付が前日または翌日になる場合は、参加者へ基準時刻を確認する
- 夏時間の切り替わり付近は、対象日そのものを使って再確認する
- 変換先が `JST` や `EST` のような略称しか分からない場合は、IANA形式の正式名を確認する
- 100行を超える場合は上限を増やさず、範囲を分けて確認する
制限と安全上の注意
- このコードはGoogleカレンダーを読み書きしません。予定登録前の入力監査だけを行います
- タイムゾーンの制度や夏時間は地域によって変更される場合があります。重要な予定は相手が提示した日時・地域名とも照合してください
- Apps Scriptプロジェクト側のタイムゾーン設定だけで、時差情報のない文字列を自動補完しないでください
- 自動実行トリガーは設定せず、まず手動実行で確認してください
- `setValue`、`createEvent`、`deleteEvent` などの変更処理は無料例に含めていません
公開前チェックリスト
- [ ] 日時に `Z` または `±HH:MM` が付いている
- [ ] 変換先を `Asia/Tokyo` などのIANA形式で入力した
- [ ] `DRY_RUN` が `true` のまま
- [ ] `action` が `NONE`
- [ ] `HOLD` が0件
- [ ] 予定名・参加者・説明文などの個人情報をログへ出していない
- [ ] 変換後の日時を参加者の案内と照合した
まとめ
タイムゾーンのずれは、予定を登録した後より、時差情報と変換先を入力段階で検査する方が安全です。まずは日時だけのdry-runで `HOLD` をなくし、変換後の日時を目視してから、実際の登録工程を別に設計してください。
関連する有料Tips商品を見る

GasおじのTips商品一覧を見る

※このコードは学習・検証用です。実データへ適用する前に少量で確認してください。Google公式・Google公認の商品ではありません。
