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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

解決済

4回答

1449閲覧

C:現在時刻より前の時刻が与えられた場合に翌日だと判定する処理

Ykkykk

総合スコア140

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

0グッド

0クリップ

投稿2021/07/20 00:53

C言語でrtcwakeの内部処理と同様の処理を行って、ユーザから受け取った時刻に基づいてサスペンドしてレジュームする処理を考えています。

このとき、rtcwakeでは年月日時分秒の形式で起動時刻を与える必要がありますが、時刻だけ受け取って設定したいです。
その時、与えられた時刻が現在より前の時刻であった場合、それを翌日の時刻として取り扱いたく思っております。

struct rtc_timeのtm_mdayを単純に一つインクリメントすれば良いかと思ったのですが、実際には翌日が来月の可能性と来年の可能性、あるいはその双方である可能性や、月末であった場合に30日までなのか31日までなのか、うるう年かどうかなどの判定を行う必要があると思いました。

このような場合、愚直に条件分岐で日付を判定するしかないでしょうか。

ちなみに、rtcwwakeで実際にRTCタイマをセットしている関数は下記の通りです。

static int setup_alarm(struct rtcwake_control *ctl, int fd, time_t *wakeup) { struct tm tm; struct rtc_wkalrm wake = { 0 }; /* The wakeup time is in POSIX time (more or less UTC). Ideally * RTCs use that same time; but PCs can't do that if they need to * boot MS-Windows. Messy... * * When clock_mode == CM_UTC this process's timezone is UTC, so * we'll pass a UTC date to the RTC. * * Else clock_mode == CM_LOCAL so the time given to the RTC will * instead use the local time zone. */ localtime_r(wakeup, &tm); wake.time.tm_sec = tm.tm_sec; wake.time.tm_min = tm.tm_min; wake.time.tm_hour = tm.tm_hour; wake.time.tm_mday = tm.tm_mday; wake.time.tm_mon = tm.tm_mon; wake.time.tm_year = tm.tm_year; /* wday, yday, and isdst fields are unused */ wake.time.tm_wday = -1; wake.time.tm_yday = -1; wake.time.tm_isdst = -1; wake.enabled = 1; if (!ctl->dryrun && ioctl(fd, RTC_WKALM_SET, &wake) < 0) { warn(_("set rtc wake alarm failed")); return -1; } return 0; }

上記のtm_mday, tm_mon, tm_yearを定義しなかったり、-1にしたりすると、ioctlでエラーとなってしまいます。

ご教示いただけますと幸いです。よろしくお願いいたします。

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

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

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

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

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

guest

回答4

0

年月日から、mktime()でUnixTimeを求めて、それに60*60*24を足して、localtime()で年月日に戻せば良いかと。

mktime()では、「8月32日」を「9月1日」と認識するので、Unixtimeへの変換前に日付を単に+1するだけでも良いです。

投稿2021/07/20 01:13

otn

総合スコア84533

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

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

Ykkykk

2021/07/20 01:32

ご回答ありがとうございます。mktimeの挙動をお教えくださりありがとうございます。大変参考になりました。ありがとうございます!
Ykkykk

2021/07/20 01:35

すみません、こちらですが、最初にlocaltimeでtm構造体を埋め、一日インクリメントしたものをmktimeに渡すという理解で問題ないでしょうか?
otn

2021/07/20 05:39

そうですね。2つ目の文で書いた方法だとそういうことになります。 1.tm構造体セット 2.mdayだけ+1 3.mktime 4.localtime
Ykkykk

2021/07/20 07:10

何度もありがとうございます。はっきりと理解できました。y_waiwaiさんのご回答と合わせて今回はlocaltimeではなくgmtime関数を使用して同様の処理を実装しました。本当にありがとうございます!大変参考になりました。
Ykkykk

2021/07/20 08:32

何度もすみません。こちら3から4の後tm構造体を見ると日付がインクリメントする前(今日)に戻ってしまうようです。gmtimeの問題でしょうか。。。
otn

2021/07/20 08:34

localtimeでなくてgmtimeを使うと9時間ずれますよ。 何故にgmtime????回答が理解できない?
Ykkykk

2021/07/20 08:36

RTC側がUnix時間になっているためUnix時間で設定したくgmtimeを使用しております。
otn

2021/07/20 08:41 編集

回答の意味を理解せずに一部を勝手に書き換えると正しい結果が得られません。 > RTC側がUnix時間になっているため それはこの質問とは何の関係もありません。
Ykkykk

2021/07/20 09:29

すみません、Unix時間ではなく世界標準時と言っているつもりでした。。。その場合でもlocaltimeで問題ないでしょうか?
otn

2021/07/20 09:42

書き間違いは想定どおりです。 RTCがUTCかどうかは今回は無関係です。 > 回答の意味を理解せずに一部を勝手に書き換えると正しい結果が得られません。 と書いたのですが、回答の意味を理解しようとしてはどうでしょうか。
Ykkykk

2021/07/20 22:09

そうなのですね、、、。ご回答の意図としては、 >1.tm構造体セット >2.mdayだけ+1 >3.mktime >4.localtime というようにして、tm構造体とtime_tの変数を変換しあうことで翌日を導出することだと理解しておりました。そこで、y_waiwaiさんからいただいたコメントでlocaltimeを使用すると日本時間になってしまうという指摘、また、rtcwakeもRTCがUTCの場合かそうでないかで引数が変わることからgmtimeを使用することになるのかな、と思った次第です。すみません。
otn

2021/07/20 23:54

自分でmktimeの仕様を確認していればわかったはずですが、mktimeはローカルタイムで動作するので、戻すときもローカルタイムである必要があります。 上記1~4のどの処理もRTCを参照しないので、RTCは無関係です。
Ykkykk

2021/07/21 00:17

すみません、mktimeについて確認していたサイトでは特にUTCかそうでないかの記述がなかったためわかりませんでした。。。では、上記のmktimeを使用する方法ではUTCでの時間を求めることはできないということですね。 上記がRTCとは別の処理であることは理解していると思っているのですが、上記の処理を通じてローカル時間で求められた時刻をRTCアラームに設定する場合には、さらに別の処理(ローカル時間をUTCに変換する処理?)が必要となるという理解で問題ないでしょうか(この質問の範囲を超えるかと思いますが)。
Ykkykk

2021/07/21 00:32

昨日localtimeとmktimeを使用したソースコードで設定した時刻にレジュームすることができました。私の時間の扱いに関する理解が足りていないことを痛感いたしました。この度はお忙しい中、何度も稚拙なことをお尋ねしてお手間を取らせてしまい、大変申し訳ありませんでした。頂いたご回答はどれも本当に勉強になりました。ありがとうございます。引き続き時間の扱いについて学習したく思います。
otn

2021/07/21 07:17 編集

> 上記の処理を通じてローカル時間で求められた時刻をRTCアラームに設定する場合には、さらに別の処理(ローカル時間をUTCに変換する処理?)が必要となるという理解で問題ないでしょうか 「2021-07-21 12:34 の1日後は何日何時か?」 という計算は、タイムゾーンに依存しないので、 元の前の日時がJSTなら求めた1日後の日時もJSTだし、 元の前の日時がUTCなら求めた1日後の日時もUTCだし。 なので、「上記の処理を通じてローカル時間で求められた時刻」という考えが間違っています。
guest

0

ベストアンサー

こういう場合は、
struct tm
を使うより、
time_t
を使うほうがいいです
#tmから相互変換できます

こいつは通算秒の表現なため、直接比較できますし、1日加算の演算もかんたんにできます

投稿2021/07/20 01:10

y_waiwai

総合スコア87774

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

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

Ykkykk

2021/07/20 01:31

ご回答ありがとうございます。time_t型で管理して必要に応じてtmなどの構造体に入れていく方が良いのですね。大変参考になりました。ありがとうございます!
y_waiwai

2021/07/20 01:35

で、このとき注意すべきなのが、国際標準時なのか日本標準時なのかってところです。 localtimeなんちゃらの関数を使うと、その地域の標準時となります
Ykkykk

2021/07/20 01:40

ありがとうございます!RTCがUnix時間なため、できればUnix時間で管理したいと思っておりました。さっと調べたところ、gmtimeという関数を使えばtm構造体をUnix時間で埋められるのですね。こちらのコメントも大変参考になりました。本当にありがとうございます!
guest

0

翌日にしたい場合、time_t型の *wakeup に 24x60x60 を足して localtime_r をすればいいかと

投稿2021/07/20 01:09

sigsegv

総合スコア895

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

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

Ykkykk

2021/07/20 01:30

ご回答いただきありがとうございます。そもそもtime_t型を使えば良いということですね。。。完全に頭が詰まってしまっていたので、助かりました。ありがとうございます!
guest

0

ふたつの時分秒の大小を比較したいだけなら
両者の (時x60+分)x60+秒 を比較すればいいんじゃないかと...

投稿2021/07/20 01:17

episteme

総合スコア16614

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問