A thread titled A renewed plea for inclusion of zone.tab offers some explanation of what zone.tab
is used for.
Its main use seems to be to show a map of cities and their locations, to allow a user to pick their timezone by clicking on a city near them.
With that in mind, it doesn't need to know all of the aliases for each city, knowing one preferred way of referring to it is sufficient. (But it looks like it always includes at least one city in each country.)
The other aliases for each zone are stored in the tzdata source code.
For example, the backward
file has
Link Asia/Kolkata Asia/Calcutta
so that people can use the new spelling or the old spelling.
All the other files in /usr/share/zoneinfo
are generated from this source code using zic
.
But there's not 600+ aliases, so why the big difference?
There's usually three versions of each timezone generated: posix
, right
, and your system's default.
$ cd /usr/share/zoneinfo
$ find right -type f | wc -l
581
$ find posix -type f | wc -l
581
$ find . \( -name posix -o -name right \) -prune -o -type f | wc -l
586
The tzcode Makefile
shows how those are generated, and mentions the reason for them: posix
ignores leap seconds, right
includes them.
See also:
The file system doesn't give you a time with timezone, it's whatever command that you use to display that time in a human friendly format that may give you a timezone if it chooses to display the time in local time (as specified by /etc/localtime
, $TZ
or other).
Generally, timestamps on Unix are expressed in a way that is irrelevant of timezones. The unix epoch time is the number of seconds (seconds expressed as the 86400th part of a day, so varying in length but more useful for calendar calculation) since a precise event in history (1970-01-01 00:00:00 UTC, an unambiguous time). Timezones only come into the picture when displaying a date in a calendar format to a human.
ps -o lstart= -p "$pid"
date -r /some/file
both give you the local time. date
might output the timezone offset or not depending on the locale. If you want the UTC time, run them under TZ=UTC0
:
TZ=UTC0 ps -o lstart= -p "$pid"
TZ-UTC0 date -r /some/file # or use date -u
GNU date
is able to parse the date reported by ps
, so you can convert it to any format, like the unix epoch time:
(export TZ=UTC0
date -d "$(ps -o lstart -p "$pid") +%s
date -r /some/file +%s)
(above using UTC time. It would also work with whatever the local time is in your environment except for one hour in the year where a time output without TZ indication is ambiguous (in zones that implement DST)).
In any case, the start time of a process doesn't have to be (and never is exactly) the time that process executed the command it is currently running. For instance:
$ TZ=UTC0 strace -qtt -e execve sh -c 'sleep 3; exec env ps -o lstart= -p "$$"'
10:27:24.877397 execve("/bin/sh", ["sh", "-c", "sleep 3; exec env ps -o lstart= "...], [/* 28 vars */]) = 0
10:27:27.882553 execve("/usr/bin/env", ["env", "ps", "-o", "lstart=", "-p", "9397"], [/* 28 vars */]) = 0
10:27:27.885272 execve("/bin/ps", ["ps", "-o", "lstart=", "-p", "9397"], [/* 28 vars */]) = 0
Fri May 5 10:27:24 2017
That 9397 process is running 4 commands in its life time: strace
(forked there), sh
, env
, ps
. The time reported by ps
corresponds to the time when it was forked by strace
, not when it executed ps
.
If you want to get subsecond precision (up to 1/$(getconf CLK_TCK)
), with zsh
, you could do:
zmodload zsh/datetime
tick=$(getconf CLK_TCK)
(echo $((EPOCHREALTIME + (${${=$(</proc/self/stat)##*)}[20]}. -
${${=$(</proc/$pid/stat)##*)}[20]})/tick)))
That is we get the start time of the $pid and of a newly created subshell (that's the 20th fields after the last occurrence of a )
character in /proc/pid/stat
expressed in CLK_TCK in modern versions of Linux), divide the difference by CLK_TCK
and add to the current time.
Best Answer
In this comment by Stéphane Chazelas, he said:
Based on this and tonioc's comment, I put together the following: