Hi All,
I am trying to generate quarter dates with user giving input as begin date and end date. Example: Input by user:
begin_date = "2009-01-01"
end_date = 2010-04-30"
required output:
2009-01-01 2009-03-31 09Q01
2009-04-01 2009-06-30 09Q02
.
.
till
2010-01-01 2010-03-31 10Q01
TIA
Here's one way to do it with Perl:
$
$
$ # display the content of the Perl program
$ cat -n printqtr.pl
1 #!perl -w
2 use Date::Calc qw (Add_Delta_YMD Date_to_Days);
3
4 # 1st parameter is start date; 2nd is end date
5 # no input validation done here
6 @sdate = split(/-/,$ARGV[0]);
7 @edate = split(/-/,$ARGV[1]);
8
9 # determine the beginning quarter for the loop
10 if ($sdate[1]/3 == int($sdate[1]/3)) {
11 $add_mon = 3*($sdate[1]/3-1);
12 $qtr = $sdate[1]/3;
13 } else {
14 $add_mon = 3*int($sdate[1]/3);
15 $qtr = int($sdate[1]/3)+1;
16 }
17 @x = Add_Delta_YMD($sdate[0],1,1, 0,$add_mon,0);
18
19 # determine the ending quarter for the loop
20 if ($edate[1]/3 == int($edate[1]/3)) {
21 $eadd_mon = 3*($edate[1]/3);
22 } else {
23 $eadd_mon = 3*(int($edate[1]/3)+1);
24 }
25 @y = Add_Delta_YMD($edate[0],1,1, 0,$eadd_mon,-1);
26
27 # and now loop from beginning quarter to ending quarter
28 while (Date_to_Days(@x) < Date_to_Days(@y)) {
29 printf("%4d-%02d-%02d\t%4d-%02d-%02d\t%sQ%02d\n",
30 @x, Add_Delta_YMD(@x, 0,3,-1), substr($x[0],2,2), $qtr);
31 @x = Add_Delta_YMD(@x, 0,3,0);
32 # roll over quarter to 1, beyond 4
33 $qtr++;
34 $qtr = $qtr > 4 ? 1 : $qtr;
35 }
$
$ # test it for different cases, boundary conditions etc.
$
$ # both parameters identical
$ perl printqtr.pl 2009-01-01 2009-01-01
2009-01-01 2009-03-31 09Q01
$
$ # dates within a quarter
$ perl printqtr.pl 2009-01-01 2009-01-20
2009-01-01 2009-03-31 09Q01
$
$ # dates spanning multiple quarters of the same year
$ perl printqtr.pl 2009-01-01 2009-04-01
2009-01-01 2009-03-31 09Q01
2009-04-01 2009-06-30 09Q02
$
$ # dates spanning multiple quarters of multiple years
$ perl printqtr.pl 2009-01-01 2011-08-28
2009-01-01 2009-03-31 09Q01
2009-04-01 2009-06-30 09Q02
2009-07-01 2009-09-30 09Q03
2009-10-01 2009-12-31 09Q04
2010-01-01 2010-03-31 10Q01
2010-04-01 2010-06-30 10Q02
2010-07-01 2010-09-30 10Q03
2010-10-01 2010-12-31 10Q04
2011-01-01 2011-03-31 11Q01
2011-04-01 2011-06-30 11Q02
2011-07-01 2011-09-30 11Q03
$
$ # dates in incorrect order
$ perl printqtr.pl 2011-08-01 2001-08-28
$
$
HTH,
tyler_durden
Thanks tyler_durden, it is working... thanks a lot...
can it be done using awk? just wanted to know...
Hi Tyler,
Suppose if Igive start date as 2000-10-01 and end date as 2010-05-31
Can I get output as
2009-10-01 2009-12-31 09Q04
2010-01-01 2010-03-31 10Q01
2010-04-01 2010-05-31 10Q02
Well, what do you see when you pass those parameters to the program ?
tyler_durden
2009-10-01 2009-12-31 09Q04
2010-01-01 2010-03-31 10Q01
2010-04-01 2010-06-30 10Q02
Instead of 2010-06-30 can I get the end provided as output...
I guess you are passing "2009-10-01" as the first parameter and not "2000-10-01" as mentioned in your earlier post:
Set the value of @y to the lesser of @y and @edate at line no. 26 of the script.
tyler_durden
Hi Tyler,
Yep it is 2009-10-01, typo
I mean suppose if I give the input as sdate as 2009-10-01 and edate as 2010-05-31
I have to get following output:
2009-10-01 2009-12-31 09Q04
2010-01-01 2010-03-31 10Q01
2010-04-01 2010-05-31 10Q02
But from your code, I get the following output:
2009-10-01 2009-12-31 09Q04
2010-01-01 2010-03-31 10Q01
2010-04-01 2010-06-30 10Q02
And if I give input as sdate as 2009-10-01 and edate as 2010-06-30
I have to get following output:
2009-10-01 2009-12-31 09Q04
2010-01-01 2010-03-31 10Q01
2010-04-01 2010-06-30 10Q02
I have tried modying the code as you said, it is giving the fllowing error:
Useless use of numeric lt (<) in void context at qtr_dates.pl line 26.
TIA
if (($edate[0],$edate[1],$edate[2]) < @y) {
@y = ($edate[0],$edate[1],$edate[2]);
}
else
{ @y = Add_Delta_YMD($edate[0],1,1, 0,$eadd_mon,-1);
}
I am not sure, if what I am doing is right... correct me if I am wrong here