In order to obtain the local time offset, [time](https://crates.io/crates/time) calls out to `libc`s `localtime_r` function. Implementations of `localtime_r`, like `glibc` and `musl`, call `getenv("TZ")` to obtain the current value for the `TZ` environment variable. Unfortunately, values returned by `getenv()` can be invalidated by calls that modify the environment, like `setenv()`, `unsetenv()`, or `putenv()`. For example, the following single-threaded application has a potential use after free bug: ```c char * value = getenv("KEY"); // obtain pointer setenv("KEY", "new value"); // potential free printf("KEY = %s", value); // potential use after free ``` The functions in Rust's `std::env` module synchronize access to the environment through a lock. However, any foreign code (including `libc` implementations) is free to modify the environment without acquiring that lock. This has led to discussion about whether Rust's [`std::env::set_var` should be marked unsafe](https://internals.rust-lang.org/t/synchronized-ffi-access-to-posix-environment-variable-functions/15475/19). Under the assumption that accessing the environment is implemented correctly everywhere for single-threaded programs, there can only be issues in multi-threaded programs. This is why the [time](https://crates.io/crates/time) crate lets you obtain the UTC offset while the number of threads is 1. This crate provides a solution for applications that can accept using a cached value of the UTC offset by doing exactly that: caching the UTC offset at the time of invocation. Here is an example: ```rust use time_local::{OffsetDateTimeExt, UtcOffsetExt}; fn main() { time_local::init().expect("initialization should succeed before spawning threads"); let date = std::thread::spawn(|| { // We can not convert a date time to it's local representation. assert!(time::OffsetDateTime::now_utc() .to_local() .is_err(), "to_local should fail"); // We can use the cached UTC offset computed at application startup. Note that this is computing something // different entirely, but it may be good enough for your application. time::OffsetDateTime::now_utc().to_offset(time::UtcOffset::cached_local_offset()) }) .join() .expect("thread should not panic"); println!("{date:?}") } ``` Note that a UTC offset depends on both the timezone and a particular date and time. The cached UTC offset is computed from the current machine's timezone and time. Changes to the system's local time and/or the `TZ` environment variable will not be reflected by the cached UTC offset, and the cached UTC offset used in `.to_local()` does not depend on the `OffsetDateTime`. See https://github.com/time-rs/time/issues/688#issue-2346267822 for origins.