当月末与相对日期结束时,at 的表现如何?

当月末与相对日期结束时,at 的表现如何?

使用时at midnight next month,1 月 31 日,它会表现如何?是3月4日还是2月28日?还是3月31日?

答案1

此答案的目标是补充您已经收到的其他(正确)答案,并提供一些额外的技术信息。

atcommands获取命令时NEXT <inc_dec_period>1,将当前日期作为时间结构(struct tm2),并且在指定期间加“1”

因此,如果at指示运行NEXT MONTH,它将采用当前日期,并将“1”添加到月份3,以便 0(一月)变为 1(二月),1 变为 2(三月),依此类推。这相当于date -d 'now + 1 month'命令。

现在,这是重要的部分:两者dateat然后,命令获取操作后创建的新时间结构,并将其用作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 返回表示日历时间的mktime数据类型。time_t当解释为绝对时间值时,它表示自纪元 1970-01-01 00:00:00 +0000 (UTC) 以来经过的秒数。

答案2

3 月 3 日。

“下个月”的意思是前进一个月,到相同数字的那一天。所以从 1 月 31 日开始,“下个月”就是 2 月 31 日,但这相当于(用手指数...29、30、31)3 月 3 日。如果是闰年,则为 3 月 2 日。同样,3 月 31 日+一个月就是 5 月 1 日,因为 4 月 31 日距离 4 月底只有 1 天休息日。

# 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强制当前日期远离本月的结束日期(以避免超出额外的一个月),date再次跳转两个月,将天数设置为 01 ,并有一天回去。这是一条单行线。

编辑:发布的第一个版本在四个日期失败,其中下一个月比当前的短: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(星期几)选项将日期转移到该月的最后一个星期五(例如)。

相关内容