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

Avoid COM dates that end up with ms=1000, instead rounding to the nex… #1683

Merged
merged 1 commit into from
May 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ Since build 300:
* Fix a bug in `win32profile.GetEnvironmentStrings()` relating to environment
variables with an equals sign (@maxim-krikun in #1661)

* Fixed a bug where certain COM dates would fail to be converted to a Python
datetime object with `ValueError: microsecond must be in 0..999999`. Shoutout
to @hujiaxing for reporting and helping reproduce the issue (#1655)

* Added win32com.shell.SHGetKnownFolderPath() and related constants.

* Shifted work in win32.lib.pywin32_bootstrap to Python's import system from
Expand Down
4 changes: 4 additions & 0 deletions com/win32com/test/testPyComTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,10 @@ def TestCommon(o, is_generated):
later = now + datetime.timedelta(seconds=1)
TestApplyResult(o.EarliestDate, (now, later), now)

# The below used to fail with `ValueError: microsecond must be in 0..999999` - see #1655
# https://planetcalc.com/7027/ says that float is: Sun, 25 Mar 1951 7:23:49 am
assert o.MakeDate(18712.308206013888) == datetime.datetime.fromisoformat("1951-03-25 07:23:49+00:00")

progress("Checking currency")
# currency.
pythoncom.__future_currency__ = 1
Expand Down
9 changes: 7 additions & 2 deletions win32/src/PyTime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,11 +380,16 @@ PyObject *PyWin_NewTime(PyObject *timeOb)
double minutes = (hours - (int)hours) * 60.0;
double seconds = round((minutes - (int)minutes) * 60.0, 4);
double milliseconds = round((seconds - (int)seconds) * 1000.0, 0);
// assert(milliseconds>=0.0 && milliseconds<=999.0);

// Strip off the msec part of time
double TimeWithoutMsecs = t - (ONETHOUSANDMILLISECONDS / 1000.0 * milliseconds);

// We might have rounded ms to 1000 which blows up datetime. Round up
// to the next second.
if (milliseconds >= 1000) {
TimeWithoutMsecs += ONETHOUSANDMILLISECONDS;
milliseconds = 0;
}

// Let the OS translate the variant date/time
SYSTEMTIME st;
if (!VariantTimeToSystemTime(TimeWithoutMsecs, &st)) {
Expand Down