Small Rust scripts
at main 77 lines 2.2 kB view raw
1#!/usr/bin/env -S cargo +nightly -Zscript 2 3--- 4[package] 5edition = "2024" 6[dependencies] 7argh = "0.1" 8chrono = "0.4" 9--- 10 11use argh::FromArgs; 12use chrono::{DateTime, Local, NaiveDateTime, TimeZone, Utc}; 13 14#[derive(FromArgs)] 15#[argh(description = "Convert between Unix timestamps and human-readable dates.")] 16struct App { 17 #[argh(switch, description = "use UTC instead of local time.")] 18 utc: bool, 19 20 #[argh(switch, description = "treat timestamp as milliseconds.")] 21 millis: bool, 22 23 #[argh(positional, description = "timestamp, date (YYYY-MM-DD HH:MM:SS), or 'now'.")] 24 input: Option<String>, 25} 26 27fn main() { 28 let app: App = argh::from_env(); 29 let input = app.input.as_deref().unwrap_or("now"); 30 31 match input { 32 "now" => { 33 let now = Utc::now(); 34 if app.millis { 35 println!("{}", now.timestamp_millis()); 36 } else { 37 println!("{}", now.timestamp()); 38 } 39 } 40 s if s.chars().all(|c| c.is_ascii_digit()) => { 41 let ts: i64 = s.parse().expect("invalid timestamp"); 42 let dt = if app.millis { 43 Utc.timestamp_millis_opt(ts).single() 44 } else { 45 Utc.timestamp_opt(ts, 0).single() 46 } 47 .expect("invalid timestamp"); 48 49 if app.utc { 50 println!("{}", dt.format("%Y-%m-%d %H:%M:%S UTC")); 51 } else { 52 let local: DateTime<Local> = dt.into(); 53 println!("{}", local.format("%Y-%m-%d %H:%M:%S")); 54 } 55 } 56 s => { 57 let naive = NaiveDateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S") 58 .expect("expected format: YYYY-MM-DD HH:MM:SS"); 59 60 let dt: DateTime<Utc> = if app.utc { 61 Utc.from_utc_datetime(&naive) 62 } else { 63 Local 64 .from_local_datetime(&naive) 65 .single() 66 .expect("invalid local time") 67 .into() 68 }; 69 70 if app.millis { 71 println!("{}", dt.timestamp_millis()); 72 } else { 73 println!("{}", dt.timestamp()); 74 } 75 } 76 } 77}