将格式“%d/%m/%Y %H:%M”的日期转换为秒

将格式“%d/%m/%Y %H:%M”的日期转换为秒

我收到以下错误

date: invalid date '23/07/2021 14:44'

运行此代码时

start="23/07/2021 14:44"
startSec=`date +%s -d "${start}"`

我也尝试过

start="23/07/2021 14:44"
startSec=`date -d "${start}" +%s`

如何将字符串日期 ($start) 格式为 '%d/%m/%Y %H:%M',然后将其转换为秒?

谢谢。

答案1

您可以使用字符串操作将输入强制转换为date.

或者,在 perl 中您必须指定确切的输入格式。

start='23/07/2021 14:44'
perl -MTime::Piece -sE '
    say Time::Piece->strptime($input, "%d/%m/%Y %H:%M")->epoch
' -- -input="$start"
1627051440

字符串操作:我用来read将字符串分解为变量,使用字符$IFS作为字段终止符:

start='23/07/2021 14:44'
IFS='/ ' read -r day month year time <<<"$start"
date -d "$year-$month-$day $time"
Fri Jul 23 14:44:00 EDT 2021

这有一个 bashism,即<<<此处字符串重定向。对于更多 POSIX shell:

IFS='/ ' read -r day month year time <<END_START
$start
END_START

答案2

-d选项不是 的标准选项date,并且 标准date规格没有规定以一种格式获取日期并将其重新格式化为另一种格式。

BSD、GNU、ast-open 和 busyboxdate都有这方面的选项,但具有不同的语法和 4,GNU date,您似乎正在使用给定错误消息的措辞,是唯一一个您无法指定输入格式。

所以你不能独自完成你所要求的便携式任务date

在这里,除了诉诸适当的编程语言(例如perl/ python/ tcl...)之外,您还可以从bash具有zsh内置接口的语言切换到strptime()

$ zmodload zsh/datetime
$ start='23/07/2021 14:44'
$ strftime -r '%d/%m/%Y %H:%M' $start
1627047840

这为您提供了该日期的纪元时间,解释为当地时间(对我来说,欧洲/伦敦时间)14:44:00。如果该时间戳采用 UTC 时间,则更改为:

$ TZ=UTC0 strftime -r '%d/%m/%Y %H:%M' $start
1627051440

要存储到标量变量中,您可以使用该-s选项。

$ strftime -s startSec -r '%d/%m/%Y %H:%M' $start
$ echo $startSec
1627047840

ksh93 shell 还可以使用其printf内置函数(或者它的date内置函数,如果它是作为 ast-open 的一部分构建的,尽管现在这种情况很少见)来解析日期,尽管指定输入格式有点麻烦,因为您需要存储使用变量指定的文件中的格式列表$DATEMSK(对于 standard getdate()),尽管在带有 的系统上/dev/fd/x,您可以执行以下操作:

$ { DATEMSK=/dev/fd/3 printf '%(%s)T\n' "$start"; } 3<<< '%d/%m/%Y %H:%M'
1627047840

(如果没有我的 ksh93 版本(来自 Ubuntu 20.04 ksh 软件包)的命令组,它就无法工作,显然在较新版本中修复了一个错误https://github.com/ksh93/ksh)。

请注意,虽然23/07/2021 14:44您所在时区的本地时间很可能是明确的,但采用该时间戳格式,如果您的时区实施 DST,则可能会出现不明确的情况。

例如,在我的欧洲/伦敦时区中,有两个可能的 Unix 纪元时间对应于25/10/2020 01:30

$ strftime '%d/%m/%Y %H:%M' 1603585800
25/10/2020 01:30
$ strftime '%d/%m/%Y %H:%M' 1603589400
25/10/2020 01:30

在我的系统上,zsh strftime -r(系统的strptime())选择后者:

$ strftime -r '%d/%m/%Y %H:%M' '25/10/2020 01:30'
1603589400

答案3

GNU 日期(和其他)无法接受您想要的格式的日期字符串。它主要接受美国日期格式。

要具有可变格式,最简单的解决方案是使用,只需在选项中busybox date告知格式(您已经拥有:):%d/%m/%Y %H:%M-D

$ busybox date -u +%s -D '%d/%m/%Y' -d "23/07/2021"
1626998400

最好包含-u( utc) 选项,这样答案就是给定的精确时间(以秒为单位),而不是当地时间的模糊结果。当地时间是模糊由于夏令时、意外的时间变化等。

还有一些其他日期实现可以接受可变日期字符串格式 (BSD)。但 busybox 是一个非常小的可执行文件,而且非常有用,因为它可以替代许多实用程序。

答案4

既然你有 GNU date,你也有或可以获得 GNU awk:

$ start="23/07/2021 14:44"
$ awk -v start="$start" 'BEGIN{split(start,d,"[/ :]"); print mktime(d[3]" "d[2]" "d[1]" "d[4]" "d[5]" 0")}'
1627069440

上面使用您的 TZ 设置,或者对于 UTC,您可以在 mktime() 中设置 UTC 标志:

$ awk -v start="$start" 'BEGIN{split(start,d,"[/ :]"); print mktime(d[3]" "d[2]" "d[1]" "d[4]" "d[5]" 0",1)}'
1627051440

相关内容