• 作成日 : 2025年12月2日

スプレッドシートでタイムスタンプを記録するには?手動入力からGAS自動化まで完全ガイド

Googleスプレッドシート(Google Sheets)でタイムスタンプを適切に管理することで、データの追跡性と信頼性が大幅に向上します。本記事では、NOW関数やショートカットキーを使った手動入力方法から、Google Apps Script(GAS)による完全自動化、タイムゾーンやフォーマットの考慮事項まで、実務で即座に活用できる包括的なテクニックを詳しく解説します。

正確な時刻記録により、業務プロセスの可視化と効率的なデータ管理を実現できます。

スプレッドシートでタイムスタンプを手動で入力する基本的な方法は?

タイムスタンプの手動入力には、ショートカットキーや関数を使用する方法があり、用途に応じて最適な手法を選択できます。 静的な時刻記録が必要な場合はショートカットキー、動的な更新が必要な場合は関数を使用します。

手動でのタイムスタンプ入力は、最もシンプルで確実な方法です。特に、データ入力時点の正確な時刻を記録したい場合や、後から時刻が変更されないことを保証したい場合に適しています。ショートカットキーを活用することで、素早く正確な時刻入力が可能になります。

ショートカットキーによる即座の時刻入力

現在の日時を瞬時に入力するショートカットキー
  • 現在の日付:Ctrl + ;(セミコロン)[Mac: Command + ;]
  • 現在の時刻:Ctrl + Shift + :(コロン)[Mac: Command + Shift + :]
  • 日付と時刻の両方:上記を組み合わせて使用

これらのショートカットで入力された値は静的なテキストとして保存され、シートを再計算しても変更されません。この特性により、データの作成時刻や更新時刻を確実に記録できます。

組み合わせ入力の例
  1. セルを選択
  2. Ctrl + ; で日付を入力
  3. スペースキーを押す
  4. Ctrl + Shift + : で時刻を追加
  5. Enterキーで確定

NOW関数とTODAY関数の活用と制限

NOW( )関数は現在の日時を、TODAY( )関数は現在の日付を返しますが、シートが再計算されるたびに値が更新される点に注意が必要です。 リアルタイム表示には適していますが、記録用途には工夫が必要です。

基本的な使用方法:

=NOW( )   // 現在の日時を表示(例:2024/11/15 14:30:25)

=TODAY( )    // 現在の日付のみ表示(例:2024/11/15)

静的な値に変換する方法:

  1. NOW( )関数を入力
  2. セルをコピー(Ctrl + C)
  3. 同じセルで「値のみ貼り付け」(Ctrl + Shift + V)
  4. 関数が静的な値に置き換わる

時刻のみを抽出する場合:

=NOW()-TODAY()    // 時刻部分のみ抽出

=TEXT(NOW(),”HH:mm:ss”)    // 時刻を文字列として表示

ワークシート関数での柔軟な時刻記録

独自の要件に合わせたカスタム関数を作成することで、より柔軟な時刻記録が可能になります。

タイムゾーンに応じた表示
  • シートのタイムゾーンを JST に設定(ファイル → 設定 → 一般 → 地域と言語 → タイムゾーン)した上で
    =TEXT(NOW(),”yyyy/MM/dd HH:mm:ss”)&” JST” を使用。
  • シート側を変更できない場合は Apps Script
    Utilities.formatDate(new Date(), “Asia/Tokyo”, “yyyy/MM/dd HH:mm:ss”)
    のように 明示的に “Asia/Tokyo” を指定して書き込みます。

曜日を含む詳細表示:

=TEXT(NOW(),”yyyy年MM月dd日(ddd) HH:mm:ss”)

条件付きタイムスタンプ(反復計算を利用):

=IF(A2<>””, IF(B2=””, NOW(), B2), “”)

使用前に ファイル → 設定 → 計算 で 「反復計算を有効にする」をオン、最大反復回数=1 等に設定してください。

そうすると、A2 に値が入った瞬間に NOW() が一度だけ入り、その後は B2 が自分自身の値を保持して時刻が固定されます。

※ 反復計算を使いたくない場合は Apps Script の onEdit(e) でタイムスタンプを記録する方法が安全です。

データ検証とドロップダウンによる時刻選択

定型的な時刻入力が多い場合は、データ検証機能を使用して選択式にすることで、入力ミスを防げます。

時刻リストの作成手順
  1. 別シートに時刻リストを作成(9:00、9:30、10:00…)
  2. 入力セルを選択
  3. 「データ」→「データの入力規則」
  4. 「リストを範囲から」を選択
  5. 時刻リストの範囲を指定
15分刻みの時刻リスト
  • 0:00〜23:45 まで:
    =ARRAYFORMULA(TEXT(SEQUENCE(96,1,0,1/96),”HH:mm”))
  • 9:00 開始で 15 分刻み:
    =ARRAYFORMULA(TEXT(TIME(9,0,0)+SEQUENCE(36,1,0,1/96),”HH:mm”))

Google Apps Scriptでタイムスタンプを自動化する方法は?

GASを使用することで、特定のイベント(編集、フォーム送信等)に連動して自動的にタイムスタンプを記録できます。 完全自動化により、人為的ミスを排除し、一貫性のある時刻記録を実現できます。

スクリプトによる自動化は、大量のデータ処理や複雑な条件での時刻記録に特に有効です。トリガー機能と組み合わせることで、24時間365日稼働する自動記録システムを構築できます。

onEdit関数による編集時の自動記録

複数セル対応・初回固定・表示形式指定の安全版(A列編集→B列に記録)

function onEdit(e) {

// ガード:イベントオブジェクトが無い/複数セル以外のケースも想定

if (!e || !e.range) return;

const sheet = e.range.getSheet( );  // ← e.rangeに紐づくシートを取得

const row = e.range.getRow( );

const col = e.range.getColumn( );

const h = e.range.getNumRows( );

const w = e.range.getNumColumns( );

// 対象シート名で絞る場合(任意)

// if (sheet.getName() !== ‘入力’) return;

// 対象:A列のみ、ヘッダー(1行目)は除外

if (col !== 1 || row === 1) return;

// 編集された値(複数セル対応)

const editedValues = e.range.getValues();

// タイムスタンプを書き込む列(B列)

const tsRange = sheet.getRange(row, 2, h, 1);

const tsValues = tsRange.getValues();

const now = new Date();

for (let i = 0; i < h; i++) {

// 1列貼り付け想定(A列のみ)。A列の値を取り出す

const v = editedValues[i][0];

if (v !== “”) {

// 初回固定:B列が空のときだけ書き込む(上書きしない)

if (tsValues[i][0] === “”) tsValues[i][0] = now;

} else {

// A列を空に戻したらB列もクリア(運用に応じて削除)

tsValues[i][0] = “”; }}

tsRange.setValues(tsValues);

// 表示形式を明示(並べ替え・集計に有利:値は数値型のまま)

tsRange.setNumberFormat(“yyyy/MM/dd HH:mm:ss”);}

ポイント
  • e.range.getSheet() を使用。
  • 複数行の貼り付けにも対応(getNumRows() でループ)。
  • 初回固定(既にB列に値があれば上書きしない)。
  • 表示形式を固定して可読性と後工程の安定性を確保。

フォーム送信時に記録したい場合(onFormSubmit)

Googleフォーム連携の「回答」シートは既定で「タイムスタンプ」列がありますが、別シートへ転記する運用などで独自に記録したい場合の例です。

function onFormSubmit(e) {

if (!e || !e.range) return;

const sheet = e.range.getSheet();

const row = e.range.getRow();

const tsCell = sheet.getRange(row, 2); // 例:B列に記録

tsCell.setValue(new Date()).setNumberFormat(“yyyy/MM/dd HH:mm:ss”);}

複数シート対応の高度な実装

複数シート対応 onEdit:複数セル対応・初回固定・表示形式指定

function onEdit(e) {

if (!e || !e.range) return;

// 対象シート

const targetSheets = [‘売上データ’, ‘在庫管理’, ‘顧客情報’];

const sheet = e.range.getSheet();

if (!targetSheets.includes(sheet.getName())) return;

const row = e.range.getRow();

const col = e.range.getColumn();

const h   = e.range.getNumRows();

const w   = e.range.getNumColumns();

// 対象範囲:A〜E列、2行目以降

const startCol = 1, endCol = 5;

if (row <= 1 || col < startCol || (col + w – 1) > endCol) return;

const tsCol   = 6; // F列

const userCol = 7; // G列

// 編集された値(複数行対応、A〜Eのうち少なくとも1セルに値があれば記録)

const edited = e.range.getValues();

// 既存のタイムスタンプをまとめて取得(初回固定のため)

const tsRange  = sheet.getRange(row, tsCol, h, 1);

const tsValues = tsRange.getValues();

// 編集者(※取得できない場合がある:下記注意参照)

const editorEmail =

Session.getActiveUser().getEmail() || ”; // Workspace 外では空になることが多い

const userRange  = sheet.getRange(row, userCol, h, 1);

const userValues = userRange.getValues();

const now = new Date();

for (let i = 0; i < h; i++) {

// 行内に非空の編集があれば true(w>1 の貼り付けにも対応)

const hasValue = edited[i].some(v => v !== “”);

if (hasValue) {

// 初回固定:タイムスタンプが空のときのみ書き込む

if (tsValues[i][0] === “”) tsValues[i][0] = now;

// 編集者は常に上書き or 初回のみ等、要件に応じて切替

userValues[i][0] = editorEmail || userValues[i][0]; // 取得できた場合のみ更新

} else {

// すべて空で上書きした場合はクリア(運用に合わせて無効化可)

tsValues[i][0]   = “”;

userValues[i][0] = “”;}

tsRange.setValues(tsValues).setNumberFormat(“yyyy/MM/dd HH:mm:ss”);

userRange.setValues(userValues);}

編集者メールの注意

実運用で編集者のメールを確実に取得したい場合は、インストール型トリガー(スクリプトエディタ → トリガー)で onEdit を設定し、Google Workspace 環境での運用を推奨します。それでもポリシーにより空になることがあります。確実性が要る場合は、編集用フォーム経由にする、またはApps Script Web アプリを介した書き込みで署名付きリクエストにする等の設計が必要です。

フォーム送信時の自動タイムスタンプ

フォーム送信 onFormSubmit:シートをイベントから取得・基準列を固定

function onFormSubmit(e) {

if (!e || !e.range) return;

const sheet = e.range.getSheet();

const row   = e.range.getRow();

const tz = Session.getScriptTimeZone(); // プロジェクトのタイムゾーン

const now = new Date();

const formatted = Utilities.formatDate(now, tz, “yyyy/MM/dd HH:mm:ss”);

// 追記開始位置を先に固定(逐次 getLastColumn() を呼ばない)

const baseCol = sheet.getLastColumn() + 1;

// 追加項目(例)

const emailFromForm = (e.namedValues && e.namedValues[‘Email’])

? String(e.namedValues[‘Email’][0] || ”) : ”;

// まとめて書き込み

const values = [[

formatted, // 追加タイムスタンプ(文字列表示)

tz, // タイムゾーン

emailFromForm,   // フォームのEmail項目(名称は実シートに合わせて)

“PR-” + Utilities.formatDate(now, tz, “yyyyMMdd-HHmmss”)  // 処理番号]];

sheet.getRange(row, baseCol, 1, values[0].length).setValues(values);

// 追加した最初の列だけ数値型で持ちたい場合は setValue(new Date()) + setNumberFormat を使用

// sheet.getRange(row, baseCol).setValue(now).setNumberFormat(“yyyy/MM/dd HH:mm:ss”);}

補足

Google フォームの回答シートには既定でタイムスタンプ列があるため、上記は追加情報が必要な場合の例です。
e.namedValues のキーは質問文そのものです。スペルや全角半角の違いに注意し、変更があり得る質問文をキーにする場合は項目ID管理見出し行のマッピングを検討してください。

バッチ処理による定期的なタイムスタンプ更新

時間主導トリガーを使用した定期実行:

javascript

function setupTimeDrivenTriggers() {

// 1時間おき/毎時00分近辺で実行(完全な保証ではない)

ScriptApp.newTrigger(‘hourlyTimestamp’)

.timeBased()

.everyHours(1)

.nearMinute(0)

.create();

// 例:毎日 00:00 に実行(確定時刻が必要ならこちら)

ScriptApp.newTrigger(‘hourlyTimestampDaily’)

.timeBased()

.atHour(0)

.everyDays(1)

.create();}

function hourlyTimestamp() {

const ss = SpreadsheetApp.getActiveSpreadsheet();

const sheet = ss.getSheetByName(‘ログ’);

if (!sheet) return; // シートが無ければ終了

const now = new Date();

const tz  = Session.getScriptTimeZone();

// 欲しい指標に合わせて取得(例:権限ユーザー数)

const editors = ss.getEditors().length;

const viewers = ss.getViewers().length; // 現在の閲覧者数ではない点に注意

// ファイルサイズの例:Advanced Drive(サービス「Drive」を有効化)で quotaBytesUsed を取得

// const file = Drive.Files.get(ss.getId());

// const bytes = Number(file.quotaBytesUsed || 0);

// 代替:行数×列数などの運用メトリクスを記録

const usedRows = sheet.getLastRow();

const usedCols = sheet.getLastColumn();

const values = [[

now,

‘システム自動記録’,

viewers, // 閲覧権限ユーザー数

editors, // 編集権限ユーザー数

usedRows,

usedCols

// bytes // 使うなら Advanced Drive を有効化して上記コメント解除]];

const targetRange = sheet.getRange(sheet.getLastRow() + 1, 1, 1, values[0].length);

targetRange.setValues(values);

// 1列目の日時だけフォーマット固定

sheet.getRange(targetRange.getRow(), 1).setNumberFormat(“yyyy/MM/dd HH:mm:ss”);}

// 古いログの自動削除(30日以上前)

cleanOldLogs(sheet, 30);}

function cleanOldLogs(sheet, daysToKeep) {

const lastRow = sheet.getLastRow();

if (lastRow < 2) return; // データ無し

const rng = sheet.getRange(2, 1, lastRow – 1, 1); // 1列目に日時が入っている想定

const vals = rng.getValues();

const cutoff = new Date(Date.now() – daysToKeep * 24 * 60 * 60 * 1000);

// 残す行をフィルタして一括で書き戻す方式(高速)

const keep = vals

.map((r, idx) => ({ row: idx + 2, value: r[0] instanceof Date ? r[0] : new Date(r[0]) }))

.filter(o => !(o.value < cutoff))

.map(o => sheet.getRange(o.row, 1, 1, sheet.getLastColumn()).getValues()[0]);

// 既存データをまとめてクリア → 残すデータを再書き込み

if (lastRow > 1) sheet.getRange(2, 1, lastRow – 1, sheet.getLastColumn()).clearContent();

if (keep.length) sheet.getRange(2, 1, keep.length, keep[0].length).setValues(keep);}

※ 行数が非常に多い場合は、フィルタビュー+削除や別シートへコピー方式がさらに高速です。

タイムスタンプを記録する際の注意点は?

タイムスタンプの正確性と一貫性を保つためには、タイムゾーン設定、フォーマットの統一、パフォーマンスへの影響を考慮する必要があります。 これらの要素を適切に管理することで、信頼性の高い時刻記録システムを構築できます。

タイムスタンプは、データの監査証跡やトレーサビリティの基盤となるため、その精度と整合性は極めて重要です。特に、複数の地域やシステムと連携する場合は、標準化された時刻管理が不可欠です。

タイムゾーンの設定と変換処理

スプレッドシートとスクリプトのタイムゾーンを正確に設定することで、時刻のずれを防げます。 国際的なチームで作業する場合は、UTC基準での管理も検討すべきです。

タイムゾーン設定の確認と変更
  1. スプレッドシートの設定:「ファイル」→「設定」→「タイムゾーン」
  2. スクリプトの設定:「拡張機能」→「Apps Script」→「プロジェクトの設定」→「タイムゾーン」
運用上の推奨
  • 保存はUTC(new Date() をそのまま保存)、表示は Utilities.formatDate(…, “Asia/Tokyo”, …) などでローカル化。
  • シート:[ファイル → 設定 → 一般 → タイムゾーン]、スクリプト:エディタ右上の歯車 → プロジェクトの設定 → タイムゾーン を同一方針に揃える。
  • クロスリージョンで共有する台帳は、列を分けて UTC列(数値型の日時)+ローカル表示列(文字列) にすると混乱が減ります。

表示時にタイムゾーンを適用する(推奨)

// 任意TZでフォーマットして表示用文字列を得る

function formatInTZ(dt, tz, pattern) {

return Utilities.formatDate(dt, tz, pattern || “yyyy/MM/dd HH:mm:ss”);}

// 使い方例

function showTimes() {

const now = new Date();  // UTCベースの瞬間

const tokyo = formatInTZ(now, “Asia/Tokyo”);

const utc   = formatInTZ(now, “UTC”);

const ny    = formatInTZ(now, “America/New_York”);

const la    = formatInTZ(now, “America/Los_Angeles”);

SpreadsheetApp.getActiveSheet().appendRow([“Tokyo”, tokyo, “UTC”, utc, “New York”, ny, “Los Angeles”, la]);}

方針:データとしては UTC の Date を保存し、表示や書き出し時に Utilities.formatDate で所望TZへ整形します。

function displayMultipleTimezones() {

const sheet = SpreadsheetApp.getActiveSheet();

const now = new Date();

const pat = “yyyy/MM/dd HH:mm:ss z”; // zでTZ略称を自動付与(EST/EDT等)

sheet.appendRow([

‘Tokyo (Asia/Tokyo)’, Utilities.formatDate(now, ‘Asia/Tokyo’, pat),

‘UTC’,   Utilities.formatDate(now, ‘UTC’, pat),

‘New York’,  Utilities.formatDate(now, ‘America/New_York’, pat),

‘Los Angeles’, Utilities.formatDate(now, ‘America/Los_Angeles’, pat)]);}

ラベルは 地域名 or IANA TZ名 で表記し、略称は z で自動出力すると DST を含め正確です。

フォーマットの統一と表示形式の最適化

一貫性のあるフォーマットにより、データの比較や分析が容易になります。

推奨フォーマットパターン
  • ISO 8601形式:yyyy-MM-dd’T’HH:mm:ss’Z’ (国際標準)
  • 日本標準形式:yyyy/MM/dd HH:mm:ss
  • ファイル名用:yyyyMMdd_HHmmss (特殊文字なし)
  • 人間可読形式:yyyy年MM月dd日(E) HH時mm分ss秒

カスタム表示形式の設定:

javascript

function formatTimestamp(date, pattern) {

var patterns = {

‘iso’: “yyyy-MM-dd’T’HH:mm:ss’Z'”,

‘japanese’: “yyyy/MM/dd HH:mm:ss”,

‘filename’: “yyyyMMdd_HHmmss”,

‘readable’: “yyyy年MM月dd日(E) HH時mm分ss秒”};

return Utilities.formatDate(

date,

Session.getScriptTimeZone(),

patterns[pattern] || pattern);}

パフォーマンスとスケーラビリティの最適化

大量のタイムスタンプ処理において考慮すべき点

避けるべきパターン:

javascript

// 個別にタイムスタンプを設定(非効率)

for (var i = 0; i < 1000; i++) {

sheet.getRange(i + 1, 1).setValue(new Date());}

推奨パターン:

javascript

// バッチ処理で一括設定(効率的)

var timestamps = [];

var now = new Date();

for (var i = 0; i < 1000; i++) {

timestamps.push([now]);}

sheet.getRange(1, 1, timestamps.length, 1).setValues(timestamps);

データの整合性とバックアップ戦略

タイムスタンプの改ざん防止と監査証跡の確保:

javascript

function createAuditLog(action, details) {

var auditSheet = SpreadsheetApp.getActiveSpreadsheet()

.getSheetByName(‘監査ログ’) || createAuditSheet();

var logEntry = [

new Date(),  // タイムスタンプ

Session.getActiveUser().getEmail(),  // ユーザー

action,   // アクション

details,   // 詳細

Utilities.computeDigest(   // ハッシュ値

Utilities.DigestAlgorithm.SHA_256,

JSON.stringify([new Date(), action, details]),

Utilities.Charset.UTF_8 )];

auditSheet.appendRow(logEntry);

// シート保護(読み取り専用)

var protection = auditSheet.protect();

protection.setDescription(‘監査ログ保護’);

protection.removeEditors(protection.getEditors());}

実践的なタイムスタンプ活用でデータ管理を効率化

Googleスプレッドシートにおけるタイムスタンプの適切な実装は、データの信頼性向上と業務プロセスの可視化に不可欠な要素です。手動入力ではショートカットキーとNOW関数を使い分け、Google Apps Scriptによる自動化では、onEdit関数やトリガー機能を活用して完全自動化を実現できます。

タイムゾーンの適切な設定、フォーマットの統一、パフォーマンスの最適化といった考慮事項を押さえることで、スケーラブルで信頼性の高い時刻記録システムを構築できます。これらの技術を組み合わせることで、監査対応可能な堅牢なデータ管理基盤を確立し、業務の効率化と品質向上を同時に実現できます。


※ 掲載している情報は記事更新時点のものです。

※本サイトは、法律的またはその他のアドバイスの提供を目的としたものではありません。当社は本サイトの記載内容(テンプレートを含む)の正確性、妥当性の確保に努めておりますが、ご利用にあたっては、個別の事情を適宜専門家にご相談いただくなど、ご自身の判断でご利用ください。

関連記事