MT4のチャート右下に表示されている時刻を、

そのまま日本時間だと思い込んでいないでしょうか。

実はあの時刻は「ブローカーのサーバーがある場所の時間」であり、

日本時間とは数時間単位でズレているのが普通です。

この記事では、`TimeCurrent`・`TimeLocal`・`TimeGMT`という

3つの時間取得関数が何を返しているのかを整理したうえで、

サーバー時間と日本時間を両方チャート上に表示するインジケーターの作り方を解説します。

この記事で分かること
・TimeCurrent/TimeLocal/TimeGMTの違い
・「TimeLocal=日本時間」という誤解がなぜ危険か
・TimeGMTを使って日本時間を正確に計算する方法
・実際に動くインジケーターのコード全体

サーバー時間・ローカル時間・GMTはなぜズレるのか

まず、MT4が扱う3種類の「時間」の違いを確認します。

TimeCurrentはブローカーのサーバー時間

`TimeCurrent()`が返すのは、あなたのパソコンの時計ではなく、

ブローカーのサーバーが刻んでいる時間です。

サーバーの所在地はブローカーによって異なり、多くは米国東部時間や欧州時間を基準に、

GMT+2やGMT+3といったオフセットで運用されています。

TimeLocalは「日本時間」ではなくPCの設定時刻

`TimeLocal()`が返すのは、

MT4を動かしているパソコンのOSに設定された時刻です。

パソコンの時計が正しく日本時間に設定されていれば日本時間と一致しますが、

VPS(仮想専用サーバー)を海外リージョンで借りている場合などは、

OSの設定自体がUTCや現地時間になっていることがあり、

`TimeLocal()`が日本時間だという前提は成り立ちません。

サマータイム(夏時間)でさらにズレが変動する

欧米の多くの地域では夏時間(サマータイム)が採用されており、

年に2回、サーバーとの時差が1時間変化します。

「先月は合っていたのに今月はズレている」という場合、

多くはこのサマータイムの切り替えが原因です。

日本時間を正確に計算する方法

PCの設定に依存しない、確実な日本時間の求め方を確認します。

TimeGMTは常にUTC(協定世界時)を返す

datetime TimeGMT();

`TimeGMT()`は、PCのタイムゾーン設定やブローカーのサーバー設定に関係なく、

常にUTC(協定世界時)を返します(公式リファレンス)。

これを基準にすれば、PC設定に依存しない時間計算ができます。

日本時間はUTC+9固定で計算できる

datetime jst = TimeGMT() + 9 * 3600;

日本時間(JST)はUTC+9で固定されており、サマータイムを採用していません。

そのため`TimeGMT()`に9時間(3600秒×9)を足すだけで、

PCの設定やブローカーの所在地に関係なく、常に正確な日本時間が計算できます。

TimeGMTOffset()との違いに注意

int TimeGMTOffset();
// TimeGMTOffset() = TimeGMT() - TimeLocal()

`TimeGMTOffset()`はGMTとPCのローカル時刻との差を秒で返す関数で、

PCのタイムゾーン設定を調べる用途には使えますが、「日本時間を求める」

用途には使いません(公式リファレンス)。

PCの設定が日本時間でなければ、この関数からは日本時間を導けない点に注意してください。

補足
・TimeLocal()はPCの設定次第で変わる不確実な値
・TimeGMT()はPC設定に依存しない確実な値
・日本時間が欲しいときはTimeLocal()ではなくTimeGMT()+9時間を使う

インジケーターの表示設計を考える

実際にチャート上へ時刻を表示する設計を決めます。

ObjectCreate(OBJ_LABEL)でチャート左上に文字を表示する

座標固定で常に見える位置に表示したいため、ローソク足に紐づく図形ではなく、

`OBJ_LABEL`(チャート座標に固定されるラベル)を使います。

EventSetTimer/OnTimerで1秒ごとに更新する

価格が動かない間も時刻表示は進める必要があるため、

新しい足が来たときだけ処理される`start()`ではなく、

`EventSetTimer(1)`で1秒ごとに呼ばれる

`OnTimer()`の中で文字列を更新します。

市場セッション(東京/ロンドン/NY)の目安も添える

日本時間が分かると、「今は東京時間なのか、ロンドン時間なのか」も判断しやすくなります。

この記事では、日本時間の時刻に応じておおまかなセッション名を文字列で添える処理も加えます。

実際に動くコード全体

ここまでの要素をまとめたインジケーターの全体です。

//+------------------------------------------------------------------+
//|                                       ServerTimeJstIndicator.mq4   |
//|                     Copyright 2026, FX-EA System Project Creator  |
//|                        https://creator.fx-ea-system-project.com/  |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 0

string ObjName_Server = "stji_server";
string ObjName_Jst    = "stji_jst";
string ObjName_Session = "stji_session";

int init()
  {
   ObjectCreate(ObjName_Server, OBJ_LABEL, 0, 0, 0);
   ObjectSet(ObjName_Server, OBJPROP_CORNER, 1);
   ObjectSet(ObjName_Server, OBJPROP_XDISTANCE, 10);
   ObjectSet(ObjName_Server, OBJPROP_YDISTANCE, 20);

   ObjectCreate(ObjName_Jst, OBJ_LABEL, 0, 0, 0);
   ObjectSet(ObjName_Jst, OBJPROP_CORNER, 1);
   ObjectSet(ObjName_Jst, OBJPROP_XDISTANCE, 10);
   ObjectSet(ObjName_Jst, OBJPROP_YDISTANCE, 36);

   ObjectCreate(ObjName_Session, OBJ_LABEL, 0, 0, 0);
   ObjectSet(ObjName_Session, OBJPROP_CORNER, 1);
   ObjectSet(ObjName_Session, OBJPROP_XDISTANCE, 10);
   ObjectSet(ObjName_Session, OBJPROP_YDISTANCE, 52);

   EventSetTimer(1);
   UpdateLabels();
   return(0);
  }

int deinit()
  {
   EventKillTimer();
   ObjectDelete(ObjName_Server);
   ObjectDelete(ObjName_Jst);
   ObjectDelete(ObjName_Session);
   return(0);
  }

string GetSessionName(int jstHour)
  {
   if(jstHour >= 8 && jstHour < 16)
      return("東京時間の目安");
   if(jstHour >= 16 && jstHour < 21)
      return("東京・ロンドン重複の目安");
   if(jstHour >= 21 || jstHour < 2)
      return("ロンドン・NY重複の目安");
   return("閑散時間帯の目安");
  }

void UpdateLabels()
  {
   datetime serverTime = TimeCurrent();
   datetime jstTime     = TimeGMT() + 9 * 3600;

   ObjectSetText(ObjName_Server, "サーバー時間: " + TimeToStr(serverTime, TIME_DATE|TIME_SECONDS), 12, "Arial", White);
   ObjectSetText(ObjName_Jst, "日本時間: " + TimeToStr(jstTime, TIME_DATE|TIME_SECONDS), 12, "Arial", Yellow);

   MqlDateTime dt;
   TimeToStruct(jstTime, dt);
   ObjectSetText(ObjName_Session, GetSessionName(dt.hour), 10, "Arial", Silver);
  }

void OnTimer()
  {
   UpdateLabels();
  }

int start()
  {
   UpdateLabels();
   return(0);
  }

MetaEditorでのコンパイル・実行手順

実際にMT4へ適用するまでの手順を確認します。

  1. MetaEditorで新規カスタムインジケーター「ServerTimeJstIndicator」を作成し、上のコードを貼り付けてコンパイルする
  2. MT4のナビゲーターからチャートへドラッグ&ドロップで適用する
  3. チャート右上に「サーバー時間」「日本時間」「セッションの目安」の3行が表示されることを確認する
  4. サーバー時間と日本時間の時差が、普段把握している時差と一致するか確認する

よくあるエラーと注意点

実装・運用でつまずきやすいポイントをまとめます。

OnTimerが呼ばれない・表示が更新されない

注意
・init()でEventSetTimer(1)を呼び忘れるとOnTimer未実行
・deinit()でEventKillTimer()を呼ばないとタイマー残存

サーバー時間が想定より2〜3時間ズレて見える

ブローカーによってはGMT+2やGMT+3を採用しており、

さらにサマータイムの有無も異なります。

このインジケーターはサーバー時間を加工せずそのまま表示するため、

「サーバー時間と日本時間の差が何時間になるか」はブローカーごとに確認が必要です。

MQL5との違い

このコードはMQL4(init/start/deinit形式)を前提にしています。

MQL5では`OnInit`/`OnCalculate`/`OnDeinit`形式に

書き換える必要があり、

タイマーの扱いは`EventSetTimer`/`OnTimer`のまま共通で使えますが、

`ObjectCreate`の引数の数がMQL5では異なる点に注意してください。

よくある質問

サーバー時間・日本時間の表示について、よく検索される疑問に回答します。

TimeLocal()を使って日本時間を表示してはいけませんか?

PCのOS設定が確実に日本時間になっている環境(自宅PC等)であれば、

結果的に一致することもあります。

ただし海外サーバー上のVPSではOS設定が日本時間でないことが多く、

`TimeGMT()+9時間`の方が環境に左右されず確実です。

サマータイムの開始・終了日を自分で計算する必要がありますか?

いいえ。

`TimeGMT()`はサマータイムの影響を受けないUTCを返すため、

日本時間側の計算(UTC+9固定)にサマータイムを考慮する必要はありません。

サマータイムの影響を受けるのは、あくまでブローカーのサーバー時間側です。

このインジケーターだけでEAの時間条件も管理できますか?

表示用途としては十分ですが、

EAのエントリー時間条件には、

このインジケーターのロジックを

そのままEA側にも組み込む必要があります。

表示と実際の取引ロジックは別のコードとして扱ってください。

【MQL4】TimeGMT・TimeLocal・TimeCurrentの違いを整理して、サーバー時間と日本時間を両方表示するインジケーターの作り方:まとめ

MT4のチャート時刻は「サーバー時間」であり、

日本時間とは別物です。

`TimeLocal()`はPCの設定に依存するため、

日本時間を確実に求めたいときは

`TimeGMT()+9時間`を使うのが安全です。

関連記事