Crates.io | libtz-sys |
lib.rs | libtz-sys |
version | 0.2.2 |
source | src |
created_at | 2023-01-25 16:36:13.580726 |
updated_at | 2023-01-28 23:14:34.39095 |
description | An FFI interface to IANA's timezone library, libtz |
homepage | |
repository | https://github.com/caldwell/libtz-sys.git |
max_upload_size | |
id | 767603 |
size | 1,788,072 |
Rust FFI interface for IANA's libtz (git repository).
This is a low level library---You will most likely prefer libtz, a more idomatic Rust interface built on top of this.
This provides an equivalent of libc's localtime_r()
function (and related
functions). The difference is that this library has been compiled such that the
getenv("TZ")
call uses Rust's std::env::var_os()
which protects it from
std::env::set_var()
races which could otherwise cause segfaults on systems
that don't provide multithread safe implementations of getenv()
and
setenv()
.
Aside from that it should be a drop in replacement for most libc localtime implementations. It will read the tzdata files that the system has installed to calculate things like leap seconds and daylight saving time.
Links: [Documentation] [Git Repository] [Crates.io]
Add this to your Cargo.toml
:
[dependencies]
libtz-sys = "0.2"
use std::ffi::{CString,CStr};
use std::mem::MaybeUninit;
use libtz_sys::{tzalloc, localtime_rz, mktime_z, tzfree, TimeT, Tm};
let tzname = CString::new("America/New_York").unwrap();
let tz = unsafe { tzalloc(tzname.as_ptr()) };
if tz == std::ptr::null_mut() {
return Err(std::io::Error::last_os_error());
}
let time: TimeT = 127810800;
let mut tm = MaybeUninit::<Tm>::uninit();
let ret = unsafe { localtime_rz(tz, &time, tm.as_mut_ptr()) };
if ret == std::ptr::null_mut() {
return Err(std::io::Error::last_os_error());
}
let tm = unsafe { tm.assume_init() };
let zone: &str = unsafe { CStr::from_ptr(tm.tm_zone).to_str().expect("correct utf8") };
assert_eq!((tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_mday, tm.tm_mon),
(0, 0, 3, 19, 0, ));
assert_eq!((tm.tm_year, tm.tm_wday, tm.tm_yday, tm.tm_isdst, tm.tm_gmtoff, zone),
(74, 6, 18, 1, -14400, "EDT"));
let time_again = unsafe { mktime_z(tz, &tm) }; // Round trip
if time_again == -1 {
// Didn't work (errno is not reliably set in this case)
} else {
assert_eq!(time_again, time);
}
unsafe { tzfree(tz) };
# Ok(())
This is young code and designed to be a backend for
libtz
. It may change rapidly.
The Rust code is distributed under the MIT license.
The libtz code is mostly public domain with a couple files using the BSD-3 clause license.
See LICENSE.md for details.