shell date学习以及正确获取时间戳的姿势

最好的方法

2020.05.08

# 毫秒时间戳
date +%s%3N
# 微秒时间戳(不确定是否精确)
date +%s%6N

获取时间戳

  1. 获取从1970-01-01 00:00:00 UTC到现在的秒数
cur_sec=`date '+%s'`
  1. 获取纳秒
cur_ns=`date '+%N'`
  1. 合并为时间戳
cur_timestamp=$((`date '+%s'`*1000+`date '+%N'`/1000000))

重点

  1. 我在获取时间戳的时间是没有将第一二步的字符串放入到第三步中的,因为第一二步分别是两次获取两个时间的不同部分。第一步先获取了时间A的秒数,第二步获取了时间A后面某个时间B的纳秒,然后合并到第三步必然导致比第三步更大的误差。

代码如下:

cur_sec_and_ns=`date '+%s-%N'`
Ncur_ns=`date '+%N'`
cur_sec=${cur_sec_and_ns%-*}
cur_ns=${cur_sec_and_ns##*-}
cur_timestamp=$((cur_sec*1000+cur_ns/1000000))
timestamp2=$((cur_sec*1000+Ncur_ns/1000000))
echo 当前秒_纳秒=$cur_sec_and_ns
echo 当前秒=$cur_sec
echo 当前纳秒=$cur_ns
echo 第二次获取的纳秒=$Ncur_ns
echo 当前时间戳=$cur_timestamp
echo 分开获取的时间戳=$timestamp2

如图:

shell echo 时间 shell加时间戳_date


通过结果可以看出分别获取秒数和纳秒,将导致时间戳有1的误差。

所以,既然使用了时间戳,那么请不要分两次获取秒、纳秒。

选项

  1. -d,–date=STRING
    STRING格式中年月日(2018年12月18日)为2018-12-11、2018/12/11、12/11/2018等,12-11-2018、12/2018/11等不合法。时分秒格式(12时48分41秒)为12:48:41。
  2. –debug
    查看具体的解析过程,可以看出12/11/2018格式不是最好的格式,会出现warning。

最好的格式是2018-12-11。

shell echo 时间 shell加时间戳_shell echo 时间_02

  1. -f,–file
    指定文件解析时间,文件的某一行如果不符合date格式,不影响后续的解析。
  2. -I[FMT],–iso-8601=[FMT]
    FMT有date、hours、minutes、seconds、ns。默认使用date。支持缩写,如hours=hour=h。[FMT]在zsh中可以补全。
  3. -R,–rfc-email
    输出格式为RFC 5322格式的日期。
  4. –rfc-3339=[FMT]
    输出格式为RFC 3339格式的日期。
  5. -r,–reference=FILE
    输出FILE上一次修改的时间。
  6. -s,–set=STRING
    设置系统时间。
  7. -u,–utc,–universal
    输出UTC格式的时间。
  8. –version
  9. 通过FORMAT控制输出。

符号

意义

%%

%的转义

%a

当地星期几的缩写,例如Sun、日

%A

当地星期几的全称,例如Sunday、星期二

%b

当地月份的缩写,例如Jan、12月

%B

当地月份的全称,例如January、十二月

%c

当地日期和时间,例如Thu Mar 3 23:05:25 2005,2018年12月18日 星期二 15时46分23秒

%C

输出世纪,例如现在是2

%d

当前月份的第几天,例如18(2018-12-18)

%D

日期,格式与%m%d%y,年为两位数,例如12/18/18

%e

当前月份的第几天,例如08(2018-12-08)

%F

完整格式的日期,与%Y-%m-%d相同,例如2018-12-18

%g

年份中的后两位数,例如18

%G


%h

与%b一样

%H

小时(00…23)

%I

小时(01…12)

%j

一年中的第几天(001…366)

%k

小时(1…23)

%l

小时(1…12)

%m

月(01…12)

%M

分(01…59)

%n

新行

%N

纳秒(000000000…999999999)

%p

当地上午或下午,例如PM、下午

%P

当地上午或下午(小写),例如pm、下午

%q

第几季(1…4)

%r

当地12小时制的时间格式,例如下午 04时06分24秒

%R

24小时制的时分(%H:%M),例如16:07

%s

从1970-01-01 00:00:00 UTC到现在的秒数

%S

当前分钟的秒数(00…59)

%T

格式为%H:%M:%S,时分秒

%u

从星期一开始数,一周中的第几天(1…7)

%U

从星期日开始数,一年中的第几周(00…53)

%V

ISO周数,从周一开始数(01…53)

%w

从周日开始数,一周中的第几天(0…6)

%W

从星期一开始数,一年中的第几周(00…53)

%x

当地日期,例如2018年12月18日

%X

当地时间,例如16时16分17秒

%y

年份的后两位数(00…99)

%Y

年份

%z

时区,+hhmm,例如东八区+0800

%: z(不能有空格,因为会转义为笑脸才有)

时区,+hh::mm,例如东八区+08:00

%:: z

时区,+hh::mm:ss,例如东八区+08:00:00

%Z

时区的缩写,例如东八区CST