🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

2532閲覧

経過日数から日時を求める VC++

lo12014

総合スコア8

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/12/09 11:55

編集2019/12/09 13:37

お世話になります。

現在、2019年1月1日0時0分からある日数が経過した時(具体的には343.18448348日)の日時を世界協定時で求める関数を作っています。いかのようなコードを実行したところ、2019年12月8日19時25分39秒と、世界協定時より9時間早く計算されてしまいます。(手計算では9日、4時25分39秒)結果的に9時間足せばいいのですが、それでは根本的な解決にはならないと思います。(ctime をincludeして struct tm, time_t を用いています)
対処法をご存じでしたら、ご教授していただけると幸いです。
宜しくお願い致します。

#include <ctime> #include <iostream> using namespace std; int main(){    tm from = { 0,0,0,0,0,100 + year,0,0,0 }; // From 01.01.2019 (year = 19)    time_t time_pass = mktime(&from); // 1970/1/1/0:0:0 からの経過時間をunixで返す    time_t obrv_time = time_pass + day * 24 * 3600; // さらにday(343.18448348日分の経過秒数を足す) tm obrv_date = { 0,0,0,0,0,0,0,0,0 }; errno_t err = gmtime_s(&obrv_date, &obrv_time); // UTCで日時を返す } // 結果 // 2019-12-8 19:25:39 //手計算では 4:25:39のはず...

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

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

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

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

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

cateye

2019/12/09 13:08 編集

日本の時刻は、世界協定時(UTC)+9時間をご存知の上の質問でしょうか?
lo12014

2019/12/09 13:29

ご回答ありがとうございます。 はい。承知しております。 なので、gmtime_s関数でUTCの時間を得るようにしています。
guest

回答3

0

C++

1 tm from = { 0,0,0,0,0,100 + year,0,0,0 }; // From 01.01.2019 (year = 19)

メインの問題は解決しているところ申し訳ありません。
ちょっとだけ気になったのですが、これ、1日ずれていませんか?
tmのもつ変数のうちtm_mdayだけ値の範囲が0ではなく1始まりになっていたはず

投稿2019/12/10 17:04

yominet

総合スコア187

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

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

yumetodo

2019/12/11 01:18

あっ、見落としてた
lo12014

2019/12/11 05:46 編集

yominet様 ご指摘ありがとうございます。 確かにそうですね。コンパイルエラーにならなかったので、気づきませんでした。 私が計算に使っていた経過日数は、スタートの日付を数えたうえでの経過日数のようでした。 (343.18..日目という意味) ですので、1日ずらしてtm_mday = 0 でたまたま上手くいったようです。 tm_mday = 1 、time_pass = _mkgmtime - 24 * 3600 として、欲しい結果を出すようにしました。 ご指摘ありがとうございました。また機会がありましたら、どうぞ宜しくお願いいたします。
guest

0

mktimeを使っているからでは

投稿2019/12/09 12:43

yumetodo

総合スコア5852

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

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

episteme

2019/12/09 19:32

VC++なら _mkgmtime があったはず確か。
lo12014

2019/12/09 23:23

ご回答ありがとうございました。 上記の関数で欲しい結果が得られました。 また機会がありましたら、宜しくお願いいたします。
yumetodo

2019/12/10 03:40

余談ですがC++20でstd::chronoにカレンダーライブラリが追加されるので、それを使うことも検討してみてください。
guest

0

ベストアンサー

9時間ずれるということから質問の2019年1月1日0時0分はUTCのつもりなのでしょうけれど、
mktimeは引数で渡された現地時刻に対応する値を返すため9時間ずれます(UTCでは2018年12月31日15時0分)。
UTCの2019年1月1日0時0分に対応する値を得たい場合は_mkgmtimeを使用してください。
移植性をたもつならTZ環境変数を一時的にUTCにするという方法もあります。

投稿2019/12/09 19:31

編集2019/12/10 00:53
SHOMI

総合スコア4079

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

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

lo12014

2019/12/09 23:22

ご回答ありがとうございました。 _mkgmtimeで無事欲しい結果を得られました。 mktimeがローカルな時間を返すのを知りませんでした。 しかし、mktimeでローカルな時間を返すとしてもなぜ9時間遅くでなく、9時間早い結果が得られたのかは少しモヤモヤいたしますので、考えてみようと思います。 また機会がありましたら、よろしくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問