功能简述
打印和设置系统日期时间
常用命令
将从 EPOCH 时间(1970-01-01 UTC)开始的秒数转化为日期:
date --date='@2147483647'
显示美国西海岸的时间(使用tzselect(1)来查找TZ):
TZ='America/Los_Angeles' date
显示本地下个星期五上午九点时在美国西海岸时间:
date --date='TZ="America/Los_Angeles" 09:00 next Fri'
打印两天前的时间:
date --date='2 days ago'
打印三个月零一天后的日期:
date --date='3 months 1 day'
将系统时间设置为当前时间的两分钟后:
date --set='+2 minutes'
扩展:在 BASH 中,比较两个时间的大小:
[[ "2014-12-01T21:34:03+02:00" < "2014-12-01T21:35:03+02:00" ]]
语法格式
date [OPTION]... [+FORMAT] date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
命令描述
使用 FORMAT 指定的格式显示当前的系统时间,或者设置系统时间。
调用没有FORMAT参数的date等价于使用默认格式调用它,默认格式依赖于语言环境LC_TIME的类别。在默认的C语言环境中,这种格式是’+%a %b %e %H:%M:%S %Z %Y’,所以输出看起来像’Thu Mar 3 13:47:51 PST 2005’。
通常,date使用环境变量TZ暗指的时区规则,或者如果未设置TZ,则使用系统默认规则。请参阅GNU C库参考手册中的「使用TZ指定时区」。
如果给定以“+”开头的FORMAT参数,date将以FORMAT定义的格式来打印当前日期和时间,或者以FORMAT定义的格式来打印–date选项指定的日期和时间(参见下文),该格式FORMAT类似于strftime(3)函数。除了以’%’开头的转换说明符以外,FORMAT中的其他字符会直接输出。
命令选项
如果没有特殊说明,以下选项中,长选项需要提供参数在使用短选项时也要提供。
-d, –date=STRING
显示STRING字符串表示的日期,而不是当前时间。
例如下面的命令及命令输出:
# date -d 'Wednesday 03 May 2017' +"%Y-%m-%d" 2017-05-03
所以该选项可以用来在SHELL中格式化时间。下面的这条命令中sed与date配合来处理日期格式问题:
# find ./* -type f -name '*.txt' -print0 | xargs -i -0 sed -E 's/^更新日期:(.*)/date +更新日期:%Y年%m月%d日 -d "\1"/eg' '{}'
有关STRING的格式参考日期字符串格式。
–debug
注释解析日期,显示有效时区,并警告可能的滥用情况。
-f, –file=DATEFILE
类似于使用-d选项,解析DATEFILE中的每一行日期,并显示结果日期和时间。如果DATEFILE是’-‘,则使用标准输入。当你有很多日期需要处理时,这很有用,因为多次启动date命令的系统开销可能相当大。
-I[FMT], –iso-8601[=FMT]
使用ISO 8601格式显示日期,‘%Y-%m-%d’。参数FMT指定要包含的附加条目数量。它可以是以下之一:
‘hours’,附加显示小时,追加在日期的后面。
‘minutes’,附加显示小时、分钟。
‘seconds’,附加显示小时、分钟、秒。
‘ns’,附加显示小时、分钟、秒、纳秒。
如果显示任何时间条目,则使用格式’%:z’来包含时区。无论当前的语言环境如何,此格式始终适用于–date(-d)和–file(-f)选项的输入。
-R, –rfc-2822
使用‘%a, %d %b %Y %H:%M:%S %z’格式来显示日期和时间。因为在C语言环境中评估,所以缩写总是英文的。例如Fri, 09 Sep 2005 13:51:39 -0700。
这种格式符合互联网RFC 5322,822,822,即互联网电子邮件的当前和以前的标准。为了与旧版本的日期兼容,–rfc-2822和–rfc-822是–rfc-email的别名。
–rfc-3339=FMT
使用由Internet RFC 3339指定的格式显示日期。这与–iso-8601类似,区别在于使用空格而不是“T”将日期与时间分开。无论当前的语言环境如何,此格式始终适用于–date(-d)和–file(-f)选项的输入。
参数FMT指定包含多少个时间元素。它可以是以下之一:
‘seconds’,以空格分隔完整的日期和完整的时间,例如‘2005-09-14 00:56:06+05:30’。输出以数字类型的时间偏移结束;这里的‘+05:30’表示当地时间是UTC以东5小时30分钟。相当于‘%Y-%m-%d %H:%M:%S%:z’
‘ns’,像“seconds”一样,但也打印纳秒,例如‘2005-09-14 00:56:06.998458565+05:30’。相当于‘%Y-%m-%d %H:%M:%S.%N%:z’
-r, –reference=FILE
显示文件上次修改的日期和时间,而不是当前的日期和时间。
-s, –set=STRING
将日期和时间修改为STRING。参考-d选项,以及下面的「修改系统时间」部分。
-u, –utc, –universal
此选项表示参数中的时间为世界时间。
通过设置TZ环境变量设置为字符串’UTC0’来使用世界时间。UTC代表1960年成立的协调世界时间。由于历史原因,世界时间通常被称为“格林威治标准时间”(GMT)。通常情况下,系统会忽略闰秒,所以系统实现了UTC的近似值,而不是真正的UTC。
–help
显示帮助信息并退出。
–version
显示版本信息并退出。
附加说明
时间转换说明符
与时间相关的日期转换说明符:
‘%H’,小时 (‘00’…‘23’)
‘%I’,小时(‘01’…‘12’)
‘%k’,小时, 前缀空格 (‘ 0’…‘23’);等价于‘%_H’。这是 GNU 扩展。
‘%l’,小时, 前缀空格(‘ 1’…‘12’);等价于‘%_I’。这是 GNU 扩展。
‘%M’,分钟 (‘00’…‘59’)
‘%N’,纳秒 (‘000000000’…‘999999999’)。这是 GNU 扩展。
‘%p’,AM 和 PM。
‘%P’,与‘%p’类似,但是是小写的am和pm。这是 GNU 扩展。
‘%r’,本地的12小时时间(e.g., ‘11:11:04 PM’) 。
‘%R’,24小时的时间和分钟。等同于‘%H:%M’。
‘%s’,自epoch(1970-01-01 00:00:00 UTC)开始的秒数。除非有闰秒支持,否则闰秒不计算在内。示例见 %s-examples 。这是 GNU 扩展。
‘%S’,秒(‘00’…‘60’)。可能为60,如果支持润秒的话。
‘%T’,24小时制的小时、分钟、秒。类似于‘%H:%M:%S’。
‘%X’,区域设置的时间表示(e.g., ‘23:13:48’) 。
‘%z’,显示四位数字的时区,例如’-0600’,’+0530’;如果没有可以确定的时区,则为’–0000’。此值,使用 TZ 环境变量指定的时区规则,反映对应当前时间的数字时区。如果数字偏移量为零并且其缩写以“-”开头,则无法确定时区。时间(以及可选的时区规则)可以由 –date 选项覆盖。
‘%:z’,如果没有时区是可确定的,则显示具有’:’的数字时区,例如’-06:00’或’+05:30’或’-00:00’。这是 GNU 扩展。
‘%::z’,如果没有时区是可确定的,则使用数字时区到最近的带有’:’的秒钟(例如,‘-06:00:00’或‘+05:30:00’),或’-00:00:00’。这是 GNU 扩展。
‘%:::z’,带’:’的数字时区,使用最小必要的精度(例如’-06’,’+05:30’或’-04:56:02’);或者如果没有可确定的时区,则为’-00’。这是 GNU 扩展。
‘%Z’,时区的字母缩写(例如,’EDT’);如果没有可确定的时区,则什么也没有。请参阅’%z’了解如何确定时区。
日期转换说明符
‘%a’,语言环境相关的周缩写(e.g., ‘Sun’)
‘%A’,语言环境相关的周,变长(e.g., ‘Sunday’)
‘%b’,语言环境相关的月份缩写(e.g., ‘Jan’)
‘%B’,语言环境相关的月份,变长(e.g., ‘January’)
‘%c’,语言环境相关的日期和时间(e.g., ‘Thu Mar 3 23:05:25 2005’)
‘%C’,世纪,类似于‘%Y’,除了会忽略最后两位。例如, ‘%Y’为’2000’,则’%C’为’20’;’%Y’为’-001’,则’%C’为’-0’。它通常至少有两个字符,但可能更多。
‘%d’,月份中的某天 (e.g., ‘01’)
‘%D’,日期;等同于‘%m/%d/%y’
‘%e’,月份中的某天,前置空格;等同于‘%_d’
‘%F’,ISO 8601格式的完整日期;等同于‘%Y-%m-%d’。对于日期格式来说,这是一个不错的选择,因为它是标准的,并且很容易在年份范围在0000 … 9999的情况下进行排序。
‘%g’,对应于ISO周编号的年份,但没有世纪(范围’00’到’99’)。这与’%y’具有相同的格式和值,但是如果ISO周编号(请参见’%V’)属于上一年或下一年,则使用那年。
‘%G’,对应于ISO周编号的年份。这与’%Y’具有相同的格式和值,但是如果ISO周编号(请参见’%V’)属于上一年或下一年,则使用那年。只有当’%V’也被使用时,它才有用的;例如格式’%G-%m-%d’可能是一个错误,因为它将ISO周数与传统月份和日期结合在一起。
‘%h’,等同于%b。
‘%j’,一年中的第几天(‘001’…‘366’)
‘%m’,月份(‘01’…‘12’)
‘%q’,一年中的季度(‘1’…‘4’)
‘%u’,一周中的第几天(‘1’…‘7’);‘1’对应了周一
‘%U’,一年中的第几个周,周日为一周的第一天(’00’… ’53’)。第一个星期日之前的在新年的日子会被视为第零周。
‘%V’,ISO周数,也就是一年中的第几周,星期一是一周的第一天(’01’… ’53’)。如果包含1月1日的一周在新的一年中有4天或更多天,那么它被认为是第1周;否则,是上一年的第53周,下一周是第01周。(参见ISO 8601标准。)
‘%w’,一周中的第几天(‘0’…‘6’),0对应着周末
‘%W’,一年的周数,周一为一周的第一天(’00’… ’53’)。第一个星期一之前的新年的日子在第00周。
‘%x’,与区域设置有关的日期表示。
‘%y’,年份的最后两位(‘00’…‘99’)
‘%Y’,年。这通常至少有四个字符,但可能更多。’0000’在’0001’之前,’-001’年在’0000’之前。
文字转换说明符
这里介绍的是一些可能会用的转义字符:
‘%%’,代表一个百分号。
‘%n’,代表一个换号符号。
‘%t’,代表一个水平的制表符。
填充字符和其他标志
除非另有说明,否则日期通常用0填充数字字段,因此,例如,数字月份总是以两位数字形式输出,使用了前导0。因为EPOCH秒数(%s)没有被填充,因此没有固定宽度。
填充字符
作为GNU扩展,date在’%’之后识别以下任何可选标志(格式通常是%_X的形式,其中X为上边提到的各种说明符):
‘-’,(连字符)不要追加字段;如果输出是为了更可读的格式,则会非常有用。
‘_’,(下划线)填充空格;如果在输出中需要固定数量的字符,但是使用0又太分散注意力,这将非常有用。
‘0’,(零)填充零;即使转换说明符通常会填充空格,也改为使用0进行填充。
‘^’,如果可能,请使用大写字母。
‘#’,如果可能的话使用相反的大小写字符;通常情况下,大写变小写,小写变大写。
下面是一个示例:
# date +%d/%m -d "Feb 1" 01/02 # date +%-d/%-m -d "Feb 1" 1/2 # date +%_d/%_m -d "Feb 1" 1/ 2
宽度规范
作为GNU扩展,可以使用十进制数字指定字段宽度(如果存在任何标志)。如果输出字段的原始大小小于指定的字符数,则结果将被调整并填充到给定大小。例如,’%9B’在宽度为9的字段的右侧打印调整后的月份名称。如下示例:
01/ 2
修饰符号
可选的标志和宽度规范的后面可以跟着可选的修饰符:
‘E’,为日期和时间使用区域设置的替代表示法。此修饰符适用于‘%c’, ‘%C’, ‘%x’, ‘%X’, ‘%y’, ‘%Y’转换说明符。例如,在日本的语言环境中,’%Ex’可能会产生基于日本帝王统治(?Japanese Emperors)的日期格式。我们实在是没有给这个修饰符找到一个合适的例子:
‘O’,使用语言环境的备用数字符号来表示数字。此修饰符仅适用于数字转换说明符。
如果命令行参数FORMAT支持修饰符,但没有可用的替代表示,则会被忽略。
修改系统时间
如果给定的参数不是以’+’开始,则date会将系统时钟设置为由该参数指定的日期和时间(如下所述)。必须具有适当的权限才能设置系统时钟。请注意,如果要持久化修改时间,需要更新硬件时钟,硬件时间通常不会自动更新。
参数必须完全由数字组成,其含义如下:
‘MM’,月份
‘DD’,月份中第几天
‘hh’,小时
‘mm’,分钟
‘CC’,年份中的前两位(可选参数)
‘YY’,年份中的后两位(可选参数)
‘ss’,秒(可选参数)
请注意,–date和–set选项不能与上述格式的参数一起使用。–universal选项可以与这样的参数一起使用,以指示指定的日期和时间是相对于世界时间,而不是当地时区。
这个功能我们也是摸索了一会,它是这么用的:date “MMDDhhmmCCYYss”。如果要修改时间为06/12/2018 20:09,需要执行下面的命令:
当然还是使用–set选项好一些,但上面的这种方式也可以修改时间。
关于日期字符串的格式
关于–date=STRING,它是一种格式非常自由的人类可读日期字符串格式,比如”Sun, 29 Feb 2004 16:21:42 -0800″、”2004-02-29 16:21:42″、甚至”next Thursday”。日期字符串可能包含指示日历日期、时间、时区、星期几、相对时间、相对日期、数字。
一个空字符串表示一天的开始。
日期字符串格式比本文描述的要复杂得多,但完整描述可以查看info文档,或者「在线date手册」。鉴于其复杂性和多样性,这里就不再展开介绍了,否则成了一篇计算机时间科普文了,以后如果有机会可能会介绍这部分内容。
参考文献
- 查看在线手册:http://www.gnu.org/software/coreutils/date
- man 1 date, version GNU coreutils 8.26
- Date comparison in Bash
- 查看 info 手册:info ‘(coreutils) date invocation’