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

cwd*_*cwd 157 date timezone

我有一个运行时区设置为的服务器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秒计算,然后查看将其渲染为日期 - 但是当夏令时开始时,它仍然需要一个小时.

是否有一种更简单的方法可以在设置YYYYMMDDEDT的服务器上以格式输出日期UTC

JRF*_*son 230

您可以在查询期间设置时区,因此:

TZ=America/New_York date
Run Code Online (Sandbox Code Playgroud)

注意TZ设置和date命令之间的空格。在 Bourne-like 和rc-like shell 中,TZ只为命令行设置变量。在其他 shell ( csh, tcsh, fish) 中,您始终可以使用以下env命令:

env TZ=America/New_York date
Run Code Online (Sandbox Code Playgroud)

tl;博士

在 Linux 系统上。时区在/usr/share/zoneinfo目录中的文件中定义。这种结构通常被称为“Olson 数据库”,以表彰其创始贡献者。

每个时区的规则定义为文本文件行,然后将其编译为二进制文件。如此编译的行,定义区域名称;该区域适用的一系列数据和时间;标准时间与 UTC 的偏移量;以及定义如何转换为夏令时的符号(如果适用)。

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

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

TZ="America/New York" date ### WRONG ###
Run Code Online (Sandbox Code Playgroud)

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

TZ=":America/New_York" date
TZ=":America/Los_Angeles" date
Run Code Online (Sandbox Code Playgroud)

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

std offset [dst[offset][,start-date[/time],end-date[/time]]]
Run Code Online (Sandbox Code Playgroud)

其中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.

  • @JRFerguson - 假设此人了解各种时区,并且能够在您的情况下使用替代方案,例如纽约。那会是唯一的选择吗?例如,我不住在欧洲,我不知道重叠的时区。 (2认同)
  • @Motivated 您可以使用 [本网站](https://www.timeanddate.com/worldclock/) 之类的东西来帮助您找到您所在区域的其他点。 (2认同)
  • @JRFerguson也许你可以。但那应该没有必要。如果没有互联网连接怎么办?如果此人不知道有这样的网站怎么办?如果......这应该没有必要,并且您提出的充其量只是一种解决方法。这不是正确的做法。我并不是说你在幕后黑手,我只是说这不是正确的方式(我希望这是有道理的 - 我累坏了)。 (2认同)

Jam*_*ger 40

您可以通过操作TZ环境变量来做到这一点。以下将为您提供美国/东部的当地时间,当它出现时,它也将足够智能以处理 DST:

# all on one line
TZ=":US/Eastern" date +%Y%m%d
Run Code Online (Sandbox Code Playgroud)

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


Mik*_*e S 24

当心!如果你给它一个它无法识别的时区,Date 会很高兴地吐出你当前时区的时间。

看一下这个:

-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
Run Code Online (Sandbox Code Playgroud)

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

-bash-4.2$ find /usr/share/zoneinfo -name "*EDT*"
Run Code Online (Sandbox Code Playgroud)

返回

/usr/share/zoneinfo/EST5EDT
/usr/share/zoneinfo/posix/EST5EDT
/usr/share/zoneinfo/right/EST5EDT
Run Code Online (Sandbox Code Playgroud)

这有效:

-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
Run Code Online (Sandbox Code Playgroud)

但是,如果您的朋友居住在 Gobbledygook 的神秘之地,并且其区域信息与您自己的一致,则您可以使用 date 输出 Gobbledygook 区域中的时间,并且无需退出值即可让您知道zone 不为它所知:

-bash-4.2$ TZ=Gobbledygook date
Wed Feb 18 19:37:36 Gobbledygook 2015
-bash-4.2$ echo $?
0
Run Code Online (Sandbox Code Playgroud)

  • YMMV:在我的 MacOS/BSD 机器上,格式错误的“TZ”字符串返回 UTC 时间。 (3认同)

小智 12

TODAY=$(TZ=":US/Eastern" date)
echo $TODAY
Run Code Online (Sandbox Code Playgroud)


Dio*_*lis 11

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

这里是。调整它以满足您的需要,将其放入您的路径中,并使其可执行。

#!/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" ] ; 然后
  时间=“$ 1”
别的
  时间=`日期+%T`
菲

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

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

对于 $TZONES 中的 tz ;做
  放映时间 $TZBASE $tz
完毕

回声

对于 $TZONES 中的 tz ;做
  放映时间 $tz $TZBASE
完毕


小智 6

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

TZ=America/Curacao date -d 'Tue Nov 28 00:07:05 MSK 2016'
Run Code Online (Sandbox Code Playgroud)

在哪里:

America/Curacao - remote timezone
MSK - local timezone
Run Code Online (Sandbox Code Playgroud)