Skip to content

Inconsistent behaviour of dates / daylight savings after 2038 #874

@gowerc

Description

@gowerc

Apologies in advance I appreciate this is likely a user issue as I am not that familiar with the low level details of datetimes but I am at a loss now for what is going wrong so suspect there is a small possibility it could be some form of a bug.

If I compile and build the library using USE_SYSTEM_TZ_DB=OFF I get the correct expected datetimes after 2038 e.g.

#include <iostream>
#include <chrono>
#include <date/date.h>
#include <date/tz.h>

void printme(long long x) {
    date::sys_seconds utc_time{std::chrono::seconds(x)};
    date::zoned_time ny_time{"America/New_York", utc_time};
    std::cout << "Local time: " << date::format("%F %T %Z", ny_time) << '\n';
}

int main() {
    std::cout << "C++ Standard Version: " << __cplusplus << std::endl;
    printme(2095940701);
    printme(2127476701);
    printme(2159012701);
    printme(2190548701);
}

Produces as expected:

C++ Standard Version: 201703
Local time: 2036-06-01 09:45:01 EDT
Local time: 2037-06-01 09:45:01 EDT
Local time: 2038-06-01 09:45:01 EDT
Local time: 2039-06-01 09:45:01 EDT

However if I compile and rebuild the library with USE_SYSTEM_TZ_DB=ON and run the same exact code I no longer get the expected results (in particular it no longer seems to follow daylight savings rules):

C++ Standard Version: 201703
Local time: 2036-06-01 09:45:01 EDT
Local time: 2037-06-01 09:45:01 EDT
Local time: 2038-06-01 08:45:01 EST
Local time: 2039-06-01 08:45:01 EST

My first thought was that it must be an issue with my local tzdata however that all appears to be up-to-date, that is when running zdump -v America/New_York I can see that the rules are populated up till 2499:

America/New_York  Sun Mar  9 06:59:59 2498 UT = Sun Mar  9 01:59:59 2498 EST isdst=0 gmtoff=-18000
America/New_York  Sun Mar  9 07:00:00 2498 UT = Sun Mar  9 03:00:00 2498 EDT isdst=1 gmtoff=-14400
America/New_York  Sun Nov  2 05:59:59 2498 UT = Sun Nov  2 01:59:59 2498 EDT isdst=1 gmtoff=-14400
America/New_York  Sun Nov  2 06:00:00 2498 UT = Sun Nov  2 01:00:00 2498 EST isdst=0 gmtoff=-18000
America/New_York  Sun Mar  8 06:59:59 2499 UT = Sun Mar  8 01:59:59 2499 EST isdst=0 gmtoff=-18000
America/New_York  Sun Mar  8 07:00:00 2499 UT = Sun Mar  8 03:00:00 2499 EDT isdst=1 gmtoff=-14400
America/New_York  Sun Nov  1 05:59:59 2499 UT = Sun Nov  1 01:59:59 2499 EDT isdst=1 gmtoff=-14400
America/New_York  Sun Nov  1 06:00:00 2499 UT = Sun Nov  1 01:00:00 2499 EST isdst=0 gmtoff=-18000

Likewise when I try using other software on my machine they also seem to be following the rules as expected e.g. Python:

import zoneinfo
import datetime

def printtime(time: int):
    ny_time =  datetime.datetime.fromtimestamp(time, zoneinfo.ZoneInfo("America/New_York"))
    print(f"Time: {ny_time} ({ny_time.tzname()})")

print(zoneinfo.TZPATH)  # ('/usr/share/zoneinfo', '/usr/lib/zoneinfo', '/usr/share/lib/zoneinfo', '/etc/zoneinfo')

printtime(2095940701)  # Time: 2036-06-01 09:45:01-04:00 (EDT)
printtime(2127476701)  # Time: 2037-06-01 09:45:01-04:00 (EDT)
printtime(2159012701)  # Time: 2038-06-01 09:45:01-04:00 (EDT)
printtime(2190548701)  # Time: 2039-06-01 09:45:01-04:00 (EDT)

And also in R:

as.POSIXct(2095940701, tz = "America/New_York")      # "2036-06-01 09:45:01 EDT"
as.POSIXct(2127476701, tz = "America/New_York")      # "2037-06-01 09:45:01 EDT"
as.POSIXct(2159012701, tz = "America/New_York")      # "2038-06-01 09:45:01 EDT"
as.POSIXct(2190548701, tz = "America/New_York")      # "2039-06-01 09:45:01 EDT"

Which implies to me that the local timezone database is fully up-to-date; so is this a bug with the library or am I specifying something incorrectly (apologies if the latter) ?

EDIT -

For reference I am on Fedora 41 on a x64 intel cpu laptop using the standard package manager distributed software

> dnf info tzdata
Name            : tzdata
Epoch           : 0
Version         : 2025a
Release         : 1.fc41
Architecture    : noarch
Installed size  : 1.6 MiB
Source          : tzdata-2025a-1.fc41.src.rpm
From repository : updates
Summary         : Timezone data
URL             : https://www.iana.org/time-zones
License         : LicenseRef-Fedora-Public-Domain AND (GPL-2.0-only WITH ClassPath-exception-2.0)
Description     : This package contains data files with rules for various timezones around
                : the world.
Vendor          : Fedora Project
> zdump --version
zdump (GNU libc) 2.40
> g++ --version     
g++ (GCC) 14.2.1 20250110 (Red Hat 14.2.1-7)
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions