我将来会有一个日期,我必须每次减去3个月,直到达到当前日期。
即:
我正在运行Solaris,因此无法访问GNU日期。
我尝试在Perl中执行此操作,但不幸的是我只能使用Time::Local
模块:
#!/bin/ksh
m_date="2019/05/23"
m_year=$(echo $m_date|cut -d/ -f1)
m_month=$(echo $m_date|cut -d/ -f2)
m_day=$(echo $m_date|cut -d/ -f3)
export m_year m_month m_day
perl -MTime::Local -le '
$time = timelocal(localtime);
$i = 3;
while (timelocal(0, 0, 0, $ENV{'m_day'}, $ENV{'m_month'} - $i, $ENV{'m_year'}) > $time) {
print scalar(localtime(timelocal(0, 0, 0, $ENV{'m_day'}, $ENV{'m_month'} - $i, $ENV{'m_year'})));
$i += 3;
}
'
这仅在一年内有效。还有其他办法吗?
答案 0 :(得分:4)
分割日期字符串并对字段进行算术很简单。
use strict;
use warnings;
use 5.010;
my $future = '2015/01/23';
my $current = do {
my @current = localtime;
$current[3] += 1;
$current[5] += 1900;
sprintf '%04d/%02d/%02d', @current[5,4,3];
};
my $result;
for (my $test = $future; $test gt $current; ) {
$result = $test;
my @test = split /\//, $test;
if (($test[1] -= 3) < 1) {
--$test[0];
$test[1] += 12;
}
$test = sprintf '%04d/%02d/%02d', @test;
}
say $result;
<强>输出强>
2014/07/23
或者,您可以只进行除法计算要减去的整数四分之一,例如
use strict;
use warnings;
use 5.010;
my $future = '2015/01/23';
my @current = (localtime)[5,4,3];
$current[1] += 1;
$current[0] += 1900;
my @future = split /\//, $future;
my $months = ($future[0] - $current[0]) * 12 + $future[1] - $current[1];
$months -= 1 if $current[2] >= 23;
my @result = @current;
$result[2] = 23;
$result[1] += $months % 3;
$result[0] += int(($result[1] - 1) / 12);
$result[1] = ($result[1] - 1) % 12 + 1;
my $result = sprintf '%04d/%02d/%02d', @result;
say $result;
输出与前一代码的输出相同
答案 1 :(得分:1)
这是您的脚本已更改,因此它应该可以使用多年,
perl -MTime::Local -le'
sub nextm {
$ENV{m_year}--, $ENV{m_month} +=12 if ($ENV{m_month} -= 3) <1;
timelocal(0, 0, 0, $ENV{m_day}, $ENV{m_month}, $ENV{m_year});
}
my $time = timelocal(localtime);
while ((my $c=nextm()) > $time) {
print scalar localtime($c);
}
'
答案 2 :(得分:0)
尝试类似:
#!/usr/bin/perl -w
# just convert the real date that you have to epoch
my $torig = 1558569600;
my $tnow = time;
# 3 months in seconds to use the epoch everywhere
my $estep = 3 * 30 * 24 * 3600;
while(($torig - $estep) > $tnow){
$torig -= $estep;
}
print $torig,"\n";
print scalar localtime($torig),"\n";
这里唯一的问题是月份是近似值,如果你需要同一天但是减去3个月,你可以使用DateCalc
答案 3 :(得分:0)
由于Borodin的逻辑,我最终用KSH而不是perl来编写脚本。
#!/bin/ksh
set -A c_date $(date '+%Y %m %d')
IFS=/ d="2019/05/23"
set -A m_date $d
[[ ${c_date[2]} -gt ${m_date[2]} ]] && ((c_date[1]+=1))
c_date[2]=${m_date[2]}
c_date[1]=$(( (((${m_date[0]} - ${c_date[0]}) * 12) + (${m_date[1]} - ${c_date[1]})) % 3 + ${c_date[1]} ))
if [[ ${c_date[1]} -gt 12 ]] ; then
((c_date[0]+=1))
((c_date[1]-=12))
fi
echo ${c_date[@]}