Bash 将字符串转换为时间戳

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26432050/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 11:35:19  来源:igfitidea点击:

Bash convert string to timestamp

bashsh

提问by user3979986

I have a string in format 20141225093000which represents Dec 25, 2014 09:30:00and I want to convert the original format to a unix timestamp format so i can do time operations on it.How would I do this in bash?

我有一个20141225093000表示格式的字符串,Dec 25, 2014 09:30:00我想将原始格式转换为 unix 时间戳格式,以便我可以对其进行时间操作。我将如何在 bash 中执行此操作?

I can easily parse out the values with exprbut I was hoping to be able to identify a format like YYYYmmddHHMMSS and then convert it based on that.

我可以轻松地解析出这些值,expr但我希望能够识别像 YYYYmmddHHMMSS 这样的格式,然后根据它进行转换。

回答by Charles Duffy

With GNU date, you can convert YYYY-MM-DDTHH:MM:SSto epoch time (seconds since 1-1-1970) easily, like so:

使用 GNU 日期,您可以轻松转换YYYY-MM-DDTHH:MM:SS为纪元时间(自 1-1-1970 以来的秒数),如下所示:

date -d '2014-12-25T09:30:00' +%s

To do this starting without any delimiters:

要在没有任何分隔符的情况下执行此操作:

in=20141225093000
rfc_form="${in:0:4}-${in:4:2}-${in:6:2}T${in:8:2}:${in:10:2}:${in:12:2}"
epoch_time=$(date -d "$rfc_form" +%s)

回答by Tiago Lopo

You need to transform the string before calling date:

您需要在调用之前转换字符串date

#!/bin/bash

s="20141225093000"
s=$(perl -pe 's/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/-- ::/g' <<< "$s")
date -d "$s" +%s

Yet another way:

还有一种方式:

perl -MDate::Parse -MPOSIX -le '$s="20141225093000"; $s =~ s/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/-- ::/g ; print str2time($s);'
1419499800

回答by glenn Hymanman

GNU awk:

GNU awk:

gawk -v t=20141225093000 'BEGIN {gsub(/../, "& ", t); sub(/ /,"",t); print mktime(t)}'

If GNU date is not available, then it's likely GNU awk may not be. Perl probably has the highest chance of being available. This snippet uses strptimeso you don't have to parse the time string at all:

如果 GNU 日期不可用,则很可能 GNU awk 不可用。Perl 可能有最高的可用机会。使用此代码段strptime,您根本不必解析时间字符串:

perl -MTime::Piece -E 'say Time::Piece->strptime(shift, "%Y%m%d%H%M%S")->epoch' 20141225093000

回答by pjh

This Bash function does the conversion with builtins:

这个 Bash 函数使用内置函数进行转换:

# Convert UTC datetime string (YYYY-MM-DD hh:mm:ss) to Unix epoch seconds
function ymdhms_to_epoch
{
    local -r ymdhms=${1//[!0-9]}    # Remove non-digits

    if (( ${#ymdhms} != 14 )) ; then
        echo "error - '$ymdhms' is not a valid datetime" >&2
        return 1
    fi

    # Extract datetime components, possibly with leading zeros
    local -r year=${ymdhms:0:4}
    local -r month_z=${ymdhms:4:2}
    local -r day_z=${ymdhms:6:2}
    local -r hour_z=${ymdhms:8:2}
    local -r minute_z=${ymdhms:10:2}
    local -r second_z=${ymdhms:12:2}

    # Remove leading zeros from datetime components to prevent them
    # being treated as octal values
    local -r month=${month_z#0}
    local -r day=${day_z#0}
    local -r hour=${hour_z#0}
    local -r minute=${minute_z#0}
    local -r second=${second_z#0}

    # Calculate Julian Day Number (jdn)
    # (See <http://en.wikipedia.org/wiki/Julian_day>, Calculation)
    local -r -i a='(14-month)/12'
    local -r -i y=year+4800-a
    local -r -i m=month+12*a-3
    local -r -i jdn='day+(153*m+2)/5+365*y+(y/4)-(y/100)+(y/400)-32045'

    # Calculate days since the Unix epoch (1 Jan. 1970)
    local -r -i epoch_days=jdn-2440588

    local -r -i epoch_seconds='((epoch_days*24+hour)*60+minute)*60+second'

    echo $epoch_seconds

    return 0
}

Example usage:

用法示例:

$ ymdhms_to_epoch '1970-01-01 00:00:00'
0
$ ymdhms_to_epoch '2014-10-18 00:10:06'
1413591006
$ ymdhms_to_epoch '2014-12-25 09:30:00'
1419499800