【问题标题】:Perl convert YYYYMMDD to 16digit epoch timePerl 将 YYYYMMDD 转换为 16 位纪元时间
【发布时间】:2016-05-31 04:02:00
【问题描述】:

是否有将 YYYYMMDD 转换为 16 位纪元时间的 perl 函数?

我目前正在调用日期命令:

date -d 20160219 +%s%6N

对于转换,但我的脚本需要很长时间才能遍历数据集中的数百万个日期。

“16 位纪元时间”是指一个 16 位十进制整数,表示自纪元以来的微秒。比如2016-02-19 00:00:00 UTC是纪元后1455840000秒,所以我想要的结果是"1455840000000000"

【问题讨论】:

  • 你知道我怎么能把它变成 16 位数字吗?你知道它是否比调用 bash 日期函数有更好的性能吗?
  • 学习概念,然后您可以将任何类型的日期/时间字符串转换为时间戳,而不是四处寻找极其具体的解决方案,然后在格式发生如此轻微变化时再次陷入困境.
  • 要将 10 位转换为 16 位,请在末尾添加“000000”。
  • 您没有清楚地解释您所说的“16digit epoch time”是什么意思,大多数读者可能不知道%6N 是什么意思。我已经更新了你的问题(@MarcB,不是重复的)。因此,您所有的时间戳都仅指定日期。你想要那天的午夜吗?在当前当地时区?

标签: perl


【解决方案1】:

您也可以使用Time::Moment。为了全面披露,我是 Time::Moment 的作者。

use v5.10;
use Time::Moment;

say Time::Moment->from_string('20160219' . 'T00Z')
                ->strftime('%s%6N');

输出:

1455840000000000

【讨论】:

    【解决方案2】:

    Time::Piece 可以做你想做的所有事情。之后,将0 填入 epoch,使其变为 16 位。

    #!/usr/bin/perl
    use strict;
    use warnings;
    use Time::Piece;
    
    my $t = Time::Piece -> strptime("20160219",
                                           "%Y%m%d");
    my $epoch = $t -> epoch;
    
    # make $epoch 16 digits
    $epoch .= "0" x (16 - length($epoch));
    
    print "$epoch\n";
    

    【讨论】:

      【解决方案3】:

      您可以使用 Time::Local 核心模块:

      use Time::Local 'timelocal';
      
      $date = "20160218";
      ($year, $month, $day) = unpack "A4A2A2", $date;
      
      $time = timelocal(0, 0, 0, $day, $month-1, $year);
      $time .= '000000';
      

      【讨论】:

        【解决方案4】:

        哇,我实际上只是编写了一个脚本来获取时间戳,它需要一个时间戳,它以自纪元以​​来的秒数为单位,并将其转换为人类可读的格式。不是你问的,但也许你可以把我写的反过来。

        my $ts = $ARGV[0]; #2012-09-04-20:24:19.870 1030825460
        my $newTs = toTimeString($ts);
        print "\n".$newTs."\n";
        
        
        ## Convert from time since epoch in seconds to string YYYY-MM-DD-HH:mm:ss.sss
        sub toTimeString{   
            my $ts=shift;
            $ts += 432000; # Add 5 days to make computation easy.
            my $sec = $ts-int($ts/60)*60; # Seconds
            $ts = int($ts/60); # Convert to minutes
            my $min = $ts%60; # minutes
            $ts = int($ts/60); # Convert to hours.
            my $hr = $ts%24; # hours;
            $ts = int($ts/24); # Convert to days.
            my $yr;
            my $mo;
            my $day;
            my $days =  [   [31,28,31,30,31,30,31,31,30,31,30,31],
                            [31,29,31,30,31,30,31,31,30,31,30,31]
                        ];
            our $cumDays =  [   [0,31,59,90,120,151,181,212,243,273,304,334],
                            [0,31,60,91,121,152,182,213,244,274,305,335]
                        ];
            if($ts<366){$yr=1980;}
            else{
                $yr = 1981 + int(($ts-366)/1461)*4;
                $ts = $ts - 366 - int(($ts-366)/1461)*1461;
                if($ts < 1095){$yr += int($ts/365); $ts = $ts - int($ts/365)*365;}
                else{$yr = $yr+3; $ts=$ts-1095;}
            }
            my $leap=0;
            my $i;
            if($yr%4 == 0){$leap=1;}
            for($i=0;$i<12;$i++){
                if($ts > $cumDays->[$leap]->[$i]){
                    $mo=$i+1;
                }
            }
            $day=$ts-$cumDays->[$leap]->[$mo-1]+1;
            my $ret;
            $ret = sprintf("%04d",$yr)."-".sprintf("%02d",$mo)."-".sprintf("%02d",$day)."-";
            $ret = $ret.sprintf("%02d",$hr).":".sprintf("%02d",$min).":".sprintf("%02d",int($sec));
            $ret = $ret."\.".sprintf("%03d",int($sec*1000)%1000);
            return ($ret)
        }
        

        【讨论】:

        • 我觉得我的下巴刚刚落地。
        • 好吧,这不是 OP 所要求的,但是当我将它打印到 .csv 文件时,我经常需要将纪元中的秒数转换为日志中的可读时间戳,我写这个是为了帮助我。跨度>
        • 不仅如此,还有一些经过充分测试的库可以在 2 行中完成相同的操作。
        • 我可以告诉你为此付出了很多努力,但你测试了吗?对于 now 的输入,它返回 2026-02-23-03:00:10.000,对于零的输入(应该是 1970-01-01)返回 1980-01-06-00:00:00.000。这就是@MattJacob 建议您使用现有模块的原因。
        猜你喜欢
        • 2015-12-22
        • 2016-02-06
        • 2011-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-18
        • 2018-05-28
        • 2012-01-30
        相关资源
        最近更新 更多