CEMPD / SMOKE

Create emissions inputs for multiple air quality modeling systems with unmatched speed and flexibility
https://www.cmascenter.org/smoke/
45 stars 21 forks source link

possible DST ending date bug in I/O API #96

Open cseppan opened 1 month ago

cseppan commented 1 month ago

For determining the start and end of daylight saving time, SMOKE uses the I/OAPI ISDSTIME() function:

https://cmascenter.org/ioapi/documentation/all_versions/html/ISDSTIME.html

Checking start and end dates using the I/O API utility program “juldate” shows a potential problem.

juldate 3 9 2024

Saturday, 2024069
Standard Time in effect.

juldate 3 10 2024

Sunday, 2024070
Daylight Savings Time in effect.

The start date of DST looks fine, but the results for the ending dates seem off:

juldate 11 1 2024

Friday, 2024306
Daylight Savings Time in effect.

juldate 11 2 2024

Saturday, 2024307
Standard Time in effect.

juldate 11 3 2024

Sunday, 2024308
Standard Time in effect.

It seems like Saturday, November 2, 2024 should report DST still in effect. Since the rules changed in 2007 (and the I/O API docs mention this), I checked the results for 2006, which behaves as expected:

juldate 10 28 2006

Saturday, 2006301
Daylight Savings Time in effect.

juldate 10 29 2006

Sunday, 2006302
Standard Time in effect.

There may be an issue in the I/O API implementation for DST ending dates in 2007 and later.

hnqtran commented 1 month ago

Currently, ISDSTIME subroutine (ioapi-3.2/ioapi/isdstime.F) has distinctive treatment for DST in year before and after 2007.

        IF ( YEAR .LT. 2007 ) THEN
            DAY0  = DAY0 + 6 - MOD( K + DAY0, 7 ) !  first Sun. in Apr.
            K     = 1 + MOD( K + DAY1, 7 )        !  day-number 1...7 for OCT31
            DAY1  = DAY1     - MOD( K, 7 )        !  last  Sun. in Oct.
        ELSE
            DAY0  = DAY0 - 31                      !  March 1
            DAY0  = DAY0 + 13 - MOD( K + DAY0, 7 ) !  second Sunday in March,
            K     = 1 + MOD( K + DAY1, 7 )         !  day-number 1...7 for OCT31
            DAY1  = DAY1 +  6 - MOD( K, 7 )        !  first Sunday in November
        END IF

The issue that Catherine described earlier was solved by modifying DAY1 to:

DAY1  = DAY1 +  7 - MOD( K, 7 )        !  first Sunday in November

(It is unclear why 6 was used here).

Tests:

juldate 11 3 2024

Saturday, 2024307
Daylight Savings Time in effect.

juldate 11 4 2024

Sunday, 2024308
Standard Time in effect.