Re: Three-Digit Day of Year (245 Views)
Reply
Advisor
Michael Leis
Posts: 21
Registered: ‎12-05-2000
Message 1 of 12 (245 Views)
Accepted Solution

Three-Digit Day of Year

I need help with a unix shell script (prefer K-shell) that will convert a given date in the format yyyymmdd into yyddd. (Input format is negotiable, output format needs to be yyddd or yy seperated from ddd.) For example, I put in 20050831 it would output 05243 because August 31 was the 243 day of 2005. I'm familiar with date '+%y%j' that provides that for todays date, but I need to be able to declare any reasonable given date in the past or future. I don't want the true julian date (number of days since 4713BC), just the number of days a given date is into its year. Any help is appreciated.
Please use plain text.
Outstanding Contributor
Pete Randall
Posts: 16,205
Registered: ‎11-03-1996
Message 2 of 12 (245 Views)

Re: Three-Digit Day of Year

Sounds like a job for Clay's caljd.sh (attached). Invoke as "caljd.sh -u" for usage details.


Pete

Pete
Please use plain text.
Outstanding Contributor
Pete Randall
Posts: 16,205
Registered: ‎11-03-1996
Message 3 of 12 (245 Views)

Re: Three-Digit Day of Year

Michael,

I apologise - I assumed that Clay's script would handle such a thing but, going through the usage notes myself, I don't see an option for 3 digit output.


Pete

Pete
Please use plain text.
Outstanding Contributor
Pete Randall
Posts: 16,205
Registered: ‎11-03-1996
Message 4 of 12 (245 Views)

Re: Three-Digit Day of Year

Of course you could use caljd to determine the julian day of January 1 and subtract that from the current julian day. That ought to work.


Pete

Pete
Please use plain text.
Valued Contributor
Pat Lieberg
Posts: 107
Registered: ‎06-23-2005
Message 5 of 12 (245 Views)

Re: Three-Digit Day of Year

I whipped this up quick. Its a script that asks for the month and day and then tdells you the day of the year it is. Note that it does not calculate leap year, so Feb was hard-coded to 28 days. That could be programmed in though.


#!/bin/ksh
#
print - n "Enter the month and day: "
read month day

set -A days 31 28 31 30 31 30 31 31 30 31 30 31
((n = 0))
((j_days = 0))

((month = month - 1))

while ((n < $month))
do
((j_days = j_days + ${days[$n]}))
((n = n + 1))
done

((j_days = j_days + $day))
echo $j_days
Please use plain text.
Valued Contributor
Pat Lieberg
Posts: 107
Registered: ‎06-23-2005
Message 6 of 12 (245 Views)

Re: Three-Digit Day of Year

I forgot your desired result was inthe format dddyy, but you can add this to the end of the script:

year=$(date +%y)
result="$j_days$year"
echo $result


Please use plain text.
Honored Contributor
Hein van den Heuvel
Posts: 6,585
Registered: ‎05-19-2003
Message 7 of 12 (245 Views)

Re: Three-Digit Day of Year



In Perl:

---- julian.p ----
use Time::Local;
($y,$m,$d) = unpack "a4 a2 a2", shift @ARGV;
$s1 = timelocal(0,0,1,$d,$m-1,$y-1900);
$s2 = timelocal(0,0,0,1,0,$y-1900);
$u = 1 + ($s1 - $s2)/86400;
printf "%02d%03d\n", $y-2000, $u;


I used the $U = 1 + ... because jan-1 is day 1.
I used the hour 1 in $s1 to deal with integer truncation.


Hein.
Please use plain text.
Acclaimed Contributor
James R. Ferguson
Posts: 21,184
Registered: ‎07-06-2000
Message 8 of 12 (245 Views)

Re: Three-Digit Day of Year

Hi Michael:

A small perl script would easily help:

You an embed this in your shell and pass the Month Day Year as agruments. I've let it output a three-digit year and a three-digit day of year. THus 1999 outputs as 099 while 2005 appears as 105.

perl -e 'use Time::Local;$time=timelocal(0,0,0,$ARGV[1],$ARGV[0]-1,$ARGV[2]);($y,$d)=(localtime($time))[5,7];$d++;printf "%03d%03d\n"' 8 31 2005

...returns 105243

Obviously, you can use this in your shell like this:

RESULT=`perl -e `...`` $M $D $Y

Regards!

...JRF...
Please use plain text.
Honored Contributor
Hein van den Heuvel
Posts: 6,585
Registered: ‎05-19-2003
Message 9 of 12 (245 Views)

Re: Three-Digit Day of Year


Ah yes, I forgot about the $yday = 8th field in the localtime result. Using that my script could change to:

---- cat julian.p -----
use Time::Local;
($y,$m,$d) = unpack "a4 a2 a2", shift @ARGV;
$u = 1 + (localtime(timelocal(0,0,1,$d,$m-1,$y-1900)))[7];
printf "%02d%03d\n", $y-2000, $u;


There is a minor typo / cut&paste error in the JRF solution.
Try this:


# perl -e 'use Time::Local;$time=timelocal(0,0,0,$ARGV[1],$ARGV[0]-1,$ARGV[2]);($y,$d)=(localtime($time))[5,7];$d++;printf "%03d%03d\n", $y,$d' 8 31 2005

105243
Please use plain text.
Acclaimed Contributor
James R. Ferguson
Posts: 21,184
Registered: ‎07-06-2000
Message 10 of 12 (245 Views)

Re: Three-Digit Day of Year

Hi (again):

Yes, Hein, thank you. The paste I did cut off part of the script:

#!/usr/bin/perl
use Time::Local;
$time=timelocal(0,0,0,$ARGV[1],$ARGV[0]-1,$ARGV[2]);
($y,$d) = (localtime($time)) [5,7];
$d++;
printf "%03d%03d\n",$y,$d;

I like your use of 'unpack'. It would allow Michael to pass one argument to the perl script instead of three if that suits his needs better. Thanks for the correction to mine!

Regards!

...JRF...
Please use plain text.
Advisor
Michael Leis
Posts: 21
Registered: ‎12-05-2000
Message 11 of 12 (245 Views)

Re: Three-Digit Day of Year

Thank you for your help -- sometimes the simple things are the hardest to see. I ended up using Pat's sample script as it worked well for my purposes, however I can see where the PERL code would work well also. Thank you everyone!
Please use plain text.
Advisor
Michael Leis
Posts: 21
Registered: ‎12-05-2000
Message 12 of 12 (245 Views)

Re: Three-Digit Day of Year

Thank you for your help -- sometimes the simple things are the hardest to see. I ended up using Pat's sample script as it worked well for my purposes, however I can see where the PERL code would work well also. Thank you everyone!
Please use plain text.
The opinions expressed above are the personal opinions of the authors, not of HP. By using this site, you accept the Terms of Use and Rules of Participation