異なるセマンティクス

// Copyright 2026 Google LLC
// SPDX-License-Identifier: Apache-2.0

use std::ffi::{CStr, c_char};
use std::time::{SystemTime, SystemTimeError, UNIX_EPOCH};

unsafe extern "C" {
    /// タイムスタンプ `t` に基づいてフォーマット済みの時刻を作成する。
    fn ctime(t: *const libc::time_t) -> *const c_char;
}

fn now_formatted() -> Result<String, SystemTimeError> {
    let now = SystemTime::now().duration_since(UNIX_EPOCH)?;
    let seconds = now.as_secs() as i64;

    // SAFETY: `seconds` はシステムクロックによって生成されるため、
    // オーバーフローを引き起こしません
    let ptr = unsafe { ctime(&seconds) };

    // SAFETY: ctime は事前に確保された(null ではない)バッファへのポインタを返します
    let ptr = unsafe { CStr::from_ptr(ptr) };

    // SAFETY: ctime は有効な UTF-8 を使用します
    let fmt = ptr.to_str().unwrap();

    Ok(fmt.trim_end().to_string())
}

fn main() {
    let t = now_formatted();
    println!("{t:?}");
}

他の言語で許可されている一部の構成は、Rust 言語では表現できません。

ctime 関数は、呼び出し間で共有される内部バッファを変更します。これは Rust のライフタイムでは表現できません。

  • 'static は適用されません。セマンティクスが異なるためです
  • 'a は適用されません。バッファは各呼び出しより長く生存するためです