Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Date 基于时间的增量日期_Date_Awk_Sed - Fatal编程技术网

Date 基于时间的增量日期

Date 基于时间的增量日期,date,awk,sed,Date,Awk,Sed,我需要根据时间将日期增加+1d。这似乎有点让我不知所措,但我怀疑它可以通过perl甚至awk来完成。对于每个带有0000的时间戳,我需要将天增加+1 输入: 15,07/31/2020 1600,1048,31,0 15,07/31/2020 1700,1086,45,0 15,07/31/2020 1800,1092,42,0 15,07/31/2020 1900,1017,20,1 15,07/31/2020 2000,945,0,28 15,07/31/2020 2100,897,0,43

我需要根据时间将日期增加+1d。这似乎有点让我不知所措,但我怀疑它可以通过perl甚至awk来完成。对于每个带有0000的时间戳,我需要将天增加+1

输入:

15,07/31/2020 1600,1048,31,0
15,07/31/2020 1700,1086,45,0
15,07/31/2020 1800,1092,42,0
15,07/31/2020 1900,1017,20,1
15,07/31/2020 2000,945,0,28
15,07/31/2020 2100,897,0,43
15,07/31/2020 2200,869,0,55
15,07/31/2020 2300,812,0,72
15,07/31/2020 0000,778,0,82
预期产出:

15,07/31/2020 1600,1048,31,0
15,07/31/2020 1700,1086,45,0
15,07/31/2020 1800,1092,42,0
15,07/31/2020 1900,1017,20,1
15,07/31/2020 2000,945,0,28
15,07/31/2020 2100,897,0,43
15,07/31/2020 2200,869,0,55
15,07/31/2020 2300,812,0,72
15,08/01/2020 0000,778,0,82
看起来awk可以增加日期,但我的问题是,如何在不改变其余行的情况下,只增加0000行的日期?

使用GNU awk:

awk '$5=="0000"{
       # convert columns to unixtime
       unixtime=mktime($4 " " $2 " " $3 " " "00 00 00")

       # add one day to unixtime and convert back to month/day/year
       nextday=strftime("%m/%d/%Y",unixtime+60*60*24)

       # rebuild current row
       $0=$1 OFS nextday " " $5 OFS $6 OFS $7 OFS $8
     }
     {print}' FS='[,/ ]' OFS=',' file
作为一行:

awk '$5=="0000"{unixtime=mktime($4 " " $2 " " $3 " " "00 00 00"); nextday=strftime("%m/%d/%Y",unixtime+60*60*24); print $1,nextday " " $5,$6,$7,$8; next}{print}' FS='[,/ ]' OFS=',' file
输出:

15,07/31/2020 1600,1048,31,0 15,07/31/2020 1700,1086,45,0 15,07/31/2020 1800,1092,42,0 15,07/31/2020 1900,1017,20,1 15,07/31/2020 2000,945,0,28 15,07/31/2020 2100,897,0,43 15,07/31/2020 2200,869,0,55 15,07/31/2020 2300,812,0,72 15,08/01/2020 0000,778,0,82 15,07/31/2020 1600,1048,31,0 15,07/31/2020 1700,1086,45,0 15,07/31/2020 1800,1092,42,0 15,07/31/2020 1900,1017,20,1 15,07/31/2020 2000,945,0,28 15,07/31/2020 2100,897,0,43 15,07/31/2020 2200,869,0,55 15,07/31/2020 2300,812,0,72 15,08/01/2020 0000,778,0,82

请参阅:

此Perl解决方案使用Time::Piece(包含在标准发行版中)

注:这是我的第一条评论。因为这个问题已经重新打开,我可以在这里发布答案


为了增加日数,我们还需要在必要时滚动月数

为此,我们需要知道一个月的天数

要知道这一点,我们还需要知道当前年份是否为闰年(即二月有28天或29天)。该公式可通过网络搜索轻松获得

我不确定您输入的格式:

15,07/31/2020 0000,778,0,82
什么是
15
?我想你只是通过了

什么是
0000778,0,82
?我假设您可以将第一个数字[作为文本]与
0000
进行比较


下面是
perl
中的代码。我编写了整个算法,不依赖于安装额外的perl软件包或使用函数,如
mktime
,等等。我尝试尽可能多地对其进行注释:

#!/usr/bin/perl
# code to increment day

master(@ARGV);
exit(0);

sub master
{

    my(@days_in_month) = (31,28,31,30,31,30,31,31,30,31,30,31);

    # input format:
    #   15,07/31/2020 0000,778,0,82
    while ($buf = <STDIN>) {
        chomp($buf);

        # split off date and time
        my($date,$time) = split(" ",$buf);

        # split up date
        my($pre,$mon,$day,$year) = split(m%[,/]%,$date);

        # decide if current year is leap year
        my($isleap) = 0;
        {
            # year must be divisible by 4
            last if (($year % 4) != 0);

            # if year is divisible by 100, it is _not_ a leap year unless ...
            if (($year % 100) == 0) {
                # ... it is also divisible by 400
                last if (($year % 400) != 0);
            }

            $isleap = 1;
        }

        # get number of days in february
        if ($isleap) {
            $days_in_month[1] = 29;
        }
        else {
            $days_in_month[1] = 28;
        }

        # change only if time is 0000
        if ($time =~ /^0000,/) {
            # increment day
            $day += 1;

            # advance month if necessary
            if ($day > $days_in_month[$mon - 1]) {
                $day = 1;
                $mon += 1;
            }

            # advance year if necessary
            if ($mon > 12) {
                $mon = 1;
                $year += 1;
            }
        }

        $date = sprintf("%2.2d,%2.2d/%2.2d/%4.4d",$pre,$mon,$day,$year);

        printf("%s %s\n",$date,$time);
    }
}
#/usr/bin/perl
#代码到增量日
船长(@ARGV);
出口(0);
副船长
{
my(@days_in_month)=(31,28,31,30,31,30,31,31,30,31);
#输入格式:
#   15,07/31/2020 0000,778,0,82
而($buf=){
chomp($buf);
#分开日期和时间
我的($date,$time)=分割(“,$buf);
#分手日期
我的($pre,$mon,$day,$year)=分割(m%[,/]%,$date);
#决定当前年份是否为闰年
我的($isleap)=0;
{
#年份必须可以被4整除
如果($year%4)!=0,则为最后一次;
#如果一年可以被100整除,那就不是闰年,除非。。。
如果(($year%100)==0){
#…它也可以被400整除
如果($year%400)!=0,则为最后一次;
}
$isleap=1;
}
#获取二月的天数
如果($isleap){
$days_in_月[1]=29;
}
否则{
$days_in_月[1]=28;
}
#仅当时间为0000时更改
如果($time=~/^0000,/){
#增量日
$day+=1;
#如有必要,提前一个月
如果($day>$days\u in\u月[$mon-1]){
$day=1;
$mon+=1;
}
#如有必要,提前一年
如果($mon>12){
$mon=1;
$year+=1;
}
}
$date=sprintf(“%2.2d、%2.2d/%2.2d/%4.4d”、$pre、$mon、$day、$year);
printf(“%s%s\n”,$date,$time);
}
}

现在我正在与sed合作
sed-i'/0000/s/07/08/g'file.csv>newfile.csv
这将查找字符串并替换月份。然而,我不确定如何让它动态检测日期并添加一天。我还研究了awk,它的挑战似乎是它不分青红皂白地影响所有日期。为了增加日期,您还需要在必要时滚动一个月。为此,您需要知道一个月的天数。要知道这一点,您还需要知道当前年份是否为闰年(即二月有28天或29天)。该公式可通过网络搜索轻松获得。我不确定您输入的格式:
15,07/31/2020 0000778,0,82
什么是
15
?我想你只是通过了。什么是
0000778,0,82
?我假设您可以将第一个数字[作为文本]与
0000
进行比较。请看:这非常有用,感谢您指出闰年警告。虽然我最终使用了下面较短的脚本,但由于布局良好的格式和清晰/有用的注释,我也将此脚本存档。我希望我也能给你一个答案。不管怎样,非常感谢你的帮助!!!不客气!正如我所提到的,我故意避免使用固定的助手函数来演示如何手动操作。特别是因为其他人正在使用它们。别担心。你应该[总是]接受最好的答案。但是,(如果你还没有这样做的话),你可以投多个好的答案。
15,07/31/2020 0000,778,0,82
#!/usr/bin/perl
# code to increment day

master(@ARGV);
exit(0);

sub master
{

    my(@days_in_month) = (31,28,31,30,31,30,31,31,30,31,30,31);

    # input format:
    #   15,07/31/2020 0000,778,0,82
    while ($buf = <STDIN>) {
        chomp($buf);

        # split off date and time
        my($date,$time) = split(" ",$buf);

        # split up date
        my($pre,$mon,$day,$year) = split(m%[,/]%,$date);

        # decide if current year is leap year
        my($isleap) = 0;
        {
            # year must be divisible by 4
            last if (($year % 4) != 0);

            # if year is divisible by 100, it is _not_ a leap year unless ...
            if (($year % 100) == 0) {
                # ... it is also divisible by 400
                last if (($year % 400) != 0);
            }

            $isleap = 1;
        }

        # get number of days in february
        if ($isleap) {
            $days_in_month[1] = 29;
        }
        else {
            $days_in_month[1] = 28;
        }

        # change only if time is 0000
        if ($time =~ /^0000,/) {
            # increment day
            $day += 1;

            # advance month if necessary
            if ($day > $days_in_month[$mon - 1]) {
                $day = 1;
                $mon += 1;
            }

            # advance year if necessary
            if ($mon > 12) {
                $mon = 1;
                $year += 1;
            }
        }

        $date = sprintf("%2.2d,%2.2d/%2.2d/%4.4d",$pre,$mon,$day,$year);

        printf("%s %s\n",$date,$time);
    }
}