Repository: gabime/spdlog
File: tests/test_timezone.cpp (C++)

Code before:
#ifdef _WIN32
        if (has_original_) {
            _putenv_s("TZ", original_tz_.c_str());
        } else {
            _putenv_s("TZ", "");
        }
        _tzset();
#else
        if (has_original_) {
            setenv("TZ", original_tz_.c_str(), 1);
        } else {
            unsetenv("TZ");
        }
        tzset();
#endif
    }
};

using spdlog::details::os::utc_minutes_offset;

#ifdef _WIN32
#define EST5EDT "EST5EDT"
#define ISTN2IDT "IST-2IDT"
#else
#define EST5EDT  "EST5EDT,M3.2.0,M11.1.0"
#define ISTN2IDT "IST-2IDT,M3.4.4/26,M10.5.0"
#endif

TEST_CASE("UTC Offset - Western Hemisphere (USA - Standard Time)", "[timezone][west]") {
    // EST5EDT: Eastern Standard Time (UTC-5)
    ScopedTZ tz(EST5EDT);

    // Jan 15th (Winter)
    auto tm = make_tm(2023, 1, 15, 12, 0);
    REQUIRE(utc_minutes_offset(tm) == -300);
}

TEST_CASE("UTC Offset - Eastern Hemisphere (Europe/Israel - Standard Time)", "[timezone][east]") {
    // IST-2IDT: Israel Standard Time (UTC+2)
    ScopedTZ tz(ISTN2IDT);

    // Jan 15th (Winter)
    auto tm = make_tm(2023, 1, 15, 12, 0);
    REQUIRE(utc_minutes_offset(tm) == 120);
}

TEST_CASE("UTC Offset - Zero Offset (UTC/GMT)", "[timezone][utc]") {
    ScopedTZ tz("GMT0");

    // Check Winter
    auto tm_winter = make_tm(2023, 1, 15, 12, 0);

Review comment (suggestion):
`ISTN2IDT` is a bit opaque/ambiguous as a macro name (it reads like a typo vs the actual TZ string `IST-2IDT`). Consider renaming to something clearer like `ISRAEL_TZ` / `IST_MINUS_2_IDT` (and similarly for `EST5EDT`) so the test intent is obvious at call sites.

Code after:
#ifdef _WIN32
        if (has_original_) {
            _putenv_s("TZ", original_tz_.c_str());
        } else {
            _putenv_s("TZ", "");
        }
        _tzset();
#else
        if (has_original_) {
            setenv("TZ", original_tz_.c_str(), 1);
        } else {
            unsetenv("TZ");
        }
        tzset();
#endif
    }
};

using spdlog::details::os::utc_minutes_offset;

/*
 * POSIX 2024 defines three formats for the TZ environment variable,
 *
 * 1. Implementation defined format which always starts with a colon:
 *    ":characters".
 * 2. A specifier which fully describes the timezone rule in format
 *    "stdoffset[dst[offset][,start[/time],end[/time]]]". Note the
 *    offset and start/end part could be omitted, in which case one hour
 *    is implied, or it's considered implementation-defined when changing
 *    to and from Daylight Saving Time occurs.
 * 3. Geographical or special timezone from an implementation-defined
 *    timezone database.
 *
 * On POSIX-compilant systems, we prefer format 2, and explicitly specify the
 * DST rules to avoid implementation-defined behavior.
 *
 * See also IEEE 1003.1-2024 8.3 Other Environment Variables.
 */
#ifndef _WIN32
/*
 * Standard time is UTC-5 ("EST"), DST time is UTC-4 ("EDT"). DST is active
 * from 2:00 on the 2nd Sunday in March, to 2:00 on 1st Sunday in November.
 */
#define EST5EDT  "EST5EDT,M3.2.0,M11.1.0"
/*
 * Standard time is UTC+2 ("IST"), DST time is UTC+3 ("IDT"). DST is active
 * from 2:00 on following day of the 4th Thursday in March, to 2:00 on the
 * last Sunday in October.
 */
#define IST_MINUS2_IDT "IST-2IDT,M3.4.4/26,M10.5.0"
#else