我有个问题想得到准确的GPS时间。看起来这个问题与代码中使用的命令mktime有关。为了得到正确的GPS时间,我增加了-2小时在协调世界时。
但是这样做的目的是要有一个自动计算GPS时间的代码,而不是以UTC-2的手动更改为例。
输入文件GMT时间(本地时间>3小时)
18/05/21 08:18:29
18/05/21 08:20:25
18/05/21 08:21:02当我运行下面的代码时,会少1小时:
gawk -F'[/: ]' -v ts=$(date -d'01/06/1980' +%s) \
-v lap=18 '{$1="" d=sprintf(20$0);
print mktime(d)+lap-ts }' file结果输出时间(<1小时)
1210922327
1210922443
1210922480当我运行下面的代码,得到准确的GPS时间。
gawk -F'[/: ]' -v ts=$(TZ=UTC-2 date -d'1/6/1980 0:00' +%s) \
-v lap=18 '{$1="" d=sprintf(20$0);
print mktime(d)+lap-ts }' file结果输出全球定位系统时间(准确时间:期望输出)
1210925927
1210926043
1210926080提前感谢
发布于 2018-05-23 15:55:39
您所遇到的大部分与您的系统的时区设置有关。由于夏令时,您的时区移动了一个小时,这导致了差异.这里是一个很好的检测DST的方法。复制它的例子,我们可以显示,对于时区TZ=欧洲/斯德哥尔摩,时区根据日期变化为夏季时间:
$ TZ=Europe/Stockholm date +%Z # CET or CEST depending of when its run
$ TZ=Europe/Stockholm date --date=20170101 +%Z # CET
$ TZ=Europe/Stockholm date --date=20170601 +%Z # CEST
$ TZ=CET date --date=20170101 +%Z # CET
$ TZ=CET date --date=20170601 +%Z # CEST, note that its auto adjusted to CEST因此,它肯定会对世界协调世界时1970-01-01T00:00的时代时间产生影响。使用zdump,我们可以看到DST何时生效:
$ zdump -v /usr/share/zoneinfo/Europe/Stockholm | grep 2018
/usr/share/zoneinfo/Europe/Stockholm Sun Mar 25 00:59:59 2018 UTC = Sun Mar 25 01:59:59 2018 CET isdst=0 gmtoff=3600
/usr/share/zoneinfo/Europe/Stockholm Sun Mar 25 01:00:00 2018 UTC = Sun Mar 25 03:00:00 2018 CEST isdst=1 gmtoff=7200
/usr/share/zoneinfo/Europe/Stockholm Sun Oct 28 00:59:59 2018 UTC = Sun Oct 28 02:59:59 2018 CEST isdst=1 gmtoff=7200
/usr/share/zoneinfo/Europe/Stockholm Sun Oct 28 01:00:00 2018 UTC = Sun Oct 28 02:00:00 2018 CET isdst=0 gmtoff=3600在这个时代,我们可以看到:
$ TZ=Europe/Stockholm date -d "2018-03-25 01:59:59" +%s
1521939599
$ TZ=Europe/Stockholm date -d "2018-03-25 03:00:00" +%s
1521939600
$ TZ=Europe/Stockholm date -d "2018-03-25 02:00:00" +%s
date: invalid date ‘2018-03-25 02:00:00’正如你所看到的,对于TZ=欧洲/斯德哥尔摩来说,时间2018-03-25T02:00:00不存在,另外两个只有1秒的间隔。
摘要,这意味着什么:本质上意味着您的系统会自动补偿DST,除非您的TZ是UTC。这在所有与日期相关的命令中都起作用,比如systime()、date甚至是Awk的mktime()。
awk**:**可以避免DST补偿,因为OP需要GPS-时间,即自1980-01-06T00:00:00以来的总秒数,基本上减去两次。因此,如果两者都在相同的TZ中计算,而没有DST校正,则始终得到正确的结果。有两种方法可以做到这一点:
awk 4.20开始,您可以通过使用UTC标志告诉mktime()假设日期是UTC。(mktime(datespec [, utc-flag ]))
$ awk 'BEGIN { ts = mktime("1980 01 06 00 00 ",1) }{ datespec="20"$0;gsub(//:/“,”,datespec);打印mktime(datespec,1) +领- ts }的lap=18文件
这两个结果都会产生以下输出。
1210925927 1210926043 1210926080
在这两种情况下,您都不需要担心您的系统时区和所有与夏时制有关的杂乱无章的事情。mktime:的部分添加DST条目时,可以告诉系统是否在DST中工作,或者让系统自己计算出来。后者是您要做的,不是想要的。datespec是表单YYYY MM DD HH MM SS [DST]的字符串。这也降低了它:
$ awk 'BEGIN { ts = mktime("1980 01 06 00 0000 0") }{ datespec="20"$0;gsub(//:/ ",“,datespec);打印mktime(datespec”0") + lap }的lap=18文件mktime awk 4.2.0以后的文档:
mktime(datespec [,utc-标志])将
datespec转换为与systime()返回的格式相同的时间戳。它类似于ISO C中同名的函数,参数datespec是表单"YYYY MM DD HH MM SS [DST]"的字符串。字符串由六个或七个数字组成,分别代表整个年份,包括世纪、月1至12、月1至31、一天0至23、0至59分钟、0至60、55和可选日光节约标志。 这些数字的值不一定在指定的范围内;例如,-1小时表示午夜前1小时。假定原点为零度公历,前一年为0,前一年为1 -1 .如果存在utc-flag,且时间为非零或非空,则假定时间位于UTC时区;否则,假定时间位于本地时区。如果DST夏时制标志为正值,则假定时间为夏时制时间;如果为零时,则假定时间为标准时间;如果为负值(默认情况下),mktime()将尝试确定夏时制时间对指定时间是否有效。 如果datespec没有包含足够的元素,或者如果结果时间超出了范围,mktime()将返回-1。
https://stackoverflow.com/questions/50487902
复制相似问题