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

fix timestamp_local() #44

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

dimbleby
Copy link
Contributor

cf #43

@Techcable
Copy link
Member

Strangely I get an indeterminate offset error on my local machine as well.

I will have to look into this more (also thank you for the PR 😄 )

@ohmyarch
Copy link

ohmyarch commented Mar 1, 2022

The time displayed now is actually UTC, which should be a bug.

Techcable added a commit that referenced this pull request Mar 1, 2022
remove unused time features

This is fine to merge right now. I want to look at #44 more closely because it addresses a very serious bug

However, I'm not sure the solution works because I get an error on my local machine and on Github Actions :(
@Techcable
Copy link
Member

I asked why this is failing in time-rs/time#455 and got this response:

The method will fail on Unix systems when multiple threads are running. This is because it is otherwise unsound. For libraries, there is no workaround because you have no way of knowing what the end user will do with regard to threads.

So unfortunately it appears we are either:
A. Stuck with UTC
B. Have a programatic API to explicitly specify the timezone offset (working around the multiple threads problem)

@Techcable
Copy link
Member

Techcable commented May 23, 2022

I think we could override the use_local_timestamp method to accept a user-specified time offset.

This would allow workaround the nasty soundness issues of the underlying system methods.

Then we could just have UTC for time values (by default).

Technically requiring an explicit offset is a breaking change. However it isn't really breaking because the code relying on system offset was never sound before. I am not sure if the previous impl was silently unsound or always gave an error. I will have to go back and check......

@yaozongyou
Copy link

after some dig, the time crate using libc's localtime_r function to convert a timestamp to the user's specified timezone localtime, and as the manual suggests: for portable code, tzset(3) should be called before localtime_r(). And tzset function settting environment variable is not thread safe, so this is the problem:
https://github.com/time-rs/time/blob/500f8e4517cb89f0aa80087130ed2f8b8349f162/time/src/sys/local_offset_at/unix.rs#L147

Maybe we can switch depency from time to chrono, the chrono has no such limitations, the chrono do not using localtime_r, it gets localtime's timezone with TZ environment variable and fall back to /etc/localtime config.

@Jarsop
Copy link

Jarsop commented Sep 28, 2023

Hello, regardless of the fact that time uses a method that is not thread safe, a simple test (single threaded) highlights the conversion problem.

Code:

fn main() {
    println!(
        "Into::<time::OffsetDateTime>::into(std::time::SystemTime::now()): {:?}",
        Into::<time::OffsetDateTime>::into(std::time::SystemTime::now())
    );
    println!(
        "time::OffsetDateTime::now_utc(): {:?}",
        time::OffsetDateTime::now_utc()
    );
    println!(
        "time::OffsetDateTime::now_local(): {:?}",
        time::OffsetDateTime::now_local().unwrap()
    );
}

Output:

Into::<time::OffsetDateTime>::into(std::time::SystemTime::now()): 2023-09-28 21:07:56.911696843 +00:00:00
time::OffsetDateTime::now_utc(): 2023-09-28 21:07:56.91171041 +00:00:00
time::OffsetDateTime::now_local(): 2023-09-28 23:07:56.911713926 +02:00:00

So II think the method used so far to handle local time doesn't work :)

@Techcable
Copy link
Member

I just had an idea on how to fix the default time formatting without breaking backwards compatibility.

The new default formatting will include an explicit UTC timezone specifier, so it will be clear it's not in local time.

This will avoid the unsafety of getting the localtime when multiple threads are involved.

Techcable added a commit to Techcable/slog-term that referenced this pull request Feb 18, 2024
As discussed in PR slog-rs#44, the 'time' crate fails timezine detection
in the prsesense of multiple threads, because the underlying
POSIX function localtime_r is not thread safe (at least not on Linux).

In order to avoid these thread-safety issues,
we use the chrono crate. It avoids system libraries
and reimplements timezone detection from scratch.
(Thanks to @yaozongyou for pointing this out)

TODO: Maybe we should switch to chono entirely.
It seems to be a fairly complete replacement.
What are the advantages & disadvantages?
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.

5 participants