evenyag / civil-time

Civil Time library in Rust.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Civil Time

A library ported from the civil_time library in cctz.

This library supports computing with human-scale time, such as dates (which are represented by the CivilDay struct) and can be considered as an supplement to the chrono library. In particular, it provides:

  • Types with different alignments (from second to year).
  • Auto normalization if arguments passed to the constructor are out-of-range.
  • Constant constructors of civil time types.
  • Natural arithmetic operators such as addition, subtraction, and difference.
  • Utilities to get next or previous weekday.

NOTE: Now the API is still unstable and may be changed in the future.

Usage

Put this in your Cargo.toml:

[dependencies]
civil-time = { version = "0.1", git = "https://github.com/evenyag/civil-time.git" }

Overview

The following six structs form the core of this civil-time library:

  • CivilSecond
  • CivilMinute
  • CivilHour
  • CivilDay
  • CivilMonth
  • CivilYear

Each struct is a simple value type with the same six accessors for each of the civil fields (year, month, day, hour, minute, and second, aka YMDHMS). These structs differ in their alignment, which is indicated by the type name and specifies the field on which arithmetic operates.

Construction

Each of the civil-time types can be constructed by default() method, or by directly passing to the constructor up to six integers representing the YMDHMS fields, or by Builder::build.

use civil_time::{Builder, CivilDay, CivilHour, CivilMinute, CivilMonth, CivilSecond, CivilYear};

// Default value is "1970-01-01 00:00:00"
let default_value = CivilDay::default();
assert_eq!("1970-01-01", format!("{:?}", default_value));

// Constructed by new(), e.g. "2015-02-03 00:00:00"
let a = CivilDay::new(2015, 2, 3);
assert_eq!("2015-02-03", format!("{:?}", a));

// Constructed by Builder, e.g. "2015-01-01 00:00:00"
let b = Builder::new().year(2015).build_day();
assert_eq!("2015-01-01", format!("{:?}", b));

// Constructed by Builder::build(), e.g. "2015-02-03 00:00:00"
let c: CivilDay = Builder::new()
    .year(2015)
    .month(2)
    .day(3)
    .hour(4)
    .minute(5)
    .second(6)
    .build();
assert_eq!("2015-02-03", format!("{:?}", c));

// e.g. "2015-02-03 04:05:06"
let ss = CivilSecond::new(2015, 2, 3, 4, 5, 6);
assert_eq!("2015-02-03T04:05:06", format!("{:?}", ss));

// e.g. "2015-02-03 04:05:00"
let mm = CivilMinute::new(2015, 2, 3, 4, 5);
assert_eq!("2015-02-03T04:05", format!("{:?}", mm));

// e.g. "2015-02-03 04:00:00"
let hh = CivilHour::new(2015, 2, 3, 4);
assert_eq!("2015-02-03T04", format!("{:?}", hh));

// e.g. "2015-02-03 00:00:00"
let d = CivilDay::new(2015, 2, 3);
assert_eq!("2015-02-03", format!("{:?}", d));

// e.g. "2015-02-01 00:00:00"
let m = CivilMonth::new(2015, 2);
assert_eq!("2015-02", format!("{:?}", m));

// e.g. "2015-01-01 00:00:00"
let y = CivilYear::new(2015);
assert_eq!("2015", format!("{:?}", y));

Normalization

Integer arguments passed to the new() constructor may be out-of-range, in which case they are normalized to produce a valid civil-time struct. This enables natural arithmetic on new() arguments without worrying about the field's range. Normalization guarantees that there are no invalid civil-time structs.

use civil_time::CivilDay;

// Out-of-range day; normalized to 2016-11-01
let d = CivilDay::new(2016, 10, 32);
assert_eq!("2016-11-01", format!("{:?}", d));

Arithmetic

Arithmetic operates on the civil-time field indicated in the type's name. Difference requires arguments with the same alignment and returns the answer in units of the alignment.

use civil_time::{CivilDay, CivilMonth};

let mut a = CivilDay::new(2015, 2, 3);
a += 1;
assert_eq!("2015-02-04", format!("{:?}", a));
a -= 1;
assert_eq!("2015-02-03", format!("{:?}", a));

let b = a + 1;
assert_eq!("2015-02-04", format!("{:?}", b));
let c = b + 1;
assert_eq!("2015-02-05", format!("{:?}", c));

let n = c - a;
assert_eq!(2, n);
// let m = c - CivilMonth::from(c); // Won't compile: different types.

Weekday

Returns the CivilDay that strictly follows or precedes the given CivilDay, and that falls on the given weekday.

use civil_time::{CivilDay, Weekday};

let a = CivilDay::new(2015, 8, 13);
assert_eq!(Weekday::Thu, a.weekday());
let b = a.next_weekday(Weekday::Thu);
assert_eq!("2015-08-20", format!("{:?}", b));
let c = a.prev_weekday(Weekday::Thu);
assert_eq!("2015-08-06", format!("{:?}", c));

let d = a - 1;
// Gets the following Thursday if d is not already Thursday
let thurs1 = d.next_weekday(Weekday::Thu);
assert_eq!("2015-08-13", format!("{:?}", thurs1));
//  Gets the previous Thursday if d is not already Thursday
let d = a + 1;
let thurs2 = d.prev_weekday(Weekday::Thu);
assert_eq!("2015-08-13", format!("{:?}", thurs2));

About

Civil Time library in Rust.


Languages

Language:Rust 100.0%