Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Y2K38 in wxDateTime #24464

Closed
wants to merge 6 commits into from
Closed

Support Y2K38 in wxDateTime #24464

wants to merge 6 commits into from

Conversation

lanurmi
Copy link
Contributor

@lanurmi lanurmi commented Apr 11, 2024

  • Return 64-bit values from GetTicks() if time_t is 64-bit
  • Use CRT for dates up to (the arbitrarily chosen) year 2200
  • Add some 64-bit timestamps to test

There are actually fewer changes than I expected to be needed; I hope this is all that it takes.

This is could and probably should be backported to 3.2.

May fix #24414.
Should fix #22561.

This allows successfully running the tests with dates beyond Y2K38,
when time_t is 32-bit.
This is very essential, since otherwise GetTicks() would become
practically useless at Y2K38, i.e. less than 14 years from now.

Also remove redundant cast of TIME_T_FACTOR, which is already
long, and does not need to be explicitly cast to long.
… 64-bit

MSVC claims to support dates up to 3000; what glibc, OSX, or other *nix
claim is unknown, but we shall assume 2200 is a reasonable maximum for
those also.
Copy link
Contributor

@vadz vadz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, it's reassuring (even if not really surprising) that the changes are so small, but I'd prefer not to hardcode the 2200 limit.

And, ideally, we'd need more tests, i.e. add dates after 2038 to at least some other tests to check that the relevant functionality keeps working after 2K38 when sizeof(time_t) == 8 (and skip these tests if it isn't).

// is safe to return values exceeding wxINT32_MAX

return m_time >= 0l &&
( (sizeof(time_t) > 4 ) || ( (m_time / TIME_T_FACTOR) < wxINT32_MAX) );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this ought to use use the same limit as the code in datetime.cpp (i.e. 2200 right now, but see there), shouldn't it?

// While the range for 64-bit time_t is billions of years per se,
// we cannot expect the C runtime to support dates thousands of years
// in the future. MSVC claims to support dates up to 3000-12-31;
// what macOS and *nix support is unknown, but let us pick year 2200
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like arbitrary picking up the values out of thin air like this. What's the worst that can happen if try using the standard library for the year 12345678 (i.e. infinitely far in the future)? It's probably not going to do worse than our own code here, is it?

I.e. I'd drop the check for max year here (and then we wouldn't need to change the code in IsInStdRange()).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like arbitrary picking up the values out of thin air like this. What's the worst that can happen if try using the standard library for the year 12345678 (i.e. infinitely far in the future)? It's probably not going to do worse than our own code here, is it?

On MSVC, localtime and mktime will fail (and return NULL and -1, respectively) for dates after 3000, per the documentation. But I cannot judge if that is better or worse than what wx's own code does.

I.e. I'd drop the check for max year here (and then we wouldn't need to change the code in IsInStdRange()).

I'll do that.

@lanurmi
Copy link
Contributor Author

lanurmi commented Apr 12, 2024

And, ideally, we'd need more tests, i.e. add dates after 2038 to at least some other tests to check that the relevant functionality keeps working after 2K38 when sizeof(time_t) == 8 (and skip these tests if it isn't).

As far as I see, most arrays of dates in datetimetest.cpp already have dates after 2038, but I'll also add some more to those that do not have.

@vadz
Copy link
Contributor

vadz commented Apr 14, 2024

Thanks, I've rebased, done some minor changes (mostly to the comments which still mentioned 2200) and will merge it soon.

It also can be backported to 3.2 AFAICS, so let's do it later, if we don't find any problems with it in master.

@vadz vadz added the backport-3.2 Fix applied to master but still has to be backported to stable 3.2 label Apr 14, 2024
vadz added a commit that referenced this pull request Apr 14, 2024
Solve some Y2K38 problems in wxDateTime.

See #24464.
@vadz
Copy link
Contributor

vadz commented Apr 14, 2024

Merged into master by the commit above, so closing.

@vadz vadz closed this Apr 14, 2024
vadz added a commit to vadz/wxWidgets that referenced this pull request Apr 28, 2024
Use CRT for dates > 2038 in wxDateTime::Set() if time_t is 64-bit.

See wxWidgets#24464.

Co-authored-by: Vadim Zeitlin <vadim@wxwidgets.org>
@vadz vadz removed the backport-3.2 Fix applied to master but still has to be backported to stable 3.2 label Apr 28, 2024
lanurmi added a commit to lanurmi/wxWidgets that referenced this pull request May 6, 2024
Use CRT for dates > 2038 in wxDateTime::Set() if time_t is 64-bit.

See wxWidgets#24464.

Co-authored-by: Vadim Zeitlin <vadim@wxwidgets.org>
(cherry picked from commit 2c47603)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

tests fail after 2038 Y2K38, wxDateTime::GetTicks(), wxDateTime::IsInStdRange()
2 participants