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

SystemTimeToTzSpecificLocalTime failed with: The parameter is incorrect. (os error 87) #651

Closed
andrewbanchich opened this issue Feb 17, 2022 · 7 comments
Labels

Comments

@andrewbanchich
Copy link

We're getting a panic from chrono here when run on a Windows 2012 server:

thread '<unnamed>' panicked at 'SystemTimeToTzSpecificLocalTime failed with: The parameter is incorrect. (os error 87)',
/cargo/registry/src/git.luolix.top-1ecc6299db9ec823/chrono-0.4.19/src/sys/windows.rs:97:9
stack backtrace:
   0: rust_begin_unwind
             at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b\/library\std\src/panicking.rs:498:5
   1: core::panicking::panic_fmt
             at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b\/library\core\src/panicking.rs:107:14
   2: chrono::sys::inner::time_to_local_tm
   3: <chrono::offset::local::Local as chrono::offset::TimeZone>::from_utc_datetime
   4: <chrono::datetime::DateTime<chrono::offset::local::Local> as core::convert::From<std::time::SystemTime>>::from
...

We debugged the SystemTime we were getting and it was:

SystemTime {
    intervals: 147221225472,
}

A normal intervals value (e.g. 132790361186042732) is much larger.

I'm assuming there's something about this unusually short SystemTime that's causing chrono to panic.

@annmarie-switzer
Copy link

use std::{io, mem};
use winapi::{shared::minwindef::*, um::timezoneapi::*};

fn main() {
    // works - 132790361186042732
    // fails - 147221225472

    let t = 147221225472 as u64;

    let ft = FILETIME {
        dwLowDateTime: t as DWORD,
        dwHighDateTime: (t >> 32) as DWORD,
    };

    unsafe {
        let mut utc = mem::zeroed();
        let mut local = mem::zeroed();

        FileTimeToSystemTime(&ft, &mut utc);

        dbg!(&utc.wYear); // 1601
        dbg!(&utc.wMonth); // 1
        dbg!(&utc.wDayOfWeek); // 1 (Monday)
        dbg!(&utc.wDay); // 1
        dbg!(&utc.wHour);
        dbg!(&utc.wMinute);
        dbg!(&utc.wSecond);
        dbg!(&utc.wMilliseconds);

        SystemTimeToTzSpecificLocalTime(0 as *const _, &mut utc, &mut local); // returns 0 (failure)
        dbg!(io::Error::last_os_error()); // InvalidInput
    }
}

Those debug statements tell you that the SystemTime is January 1, 1601. And while that seems totally ridiculous, it should be a valid date according to Microsoft documentation. Despite this, passing that value to SystemTimeToTzSpecificLocalTime triggers an InvalidInput error:

[src\main.rs:31] io::Error::last_os_error() = Os {
    code: 87,
    kind: InvalidInput,
    message: "The parameter is incorrect.",       
}

@andrewbanchich
Copy link
Author

This seems to be an issue with something lower level having to do with Windows, so I'm going to close this.

We opened an issue in the official windows crate repo.

@andrewbanchich
Copy link
Author

Actually, I'm reopening this since based on the feedback from that issue it looks like the problem might be more in chrono's domain.

@djc
Copy link
Member

djc commented Mar 23, 2022

I'm unable to test on Windows myself. I'd be happy to review any code changes that are supported with documentation and/or explanation why they improve the current situation, but I probably won't be able to work on this proactively.

Let me know if you need any guidance on how to fix chrono to support this scenario better.

@andrewbanchich
Copy link
Author

@annmarie-switzer should have the fix for this. Unfortunately, I don't have the code and also am unable to test on Windows.

@rgwood
Copy link

rgwood commented Jul 25, 2022

Just adding some additional info:

We (Nushell) recently got a bug report where this panic was occurring when the user ran ls ~/Downloads (which uses chrono for file modified times).

The culprit ended up being a file named NUL (which should not exist, cannot be created manually, and was probably created by some buggy third-party software; NUL is a reserved name). To fix the issue the user just deleted the file.

@pitdicker
Copy link
Collaborator

While #1150 is a duplicate of this issue, it becomes a bit more specific on what to fix.
Closing this issue as a duplicate.

@pitdicker pitdicker reopened this Jul 5, 2023
@pitdicker pitdicker closed this as not planned Won't fix, can't repro, duplicate, stale Jul 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants