月が相対日付で終わると、atはどのように機能しますか?

月が相対日付で終わると、atはどのように機能しますか?

1月31日に使用するとどのような性能を発揮しますかat midnight next month? 3月4日ですか、それとも2月28日ですか?それとも3月31日ですか?

答え1

この回答の目的は、既に受け取った他の(正しい)回答を補完し、いくつかの追加の技術情報を提供することです。

atコマンドがコマンドを受信したときNEXT <inc_dec_period>1、現在の日付を時間構造として使用する(struct tm2指定した期間に「1」を追加します。

したがって、atコマンドが実行されるとNEXT MONTH、現在の日付を使用して3月に「1」を追加して、0(1月)が1(2月)になり、1が2(3月)になるようになります。これはdate -d 'now + 1 month'コマンドと同じです。

今重要な部分は次のdateとおりです。atその後、コマンドは、操作後に生成された新しい時間構造を取得し、mktime(3)新しい絶対時間4を返すライブラリ呼び出しの引数として使用します。mktime(3)文書には次のように記載されています。

このmktime()機能が修正されました。Tm値2構造は次のとおりです。 [...]構造メンバーが有効範囲外になると正規化されます(たとえば、10月40日が11月9日に変更されます)。);

たとえば、次のようになります。

  • 現在の日付が2023-08-31の場合、
  • コマンドはnext month
  • 新しい時間構造は2023年9月31日です。

31は9月の有効な間隔を超えているため、文書に記載されているように2023年10月1日に正規化されます。

$ date -d '2023-08-31 + 1 month' --rfc-3339=date
2023-10-01

現在の日付が2023-01-31の場合、同じコマンドの結果atは時間構造2023-02-31であり、これは2023-03-03に正規化されます。

$ date -d '2023-01-31 + 1 month' --rfc-3339=date
2023-03-03
$ date -d '2024-01-31 + 1 month' --rfc-3339=date # leap year
2024-03-02

1か所inc_dec_period次のいずれかです。

MINUTE | HOUR | DAY | WEEK | MONTH | YEAR

2tm構造には、少なくとも次のメンバーが含まれます。

int    tm_sec   seconds [0,61]
int    tm_min   minutes [0,59]
int    tm_hour  hour [0,23]
int    tm_mday  day of month [1,31]
int    tm_mon   month of year [0,11]
int    tm_year  years since 1900
int    tm_wday  day of week [0,6] (Sunday = 0)
int    tm_yday  day of year [0,365]
int    tm_isdst daylight savings flag

3月の結果が11より大きい場合、年フィールドも1ずつ増加します。

4カレンダー時間を表すデータ型を返しますmktimetime_t絶対時間値として解釈した場合、epoch 1970-01-01 00:00:00 +0000(UTC)から経過した秒数を示します。

答え2

3月3日

「次の月」とは、同じ数字で1ヶ月前に移動することを意味します。したがって、1月31日から始まる「次の月」は2月31日ですが、これは(指で数える... 29、30、31)3月3日と同じです。うるう年なら3月2日だ。同様に、3月31日+月は5月1日です。なぜなら、4月31日は4月末で一日だけ休むからです。

# date --set '2023-01-31 12:00'
Tue Jan 31 12:00:00 PM UTC 2023
# date
Tue Jan 31 12:00:00 PM UTC 2023
# at midnight next month
warning: commands will be executed using /bin/sh
at Fri Mar  3 00:00:00 2023
at> echo foo
at> <EOT>
job 2 at Fri Mar  3 00:00:00 2023

同様にdate:

# date -d 'now + 1 month'
Fri Mar  3 12:01:32 PM UTC 2023

とにかく、これは私のUbuntuシステムで動作する方法です。

答え3

現在の日付から翌月の最終日を取得するには、現在のdate日付を現在の月の終わりから離れて(追加月を超えないように)、2ヶ月をdate再びジャンプし、dayから01まで、Go back one dayを持ちます。一方通行距離。

編集:最初のリリースでは、翌月が現在の月より短い4つの日付(12月29〜31日と7月31日)に失敗しました。

$ date  # To show where we are now.
Tue 29 Aug 16:29:44 BST 2023
$ echo | at "$( date -d "$( date '+%Y-%m-15' ) + 2 months" '+%Y-%m-01') - 1 day"
warning: commands will be executed using /bin/sh
job 73 at Sat Sep 30 16:29:00 2023
$ atq
73  Sat Sep 30 16:29:00 2023 a paul

%wこのアイデアのいくつかの拡張は、(曜日)オプションを使用して(たとえば)日付を毎月最後の金曜日に移動できることです。

関連情報