Re: DAY Number in an Year
- From: "James Giles" <jamesgiles@xxxxxxxxxxxxxxxx>
- Date: Thu, 29 Sep 2005 04:48:09 GMT
Rich Townsend wrote:
> ttw@xxxxxxxxxxxxxxx wrote:
>> In 2003, I suggested:
>> FUNCTION juldate (year,month,day)
>> c
>> c Converts DAY/MONTH/YEAR to a Julian date transformed to 2000
>> c
>> IMPLICIT NONE
>> c
>> INTEGER juldate, day, month, year
>> c
>>
>> juldate=367*year-7*(year+(month+9)/12)/4-3*((year+(month-9)/7)/100
>>
>>
>> 1 +1)/4+275*month/9+day-730516
>> END
>>
>>
>> The constant 730516 can be adjusted to match any date desired as
>> the starting point or to change Gregorian dates to Julian.
>>
>
> Note, however, that Julian days formally begin at 12 noon. So your
> algorithm has an off-by-one error for AM vs PM.
For a one-to-one correspondence with calendar dates,
using round to nearest of the Julian day number is a good
choice. That's what the above produces. (Note that
astronomical day numbers are not integers, the fraction
of the day is part of the value.)
My complaint about the above is that it's difficult to
verify correctness. In the old days of programmable
pocket calculators and the like, saving space using
obscure formulae that didn't require any auxilliary
tables and such might have been appropriate. Today,
it's more important to be legible and verifiably correct.
In the same thread Dr. Warnock mentioned the above,
I recommended:
integer function dateval(m, d, y)
integer, intent(in):: m, d, y
integer, parameter:: ar(12) = (/365, 396, 59, 90, 120, 151, 181, &
212, 243, 273, 304, 334/)
integer :: yr
yr = y
if (m < 3) yr = y-1
dateval = yr*365 + yr/4 - yr/100 + yr/400 +ar(m) + d + 1721060
return
end
Originally, the leap day at the end of Feb. was at the end
of the year (March was the first month). With the change
to January as the first month, leap day was left as the
last of February. It's still easiest to calculate if leap
day is the last of the year however. So that's why the
first two months are adjusted as above. That's the
only confusing part of the algorithm. The rest is
clearly a direct application of the normal rules of
the Gregorian calendar. The 1721060 is the necessary
value for the Julian day number sequence (the first day
of which was chosen to be Jan 1, 4713 BC). Any number
can be chosen if you want a different initial date.
The above obviously doesn't check for valid dates. If the
day of the month or the year are impossible or way out of
range, the returned value is meaningless. The month
is not checked either unless array bounds checking is turned
on. On the other hand, for valid Gregorian dates (more
recent then Oct 15, 1582 and for as far in the future as
I expect to survive - at least assuming default INTEGERs
are at least 23 bits) the returned result should be correct.
To get the fractional Julian day number, take the time of
day (in hours), subtract 12, divide by 24.0 and add to the
above calculated integer.
> PS I'm talking about the astronomical Julian calendar, as created by Julius
> Scalinger. For some reason, many programmers refer to the days-since-arbitrary
> epoch (say, 1900 or 1970) as the Julian date, but that's just wrong.
Actually it was invented by Jacob Scalinger and named for his
father, whose name was Julius.
--
J. Giles
"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare
.
- References:
- DAY Number in an Year
- From: prasad413in
- Re: DAY Number in an Year
- From: ttw
- Re: DAY Number in an Year
- From: Rich Townsend
- DAY Number in an Year
- Prev by Date: Re: DAY Number in an Year
- Next by Date: Re: Can Fortran Use This C Variable Directly Via "external" Decl?
- Previous by thread: Re: DAY Number in an Year
- Next by thread: Re: DAY Number in an Year
- Index(es):
Relevant Pages
|