Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations MikeeOK on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Julian Date conversion 2

Status
Not open for further replies.

frangac

Technical User
Feb 8, 2004
163
ZA
Hi,

Any idea on how to convert a julian date format into "2004/05/26".

My script:

awk '{
for (e=1;e<NF;e++){if ($e~/BasicInfo1/)
{printf "%s %s %15s %s\n" ,$(e+2) ,$11, $16,$13
}
}
}' |
awk '{
hexstr="0123456789abcdef"
newnum=tolower(substr($4,5,2) substr($4,3,2) substr($4,1,2))
JD=JDATE_CAL $11

Many Thanks
Chris
 
By a Julian date do you mean one in the form yyyyddd i.e. 2004147 would convert to 2004/05/26? I don't really understand your script but here is a standalone script which you may be able to adapt to your needs.

BEGIN { m[1]=31;m[2]=28;m[3]=31;m[4]=30;m[5]=31;m[6]=30;
m[7]=31;m[8]=31;m[9]=30;m[10]=31;m[11]=30;m[12]=31;
}
{
yy=substr($0,1,4)
dd=substr($0,5)+0
if (yy%4 == 0) m[2]=29;
mm = 1
while (dd > m[mm]) {
dd -= m[mm]
mm++
}
printf ("%4.4d/%2.2d/%2.2d\n", yy, mm, dd)
}



CaKiwi
 
Hi CaKiwi,

Thanks for the reply.

My mistake, I meant a julian date ( 0147 ) which when converted will be "2004-05-27"

Thanks Again
Chris
 
Ooooops

Again my mistake, julian date ( 147 ) should be "2004-05-26"

Thanks
Chris
 
So in your script above does the variable JD contain the Julian date? If so, try

split("31 29 31 30 31 30 31 31 30 31 30 31",m)
yy=2004
dd=JD
mm = 1
while (dd > m[mm]) {
dd -= m[mm]
mm++
}
printf ("%4.4d/%2.2d/%2.2d\n", yy, mm, dd)
}

This uses a split instead of all the assignments in my previous post and you end up with the year, month and day in the vaiables yy, mm and dd. Does this help?

CaKiwi
 
here's a ksh version to convert a Julian date to 'Year Month Date'.
I have an awk version of this somewhere, but cannot find it right away.

Code:
#!/bin/ksh
#
# Calendar date from Julian Day Number
julian2date() # julianday
{
  #set -x
  typeset tmpday=$(($1 - 1721119))
  typeset centuries=$(( (4 * tmpday - 1) / 146097))
  tmpday=$((tmpday + centuries - centuries/4))
  typeset year=$(( (4 * tmpday - 1) / 1461))
  tmpday=$((tmpday - (1461 * year) / 4))
  typeset month=$(( (10 * tmpday - 5) / 306))
  day=$((tmpday - (306 * month + 5) / 10))
  month=$((month + 2))
  year=$((year + month/12))
  month=$((month % 12 + 1))
  printf "%s %02d %02d" $year $month $day
}

vlad
+----------------------------+
| #include<disclaimer.h> |
+----------------------------+
 
Hi CaKiwi,

Spot on. I have a couple of questions.

1) In place of yy=2004 should I replace it "echo date +'%Y'"
2)Could you explain the following

mm = 1
while (dd > m[mm]) {
dd -= m[mm]
mm++

Many Thanks
Chris

 
You could use

"date +%Y" | getline yy

mm=1 # start the month counter at 1
while (dd > m[mm]) { # while the number of days left is greater that the number of days in the current month
dd -= m[mm] # subtract the number of days in the current month from the number of days left
mm++ # add 1 to the month counter
}


CaKiwi
 
I hink that should be

"date +'%Y'" | getline yy

CaKiwi
 
Hi CaKiwi,

Thanks Vlad.

CaKiwi
Forgot to ask you will this work for the year 2005 and so on, as I noticed that for the month of Feb you are using 29 days as it is a leap year. what about no leap years.

Thank
Chris
 
My original script handled leap years

split("31 28 31 30 31 30 31 31 30 31 30 31",m)
"date +'%Y'" | getline yy
if (yy%4 == 0) m[2] = 29
dd=JD
mm = 1
while (dd > m[mm]) {
dd -= m[mm]
mm++
}


CaKiwi
 
CaKiwi,

Sleeping time for me.
Thanks.

Please explain

if (yy%4 == 0) m[2] = 29

Thanks
Chris
 
if (yy%4 == 0) m[2] = 29

If the year divided by 4 has a remainder of 0, it's a leap year so the second month (February) has 29 days. It should really include a test for divisible by 100 but not 400. This correction is left as an exercise for the reader...

CaKiwi
 
Ok I couldn't help myself. It should be

if (yy%4==0 && (yy%100!=0 || yy%400==0)) m[2] = 29

CaKiwi
 
CaKiwi,

Since you insisted, please explain why the 100 but not 400.
Why these values?

Thanks
Chris
 
Because years divisible by 100 are not leap years unless they are also divisible by 400. Thus 2000 was a leap year but 1900 was not and 2100 will not be. See man date for more details

CaKiwi
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top