work not v0.1.0
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "simpledateformat"
|
name = "simpledateformat"
|
||||||
version = "0.0.0"
|
version = "0.1.0"
|
||||||
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "SimpleDateFormat.java style like date format"
|
description = "SimpleDateFormat.java style like date format"
|
||||||
|
|||||||
18
README.md
18
README.md
@@ -3,5 +3,21 @@
|
|||||||
SimpleDateFormat.java style like date format
|
SimpleDateFormat.java style like date format
|
||||||
|
|
||||||
|
|
||||||
Working in progress ...
|
Usage:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let f = match fmt("yyyy-MM-dd HH:mm:ss z") {
|
||||||
|
Ok(f) => f, Err(err) => {
|
||||||
|
println!("Parse fmt error: {}", err);
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
println!("Formated date: {}", f.format(&Local::now()));
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
```
|
||||||
|
Formated date: 2020-05-30 13:32:04 +08:00
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
81
src/lib.rs
81
src/lib.rs
@@ -1,8 +1,6 @@
|
|||||||
#[macro_use] extern crate quick_error;
|
#[macro_use] extern crate quick_error;
|
||||||
use chrono::{ Local,prelude::*, };
|
use chrono::prelude::*;
|
||||||
|
use std::{ str::Chars, iter::Peekable };
|
||||||
use std::str::Chars;
|
|
||||||
use std::iter::Peekable;
|
|
||||||
|
|
||||||
quick_error! {
|
quick_error! {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -15,14 +13,19 @@ quick_error! {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum SimpleDateFormatPart {
|
enum SimpleDateFormatPart {
|
||||||
YearLower(usize),
|
Ear,
|
||||||
YearUpper(usize),
|
Year(usize),
|
||||||
Month(usize),
|
Month(usize),
|
||||||
Day(usize),
|
Day(usize),
|
||||||
HourLower(usize),
|
HourLower(usize),
|
||||||
HourUpper(usize),
|
HourUpper(usize),
|
||||||
Minute(usize),
|
Minute(usize),
|
||||||
Second(usize),
|
Second(usize),
|
||||||
|
Millis(usize),
|
||||||
|
AmPm(usize),
|
||||||
|
WeekDay(usize),
|
||||||
|
YearDay(usize),
|
||||||
|
Zone(usize),
|
||||||
LiteralChar(char),
|
LiteralChar(char),
|
||||||
Literal(String),
|
Literal(String),
|
||||||
}
|
}
|
||||||
@@ -34,14 +37,16 @@ pub struct SimpleDateFormat {
|
|||||||
|
|
||||||
impl SimpleDateFormat {
|
impl SimpleDateFormat {
|
||||||
|
|
||||||
pub fn format_local(&self, date_time: &DateTime<Local>) -> String {
|
pub fn format<Tz>(&self, date_time: &DateTime<Tz>) -> String where Tz: TimeZone {
|
||||||
let mut ret = String::with_capacity(512);
|
let mut ret = String::with_capacity(512);
|
||||||
|
|
||||||
for part in &self.parts {
|
for part in &self.parts {
|
||||||
|
date_time.timezone();
|
||||||
match part {
|
match part {
|
||||||
|
SimpleDateFormatPart::Ear => ret.push_str("AD"), // ?
|
||||||
SimpleDateFormatPart::LiteralChar(c) => ret.push(*c),
|
SimpleDateFormatPart::LiteralChar(c) => ret.push(*c),
|
||||||
SimpleDateFormatPart::Literal(s) => ret.push_str(s),
|
SimpleDateFormatPart::Literal(s) => ret.push_str(s),
|
||||||
SimpleDateFormatPart::YearLower(cnt) => ret.push_str(&format_str(date_time.year(), *cnt)),
|
SimpleDateFormatPart::Year(cnt) => ret.push_str(&format_year(date_time.year(), *cnt)),
|
||||||
SimpleDateFormatPart::Month(cnt) => if *cnt <= 2 {
|
SimpleDateFormatPart::Month(cnt) => if *cnt <= 2 {
|
||||||
ret.push_str(&format_str(date_time.month() as i32, *cnt))
|
ret.push_str(&format_str(date_time.month() as i32, *cnt))
|
||||||
} else {
|
} else {
|
||||||
@@ -52,7 +57,11 @@ impl SimpleDateFormat {
|
|||||||
SimpleDateFormatPart::HourUpper(cnt) => ret.push_str(&format_str(date_time.hour() as i32, *cnt)),
|
SimpleDateFormatPart::HourUpper(cnt) => ret.push_str(&format_str(date_time.hour() as i32, *cnt)),
|
||||||
SimpleDateFormatPart::Minute(cnt) => ret.push_str(&format_str(date_time.minute() as i32, *cnt)),
|
SimpleDateFormatPart::Minute(cnt) => ret.push_str(&format_str(date_time.minute() as i32, *cnt)),
|
||||||
SimpleDateFormatPart::Second(cnt) => ret.push_str(&format_str(date_time.second() as i32, *cnt)),
|
SimpleDateFormatPart::Second(cnt) => ret.push_str(&format_str(date_time.second() as i32, *cnt)),
|
||||||
_ => (),
|
SimpleDateFormatPart::Millis(cnt) => ret.push_str(&format_str((date_time.nanosecond() / 1_000_000) as i32, *cnt)),
|
||||||
|
SimpleDateFormatPart::AmPm(cnt) => ret.push_str(format_ampm(date_time.hour12().0, *cnt)),
|
||||||
|
SimpleDateFormatPart::WeekDay(cnt) => ret.push_str(format_week_day(date_time.weekday(), *cnt)),
|
||||||
|
SimpleDateFormatPart::YearDay(cnt) => ret.push_str(&format_str(date_time.ordinal() as i32, *cnt)),
|
||||||
|
SimpleDateFormatPart::Zone(cnt) => ret.push_str(&format_zone(date_time, *cnt)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret
|
ret
|
||||||
@@ -87,14 +96,19 @@ pub fn fmt(f: &str) -> Result<SimpleDateFormat, ParseError> {
|
|||||||
is_in_quotation_mark = true;
|
is_in_quotation_mark = true;
|
||||||
},
|
},
|
||||||
',' | '.' | ':' | '-' | ' ' | '/' => parts.push(SimpleDateFormatPart::LiteralChar(c)),
|
',' | '.' | ':' | '-' | ' ' | '/' => parts.push(SimpleDateFormatPart::LiteralChar(c)),
|
||||||
'y' => parts.push(SimpleDateFormatPart::YearLower(get_all_chars(c, &mut chars))),
|
'G' => parts.push(SimpleDateFormatPart::Ear),
|
||||||
'Y' => parts.push(SimpleDateFormatPart::YearUpper(get_all_chars(c, &mut chars))),
|
'y' => parts.push(SimpleDateFormatPart::Year(get_all_chars(c, &mut chars))),
|
||||||
'M' => parts.push(SimpleDateFormatPart::Month(get_all_chars(c, &mut chars))),
|
'M' => parts.push(SimpleDateFormatPart::Month(get_all_chars(c, &mut chars))),
|
||||||
'd' => parts.push(SimpleDateFormatPart::Day(get_all_chars(c, &mut chars))),
|
'd' => parts.push(SimpleDateFormatPart::Day(get_all_chars(c, &mut chars))),
|
||||||
'h' => parts.push(SimpleDateFormatPart::HourLower(get_all_chars(c, &mut chars))),
|
'h' => parts.push(SimpleDateFormatPart::HourLower(get_all_chars(c, &mut chars))),
|
||||||
'H' => parts.push(SimpleDateFormatPart::HourUpper(get_all_chars(c, &mut chars))),
|
'H' => parts.push(SimpleDateFormatPart::HourUpper(get_all_chars(c, &mut chars))),
|
||||||
'm' => parts.push(SimpleDateFormatPart::Minute(get_all_chars(c, &mut chars))),
|
'm' => parts.push(SimpleDateFormatPart::Minute(get_all_chars(c, &mut chars))),
|
||||||
's' => parts.push(SimpleDateFormatPart::Second(get_all_chars(c, &mut chars))),
|
's' => parts.push(SimpleDateFormatPart::Second(get_all_chars(c, &mut chars))),
|
||||||
|
'S' => parts.push(SimpleDateFormatPart::Millis(get_all_chars(c, &mut chars))),
|
||||||
|
'a' => parts.push(SimpleDateFormatPart::AmPm(get_all_chars(c, &mut chars))),
|
||||||
|
'E' => parts.push(SimpleDateFormatPart::WeekDay(get_all_chars(c, &mut chars))),
|
||||||
|
'D' => parts.push(SimpleDateFormatPart::YearDay(get_all_chars(c, &mut chars))),
|
||||||
|
'z' => parts.push(SimpleDateFormatPart::Zone(get_all_chars(c, &mut chars))),
|
||||||
_ => return Err(ParseError::Format(format!("Illegal char: {}", c))),
|
_ => return Err(ParseError::Format(format!("Illegal char: {}", c))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,6 +116,32 @@ pub fn fmt(f: &str) -> Result<SimpleDateFormat, ParseError> {
|
|||||||
Ok(SimpleDateFormat{ parts })
|
Ok(SimpleDateFormat{ parts })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn format_zone<Tz>(date_time: &DateTime<Tz>, _cnt: usize) -> String where Tz: TimeZone {
|
||||||
|
format!("{:?}", date_time.offset())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_ampm(is_pm: bool, _cnt: usize) -> &'static str {
|
||||||
|
if is_pm { "PM" } else { "AM" }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_week_day(n: Weekday, cnt: usize) -> &'static str {
|
||||||
|
let is_short = cnt == 3;
|
||||||
|
match n {
|
||||||
|
Weekday::Mon => if is_short { "Mon" } else { "Monday" },
|
||||||
|
Weekday::Tue => if is_short { "Tue" } else { "Tuesday" },
|
||||||
|
Weekday::Wed => if is_short { "Wed" } else { "Wednesday" },
|
||||||
|
Weekday::Thu => if is_short { "Thu" } else { "Thursday" },
|
||||||
|
Weekday::Fri => if is_short { "Fri" } else { "Friday" },
|
||||||
|
Weekday::Sat => if is_short { "Sat" } else { "Saturday" },
|
||||||
|
Weekday::Sun => if is_short { "Sun" } else { "Sunday" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_year(n: i32, cnt: usize) -> String {
|
||||||
|
let y = if cnt == 2 { n % 100 } else { n };
|
||||||
|
format_str(y, cnt)
|
||||||
|
}
|
||||||
|
|
||||||
fn format_month(n: u32, cnt: usize) -> &'static str {
|
fn format_month(n: u32, cnt: usize) -> &'static str {
|
||||||
let is_short = cnt == 3;
|
let is_short = cnt == 3;
|
||||||
match n {
|
match n {
|
||||||
@@ -145,10 +185,21 @@ fn get_all_chars(c: char, chars: &mut Peekable<Chars>) -> usize {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_works() {
|
fn it_works() {
|
||||||
// println!("test output: {}", fmt("").unwrap().format_local(&Local::now()));
|
let t = Utc.timestamp_millis(0);
|
||||||
|
assert_eq!("1970/01/01 00:00:00.000 Z", &fmt("yyyy/MM/dd HH:mm:ss.SSS z").unwrap().format(&t));
|
||||||
|
|
||||||
println!("{:?}", fmt("y yy-mm 'mm '''"));
|
let t = Utc.timestamp_millis(1111111111);
|
||||||
println!("{:?}", fmt("yyyy-MM-dd HH:mm:ss MMM dd, yyyy hh:mm:ss").unwrap().format_local(&Local::now()));
|
assert_eq!("1970/01/13 20:38:31.111 Z", &fmt("yyyy/MM/dd HH:mm:ss.SSS z").unwrap().format(&t));
|
||||||
|
|
||||||
assert_eq!(2 + 2, 4);
|
let t = Utc.timestamp_millis(1111111111);
|
||||||
|
assert_eq!("1970/01/13 08:38:31.111 Z PM", &fmt("yyyy/MM/dd hh:mm:ss.SSS z a").unwrap().format(&t));
|
||||||
|
|
||||||
|
let t = Utc.timestamp_millis(1590816448678);
|
||||||
|
assert_eq!("2020/05/30 05:27:28.678 Z AM", &fmt("yyyy/MM/dd hh:mm:ss.SSS z a").unwrap().format(&t));
|
||||||
|
|
||||||
|
let t = Utc.timestamp_millis(1590816448678);
|
||||||
|
assert_eq!("Sat May 30, 2020 05:27:28.678 Z AM", &fmt("EEE MMM dd, yyyy hh:mm:ss.SSS z a").unwrap().format(&t));
|
||||||
|
|
||||||
|
let t = Local.timestamp_millis(1590816448678);
|
||||||
|
assert_eq!("Sat May 30, 2020 01:27:28.678 +08:00 PM", &fmt("EEE MMM dd, yyyy hh:mm:ss.SSS z a").unwrap().format(&t));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user