我怎样才能使`date`输出不同时区的时间?


115

我有一个时区设置为的服务器UTC。看来这通常是个好习惯(如果我错了,请纠正我)。

无论如何,我连接到的其中一台服务器要scp运行文件,并且正在运行,EDT并以以下格式存储需要复制的文件/path/to/filename/data20120913

我看过尝试rsync使用诸如find的-mtime -1标志之类的文件来归档最后一天修改过的文件,但是我没有任何运气。

我不介意仅scp用于复制当天的文件,但截至目前为止,有一个4小时的窗口,在date +%Y%m%d该窗口中运行将给每台服务器提供不同的日期,这给我带来了一些麻烦。

翻阅man date一下,我看到可以将时间输出为UTC,但是我没有看到一种将时间输出为另一个时区的方法,例如EDT

我想我也可以使用GNU日期扩展名之类的东西date -d 20100909 +%s从纪元获取秒数的日期,进行手动4 * 60 * 60第二次计算,然后将其渲染为日期,但是当日光时间到来时,仍然需要一个小时。

是否有一种更简单的方法来以设置为的服务器上的YYYYMMDD格式输出日期?EDTUTC


至少在Linux中,EDT不是公认的时区。看到我的“小心!” 以下是整个丑闻的答案。如果您的* NIX品牌使用EDT,则仍应谨慎行事,并仔细检查您的时区字符串。
Mike S

Answers:


175

您可以在查询期间设置时区,从而:

TZ=America/New_York date

请注意TZ设置和date命令之间的空格。在类似Bourne和类似Bourne的rc外壳程序中,TZ仅为命令行设置变量。在其他炮弹(cshtcshfish),你总是可以使用env命令:

env TZ=America/New_York date

tl; dr

在Linux系统上。时区在/usr/share/zoneinfo目录的文件中定义。为了纪念其创建者,通常将这种结构称为“ Olson数据库”。

每个时区的规则都定义为文本文件行,然后将其编译为二进制文件。这样编译的行定义了区域名称;该区域适用的一系列数据和时间;在标准时间内偏离UTC的时间;以及用于定义如何往返夏时制的符号(如果适用)。

例如,目录“ America”在America/New_York上面使用的文件中包含纽约的必要信息。

注意,不存在的区域(文件名)的规范将被忽略,并且会报告UTC时间。例如,这报告了错误的时间:

TZ="America/New York" date ### WRONG ###

单一UNIX规范版本3(称为SUSv3或POSIX-2001)指出,为了可移植性,标识时区描述的字符串应以冒号开头。因此,我们也可以这样写:

TZ=":America/New_York" date
TZ=":America/Los_Angeles" date

作为使用描述文件路径名的时区指定的一种替代方法,SUSv3描述了POSIX模型。以这种格式,字符串定义为:

std offset [dst[offset][,start-date[/time],end-date[/time]]]

其中std,标准组件名称dst是夏令时名称。每个名称包含三个或更多字符。该offset是积极的时区本初子午线以西负的经络是东亚。将偏移量添加到本地时间以获得UTC(以前称为GMT)。的startend标准的/日光转换发生时的时间字段指示。

例如,在美国东部,标准时间比UTC早5小时,我们可以指定EST5EDT代替America/New_York。但是,这些替代方法并不总是被认可,尤其是对于美国以外的地区,最好避免使用。

HP-UX(与SUSv3兼容的UNIX)使用文本规则,/usr/lib/tztab并且使用POSIX名称(例如EST5EDT,CST6CDT,MST7MDT,PST8PDT)。该文件包含每个时区的所有历史规则,类似于Olson数据库。

注意:您应该可以通过检查以下目录找到所有时区:/usr/share/zoneinfo


不确定我是否做错了,但export看起来比env命令要好
签署

@JRFerguson-如果列表中未包含时区,例如拉斯维加斯或内华达州,验证时间的替代方法有哪些?
推动下

@Motivated如果不包括您的城市或州,请选择使用与您相同的区域信息的城市或州。例如,我在佛罗里达州,使用与纽约相同的时区,因此我的机器与纽约时间同步。
JRFerguson

1
@JRFerguson-假设此人知道各个时区,并且可以使用其他方式(例如纽约)。那是唯一的选择吗?例如,我不住在欧洲,也不知道重叠的时区。
启发

1
@Motivated您可以使用本网站之类的内容来帮助您查找区域中的其他点。
JRFerguson

33

您可以通过操作TZ环境变量来做到这一点。下面将为您提供美国/东部时间的本地时间,这也足够聪明,可以处理DST发生的DST:

# all on one line
TZ=":US/Eastern" date +%Y%m%d

区域名称来自其中的文件和目录/usr/share/zoneinfo


17

小心!如果您给它指定了一个无法识别的时区,那么日期会很高兴地吐出当前时区中的时间。

看一下这个:

-bash-4.2$ env TZ=EDT date
Wed Feb 18 19:34:41 EDT 2015
-bash-4.2$ date
Wed Feb 18 19:34:43 UTC 2015

请注意,没有时区称为EDT。事实上,

-bash-4.2$ find /usr/share/zoneinfo -name "*EDT*"

退货

/usr/share/zoneinfo/EST5EDT
/usr/share/zoneinfo/posix/EST5EDT
/usr/share/zoneinfo/right/EST5EDT

这有效:

-bash-4.2$ TZ=EST5EDT date
Wed Feb 18 14:36:59 EST 2015
-bash-4.2$ date
Wed Feb 18 19:37:01 UTC 2015

但是,如果您的朋友居住在Gobbledygook的神秘土地上,并且其区域信息与您自己的区域一致,那么您可以在Gobbledygook的区域中输出日期的时间,并且很高兴使用nary的退出值来通知您,未知的区域:

-bash-4.2$ TZ=Gobbledygook date
Wed Feb 18 19:37:36 Gobbledygook 2015
-bash-4.2$ echo $?
0

YMMV:在我的MacOS / BSD机器上,格式错误的TZ字符串返回UTC时间。
Mark Hudson

8
TODAY=$(TZ=":US/Eastern" date)
echo $TODAY

6

日期语法是神秘且容易出错的,这使得一个命令行调用一个痛苦。因此,我编写了一个小脚本(我将其命名为worldtime),该脚本将在其他一些时区中从基准时间zome(您本地的时间)打印指定(或当前)时间,反之亦然。

这里是。调整它以适应您的需求,将其放置在路径中,并使其可执行。

#!/ bin / sh
#
#从其他时区的基准时间打印指定的(或当前)时间
#和相反
#

#要转换的基准时区
TZBASE =欧洲/雅典

#显示的时区
#有关更多名称,请参见/ usr / share / zoneinfo /
TZONES ='UTC America / Los_Angeles America / New_York Europe / London Europe / Paris'

#显示格式
格式='%H:%M(%p)%Z%a%m%b%Y'

如果[“ $ 1”];然后
  time =“ $ 1”
其他
  时间=`日期+%T`
科幻

#在指定输出中显示从指定输入时区开始的时间
# 时区
开演时间()
{
  TZIN = $ 1
  TZOUT = $ 2

  TZ = $ TZOUT日期--date ='TZ =“'$ TZIN'”'“ $ time” +“ $ time $ TZIN是$ TZOUT $ FORMAT”
}

代表$ TZONES中的tz;做
  表演时间$ TZBASE $ tz
做完了

回声

代表$ TZONES中的tz;做
  表演时间$ tz $ TZBASE
做完了


3

通常,您在本地时区有时间戳,需要将其转换为远程tz。可以通过以下方式完成:

TZ=America/Curacao date -d 'Tue Nov 28 00:07:05 MSK 2016'

哪里:

America/Curacao - remote timezone
MSK - local timezone
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.