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

thread 'main' panicked at 'called time::OffsetDateTime::now_local().unwrap() on an Err value: IndeterminateOffset' #427

Closed
zhuxiujia opened this issue Jan 14, 2022 · 10 comments
Labels
C-invalid Category: no issue exists or the issue cannot be reproduced

Comments

@zhuxiujia
Copy link

thread 'main' panicked at 'called Result::unwrap() on an Err value: IndeterminateOffset'

os: MacOS Big Sur

@jhpratt
Copy link
Member

jhpratt commented Jan 14, 2022

The method is fallible for a reason. Don't call .unwrap().

@jhpratt jhpratt closed this as completed Jan 14, 2022
@jhpratt jhpratt added the C-invalid Category: no issue exists or the issue cannot be reproduced label Jan 14, 2022
@zhuxiujia
Copy link
Author

The method is fallible for a reason. Don't call .unwrap().

But can't get local time on MacOS?

@jhpratt
Copy link
Member

jhpratt commented Jan 14, 2022

With the version published on crates.io, no. It will be supported in the next release, but only when the program does not have multiple threads running. You should explicitly handle the error case in any situation.

@zhuxiujia
Copy link
Author

在 crates.io 上发布的版本,没有。它将在下一个版本中支持,但仅限于程序没有运行多个线程时。在任何情况下,您都应该明确处理错误情况。

Ok, now I use the

let mut now = time: : OffsetDateTime: : now_utc ();

let off = UtcOffset::from_whole_seconds(chrono::offset::Local::now().offset().local_minus_utc()).unwrap();

now = now.to_offset(off);

Instead of this.
Perhaps you can refer to chrono's implementation?

@jhpratt
Copy link
Member

jhpratt commented Jan 14, 2022

What chrono does is unsound and can crash your program completely and without warning. It is a security concern. Time does not have this problem. That is why it will be restricted to single-threaded programs in the next release.

@zhuxiujia
Copy link
Author

What chrono does is unsound and can crash your program completely and without warning. It is a security concern. Time does not have this problem. That is why it will be restricted to single-threaded programs in the next release.

So I call this method only if I have a mutex, right? To ensure that it cannot be accessed by multiple threads at the same time

@jhpratt
Copy link
Member

jhpratt commented Jan 14, 2022

That is not correct. If you have multiple threads running, the method will fail on MacOS.

@zhuxiujia
Copy link
Author

zhuxiujia commented Jan 14, 2022

That is not correct. If you have multiple threads running, the method will fail on MacOS.

oh, maybe i should save in to Lazy Global data
for example:

pub const GLOBAL_OFFSET:Lazy<UtcOffset>=Lazy::new(||{
     UtcOffset::from_whole_seconds(chrono::offset::Local::now().offset().local_minus_utc()).unwrap()
});

So time zone data is only fetched once。

thanks

@jhpratt
Copy link
Member

jhpratt commented Jan 14, 2022

If you call chrono::offset::Local::now() with multiple threads running, the result is undefined behavior. Once again, this means your program can crash unexpectedly. Wrapping in Lazy does not change this. There is no way around the multithreaded unsoundness when using the chrono crate. Any manner in which you do so will fail unless you can guarantee that there is only a single thread running — this is what the time crate does.

Chrono is unsound. If you use the time crate, you will not encounter unsoundness. That is a guarantee I provide.

@zhuxiujia
Copy link
Author

zhuxiujia commented Jan 14, 2022

If you call chrono::offset::Local::now() with multiple threads running, the result is undefined behavior. Once again, this means your program can crash unexpectedly. Wrapping in Lazy does not change this. There is no way around the multithreaded unsoundness when using the chrono crate. Any manner in which you do so will fail unless you can guarantee that there is only a single thread running — this is what the time crate does.

Chrono is unsound. If you use the time crate, you will not encounter unsoundness. That is a guarantee I provide.

Ok, this is a temporary solution, pending a new version of Time。
thanks again.

should be this。 (The test will only initialize once)

pub static  GLOBAL_OFFSET: Lazy<UtcOffset> = Lazy::new(|| {
    println!("init time");
    UtcOffset::from_whole_seconds(chrono::offset::Local::now().offset().local_minus_utc()).unwrap()
});

@time-rs time-rs locked as resolved and limited conversation to collaborators Jan 14, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
C-invalid Category: no issue exists or the issue cannot be reproduced
Projects
None yet
Development

No branches or pull requests

2 participants