root/src/main.rs

// main.rs
//
// Copyright 2021-2023 nee <nee-git@patchouli.garden>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later

use chrono::prelude::*;
use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();

    if args.iter().any(|i| i == "--help") {
        println!("frdate is a commandline tool for printing French Revolutionary Calendar dates and decimal time.

Call with `frdate [ARGUMENTS]... [FORMAT]`.

Valid ARGUMENTS are:

\t--html
\t\tPrints default message with a html a-href wikipedia link.

\t--help
\t\tPrint this message

\t-u, --utc, --universal
\t\tUse UTC as the timezone. UTC is the Coordinated Universal Time.
\t\tWithout this argument the system's local timezone is used.

Valid FORMATS are:

FORMATS custom to `frdate` not consistant with `date(1)` that might change in the future:

  %dth \t day with 'nth' attachment (e.g., 2nd)
  %di \t day as number without prefix (e.g., 2)
  %L \t Link to wikipedia for thing of the day (e.g., https://en.wikipedia.org/wiki/Lily_of_the_valley)
  %f \t fractional time (percentage of the day passed) (e.g., 0.46597)
  %name\t label of the thing of the day (e.g., Lily of the valley)

FORMATS that are mostly consistant with `date(1)`:

* WARNING most of these are very listlessly implemented right now *

  %% \t prints a literal %
  %a \t abbreviated weekday name (e.g., Pri)
  %A \t full weekday name (e.g., Primidi)
  %b \t abbreviated month name (e.g., Vend)
  %B \t full month name (e.g., January)
  %C \t century; like %Y, except omit last two digits (e.g., 2)
  %d \t day of month (e.g., 01)
  %D \t date; same as %m/%d/%y
  %e \t day of month, space padded; same as %_d
  %F \t full date; same as %Y-%m-%d
  %h \t same as %b
  %H \t hour (0..9)
  %I \t same as %H
  %j \t day of year (0..366)
  %k \t hour, space padded ( 0..9); same as %_H
  %l \t same as %k
  %m \t month (1..13)
  %M \t minute (0..99)
  %n \t a newline
  %N \t nanoseconds (0..999999999) (still in standard time, might change later)
  %p \t does nothing
  %P \t does nothing
  %R \t hour and minute; same as %H:%M
  %S \t second (0..99)
  %t \t a tab
  %T \t time; same as %H:%M:%S
  %r \t time; same as %H:%M:%S
  %u \t number of the day of the week (1..10); 1 is Primidi
  %w \t number of the day of the week (0..9); 0 is Primidi
  %y \t last two digits of year (0..99)
  %Y \t year (e.g., 233)

I tried to keep most options from the standard `date` commandline program.
Some of the date FORMATS make no sense for decimal time like AM/PM
and just print nothing, or the same as the most simliar fallback format.
Example: 24h format will print the same as 12h format.

Homepage: https://patchouli.garden/git/frdate
About the calendar: https://en.wikipedia.org/wiki/French_Revolutionary_calendar
License: GPL-3.0-or-later
");
        return;
    }

    let use_utc = args
        .iter()
        .any(|i| i == "-u" || i == "--utc" || i == "--universal");

    let now_naive = if use_utc {
        Utc::now().naive_local()
    } else {
        Local::now().naive_local()
    };
    let fr = frdate::FrDate::from(now_naive.date());
    let dt = frdate::DecimalTime::from(now_naive.time());
    // or just use let (dt, fr) = frdate::now();

    if args.iter().any(|i| i == "--html") {
        frdate::print_format(
            &fr,
            &dt,
            "Today is the %dth of %B in %Y. It's the day of the <a href=\"%L\">%name</a>.",
        );
        return;
    }

    if args.len() > 1 {
        if let Some(format_str) = args.last() {
            if !format_str.starts_with("-") {
                frdate::print_format(&fr, &dt, format_str);
                return;
            }
        }
    }

    frdate::print_format(
        &fr,
        &dt,
        "It's %T, today is the %dth of %B in %Y. It's the day of the %name.",
    );
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn hi() {
        main();
    }
}