Days from 1970-01-01 to the given proleptic Gregorian date.
Howard Hinnant’s days_from_civil, which is exact for every date in
the int64 range and uses only integer operations. The year is shifted
so that the era begins on 1 March, which is what removes the leap-day
special case from the month arithmetic.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=int64), | intent(in) | :: | y_in | |||
| integer(kind=int64), | intent(in) | :: | m | |||
| integer(kind=int64), | intent(in) | :: | d |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer(kind=int64), | private | :: | doe | ||||
| integer(kind=int64), | private | :: | doy | ||||
| integer(kind=int64), | private | :: | era | ||||
| integer(kind=int64), | private | :: | y | ||||
| integer(kind=int64), | private | :: | yoe |
pure function days_from_civil(y_in, m, d) result(days) !! Days from 1970-01-01 to the given proleptic Gregorian date. !! !! Howard Hinnant's `days_from_civil`, which is exact for every date in !! the int64 range and uses only integer operations. The year is shifted !! so that the era begins on 1 March, which is what removes the leap-day !! special case from the month arithmetic. integer(int64), intent(in) :: y_in integer(int64), intent(in) :: m integer(int64), intent(in) :: d integer(int64) :: days integer(int64) :: y, era, yoe, doy, doe y = y_in if (m <= 2_int64) y = y - 1_int64 if (y >= 0_int64) then era = y/400_int64 else era = (y - 399_int64)/400_int64 end if yoe = y - era*400_int64 ! [0, 399] if (m > 2_int64) then doy = (153_int64*(m - 3_int64) + 2_int64)/5_int64 + d - 1_int64 else doy = (153_int64*(m + 9_int64) + 2_int64)/5_int64 + d - 1_int64 end if doe = yoe*365_int64 + yoe/4_int64 - yoe/100_int64 + doy ! [0, 146096] days = era*146097_int64 + doe - DAYS_EPOCH_SHIFT end function days_from_civil