質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
DateTime

多くのプログラミング言語におけるDateTimeオブジェクトは、日付と時間に関する演算と出力を行います。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

UNIX

UNIXとは、AT&Tのベル研究所で開発されたコンピューター用のマルチユーザー・マルチタスクのオペレーションシステム(OS)です。政府や教育機関や研究所で広範囲に採用されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

3回答

6643閲覧

実行時間が負の値になる場合がある(UNIXタイムの誤差?)

raaacho

総合スコア28

DateTime

多くのプログラミング言語におけるDateTimeオブジェクトは、日付と時間に関する演算と出力を行います。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

UNIX

UNIXとは、AT&Tのベル研究所で開発されたコンピューター用のマルチユーザー・マルチタスクのオペレーションシステム(OS)です。政府や教育機関や研究所で広範囲に採用されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/11/25 05:02

編集2017/11/25 05:03

UNIXタイムでコードの実行時間を測定しようとした結果,マイナスの値が出てしまいます.

具体的なシステム構成を以下に述べます.
まず,iPhoneアプリ上でタップした時のタイムスタンプをswiftで取得します.
swiftではマイクロ秒で出てくるため1000をかけてミリ秒に変換します.

swift

1 let today = Date(); 2 let sec = today.timeIntervalSince1970 3 let timestamp = String(UInt64(sec * 1000)) 4 socket.emit("tap", timestamp)

その後,上記のコードにあるようにすぐにnodeで作ったサーバにタイムスタンプを送信し,サーバはPCブラウザにそのデータを送信します.

javascript

1 socket.on("tap", function(msg){ 2 console.log("tap_at: " + msg); 3 io.sockets.emit('server_to_chrome_tap', msg); 4 });

ブラウザがデータを受信した時のタイムスタンプをJavaScriptで取得し,
それらのタイムスタンプを”終了時間ー開始時間”で引き算した結果をブラウザのコンソールに出力します.

javascript

1 socket.on("server_to_chrome_tap", function(dataFromServer) { 2 var startTimeStamp = dataFromServer; 3 end = new Date(); 4 var endTimeStamp = end.getTime(); 5 console.log(startTimeStamp); 6 console.log(endTimeStamp); 7 console.log(endTimeStamp - startTimeStamp); 8 });

以上のコードを実行した結果,70や68など自然数が表示される場合と-1や-3といった負の値が表示される時があります
だいたい半分くらいの割合で負の値になります.

これはUNIX時間の誤差の問題なのでしょうか?

それとも私が書いたコードが悪いのでしょうか?

どちらにせよ,この問題点と解決策を教えていただけると助かります.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

defghi1977

2017/11/26 12:08

システム構成をもっと明確化して下さい(WEBソケットの通信先等). タイムスタンプに絡む問題には多くの落とし穴が存在するため, 皆さんアドバイスに苦慮しています.
fuzzball

2017/11/27 00:32

質問の本質とは関係ないですが .timeIntervalSince1970 って秒単位ですよ。
guest

回答3

0

最も気にするべきはスマホとNode.jsサーバーの現在時刻の差だね。
パソコン機器の時計は精度が悪いから平気で数秒狂うし、スマホの時刻だってそんな正確かどうかなんて保証出来ないからね。

それらのタイムスタンプを”終了時間ー開始時間”で引き算した結果をブラウザのコンソールに出力します.

この一文を見てると、
スマホの現在時刻を開始時点にして、サーバーの終了時刻で引き算してるように思えるんだよね。
もしスマホがサーバーより数秒間進んでいたら、受け取ったサーバは未来のタイムとして認識するから、負の値が出て当然。


どっちかが両方の時刻の差を尊重するしかない。
例えばスマホから「サーバーさんは今何時何分版秒よ?」というリクエストを10分程度といった間隔で送って、受け取った時刻と端末の時刻の差を考慮に入れたタイムスタンプを生成するか、
Node.js鯖が受け取った時刻のタイムスタンプは参考記録としておいておいて、自分のサーバーで生成した時刻を元に計算して、最後にタイムスタンプを加工するとか…ね

投稿2017/11/25 06:23

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

think49

2017/11/25 08:45

回答の趣旨に同意なので、ここにコメントします. > 最も気にするべきはスマホとNode.jsサーバーの現在時刻の差だね。 私もこれが原因だと思いますが、これが原因ならクライアントorサーバだけでタイムスタンプを取得すれば、解決するように思いました。 必要なのが処理時間であれば、時差は関係なくて「開始時刻」「終了時刻」を同じ媒体から取得すれば、正確な時間差を得ることが出来ます。 HTTPリクエストする時間を処理時間にふくめるならクライアントでタイムスタンプを取得し、HTTPリクエスト時間を含めないならサーバでタイムスタンプを得れば良いと思います。 両方取得すれば、HTTPリクエスト時間を引き算で算出できます。
miyabi-sun

2017/11/25 09:01

そうですね。 おっしゃるように基本的にサーバ側が常に正で、ローカルの時刻は捨ててしまえば解決すると思います。 今回私が想像したのは下記のようなサイトです。 このサービスは現在時刻を正確なサーバと通信して割り出し、差分を表示してくれるWebアプリになっています。 https://www.nict.go.jp/JST/JST5.html ローカルからタイムスタンプを何故送る事を考えたのかという視点で、 (非常にニッチなケースとなりそうですが)上手く両者の辻褄を合わせる事が目的の場合、 何をしなければならないかを共有しておこうと思い、今回の回答文を用意しています。
think49

2017/11/26 11:47

調べてみましたが、NTPでは通信遅延時間も考慮したアルゴリズムになっているようで、別のアプローチが必要なようです。 詳しくは、回答欄に書きました。
defghi1977

2017/11/26 11:56

nodeサーバーはタイムスタンプを扱ってない気がするのですが? ただ見直してみたら, スマホ(タイムスタンプ取得)→node(タイムスタンプをスルー)→WEBブラウザ(現在時刻と比較)とすると, スマホとWEBブラウザの関係がよくわからず.
miyabi-sun

2017/11/26 12:14

素直に読み取ればスマホの自己申告時刻(タイムスタンプ)を利用しています。 `socket.on("server_to_chrome_tap", function(dataFromServer) {`からの ` var startTimeStamp = dataFromServer;`なんで、 Swiftがemitした文字列をそのままstartTimeStamp変数に流し込んでいます。 最後がNumber - Stringなので気持ち悪いですが、弊害は出ていないかと思います。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime (new Date()).getTime() // 1511698093227 new Date(1511698093227) // Sun Nov 26 2017 21:08:13 GMT+0900 (東京 (標準時))
guest

0

NTP (Network Time Protocol)

NTPとは、NTPサーバとクライアント端末が交信する事でクライアント端末の時刻をNTPサーバの時刻に同期するプロトコルの事です。
NTPサーバから正しい時刻を受信して同期をとればいいわけですが、NTPでは通信遅延時間を考慮したプロトコルになっています。

次のように、通信されたと仮定します。

変数サーバ時刻クライアント時刻処理内容
ts20:00:0020:00:04クライアントがリクエストを送信した時刻
Tr20:00:0120:00:05サーバがクライアントのリクエストを受信した時刻
Ts20:00:0320:00:07サーバがレスポンスを送信した時刻
tr20:00:0420:00:08クライアントがサーバのレスポンスを受信した時刻

往路(クライアント->サーバ)と復路(サーバ->クライアント)の通信時間に差がないと仮定すれば、次の計算式でサーバとクライアントの時刻差を算出できます。

(Ts + Tr) / 2 - (ts + tr) / 2; // 20:00:02 - 20:00:06 = -00:00:04

よって、クライアント端末の時刻を4秒マイナスする事になり、20:00:08から20:00:04にクライアント端末の時刻を修正することが出来ます。

処理時間

処理時間にも単位があります。

(A) クライアントからサーバへHTTPリクエスト
(B) サーバ処理
(C) サーバからクライアントへHTTPレスポンスし、クライアントで受け取る

処理時間が「(A), (B), (C) の合算」な場合は下記手順で解決します。

(A) クライアント側で「開始時刻」を記録
(C) クライアント側で「終了時刻」を記録

(B) だけが必要な場合は、下記手順で解決します。

(B) サーバで処理開始時に「開始時刻」を記録し、処理終了時に「終了時刻」を記録

それ以外の組み合わせが必要な場合は、NTPと同じ原理で時刻を修正する必要があります。
クライアント端末側からみれば、NTPと同じ仕組みで実装可能ですが、サーバ側で記録をとる場合はもう一度、クライアントからサーバへリクエストを投げ返す必要があります。
サーバから見れば、クライアントへのレスポンスが「サーバからのリクエスト」となるからです。

Re: raaacho さん

投稿2017/11/26 11:45

編集2017/11/26 11:54
think49

総合スコア18162

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

コードの内容と時刻の分解能の点から察するにDate.now()よりHigh Resolution Time仕様で定義されているTimeperformance.timing.navigationStart + performance.now()の方が良かろうと感じます.

※詳しくは試していないのであくまでヒントということで.

[参考]
https://developer.mozilla.org/ja/docs/Web/API/Performance/now

投稿2017/11/25 05:30

defghi1977

総合スコア4756

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問