我收到以下错误
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