Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plus_months function of the DateLike trait #474

Closed
ghost opened this issue Aug 21, 2020 · 5 comments
Closed

plus_months function of the DateLike trait #474

ghost opened this issue Aug 21, 2020 · 5 comments

Comments

@ghost
Copy link

ghost commented Aug 21, 2020

Is there a way to add some number of months to NaiveDate? I'm looking for something with the following behavior

assert_eq!(NaiveDate::from_ymd(2015,  1,  5).add_months(10), Some(NaiveDate::from_ymd(2015,  11,  5)));
assert_eq!(NaiveDate::from_ymd(2015,  1,  31).add_months(1), None);

Is it currently implemented somewhere?

@quodlibetor
Copy link
Contributor

Unfortunately not, the closest you can get is adding days or durations.

@doivosevic
Copy link

+1 on this and probably related to #52

Would be nice to be able to get last month

@zwq1792966796
Copy link

use chrono::{ Datelike, NaiveDate, ParseResult};
fn main() {

let fmt = "%Y-%m-%d";
//

let str_date: String = "2020-12-1".to_string(); // 2021-01-04 20:02:09
println!("now: {}", str_date);
//
let result: ParseResult<NaiveDate> = NaiveDate::parse_from_str(str_date.as_str(), fmt);
if result.is_err() {
    result.expect("parse error");
}
let date: NaiveDate = result.unwrap();


println!("time: {}, parsed from:'{}'", date, str_date);

println!("{}",year_add(&date,1));
println!("{}",month_add(&date,11));
//

println!("{}",-5/12);
println!("{}",-5%12);

let mut v=vec![];
let t=["2020-1-1",
    "2020-1-31",
    "2020-2-1",
    "2020-2-29",
    "2020-3-1",
    "2020-3-31",
    "2020-4-1",
    "2020-4-30",
    "2020-5-1",
    "2020-5-31",
    "2020-6-1",
    "2020-6-30",
    "2020-7-1",
    "2020-7-31",
    "2020-8-1",
    "2020-8-31",
    "2020-9-1",
    "2020-9-30",
    "2020-10-1",
    "2020-10-31",
    "2020-11-1",
    "2020-11-30",
    "2020-12-1",
    "2020-12-31",
];
for i in &t {
    let result: ParseResult<NaiveDate> = NaiveDate::parse_from_str(i, fmt);
    if result.is_err() {
        result.expect("parse error");
        break;
    }
    let date: NaiveDate = result.unwrap();
    v.push(date);
}
for i in v.iter() {
    //println!("{}",i);
    for j in  -48..=48 {
        println!("{}+{}====={}",i.to_string(),j,month_add(i,j));
    }
    println!("======================================")
}

}

fn year_add(date:&NaiveDate,i:i32)->String {
let month=date.month();
let day=date.day();
//is_leap_year(date.year())
match is_leap_year(date.year()) {
true=>match is_leap_year(date.year()+i){
true=>{
format!("{}-{}-{}",date.year()+i,month,day)
},
false=>{
if month==2&&day==29 {
format!("{}-{}-{}",date.year()+i,month,day-1)
}else{
format!("{}-{}-{}",date.year()+i,month,day)
}

        }
    },
    false=>match is_leap_year(date.year()+i){
        true=>{
            if month==2&&day==28 {
                format!("{}-{}-{}",date.year()+i,month,day+1)
            }else{
                format!("{}-{}-{}",date.year()+i,month,day)
            }
        },
        false=>{
            format!("{}-{}-{}",date.year()+i,month,day)  
        }
    }
} 

}
fn is_leap_year(year:i32)->bool{
match year%100{
0=>match year%400{
0=>true,
_=>false,

    },
    _=>match year%4{
        0=>true,
        _=>false           
    }
}

}

fn month_add(date:&NaiveDate,i:i32)->String {
//
let year=date.year() as i32;
let month=date.month() as i32;
let day=date.day() as i32;
// if i==0 {
// date.format("%Y-%m-%d").to_string()
// }else if i>0{
// is_positive(year,month,day,i)
// }else {
// is_negative(year,month,day,i)
// }
if i==0 {
format!("{}-{}-{}",year,month,day)
}else {
let dest_year=year+(month+i)/12;
let dest_month=(month+i)%12;
match dest_month{
0=>{
format!("{}-{}-{}",dest_year-1,12,day)
},
-2|-4|-5|-7|-9|-11=>{
format!("{}-{}-{}",dest_year-1,12+dest_month,day)
},
-1|-3|-6|-8=>{
match day {
31=>{format!("{}-{}-{}",dest_year-1,12+dest_month,30)},
_=>{format!("{}-{}-{}",dest_year-1,12+dest_month,day)},
}
},
-10=>{
match day {
29|30|31=>{
if is_leap_year(dest_year-1){
format!("{}-{}-{}",dest_year-1,12+dest_month,29)
}else {
format!("{}-{}-{}",dest_year-1,12+dest_month,28)
}
},
_=>{format!("{}-{}-{}",dest_year-1,12+dest_month,day)},
}
},
1|3|5|7|8|10=>{
format!("{}-{}-{}",dest_year,dest_month,day)
},
2=>{
if is_leap_year(dest_year) {
match day {
29|30|31=>{
format!("{}-{}-{}",dest_year,dest_month,29)
},
_=>{
format!("{}-{}-{}",dest_year,dest_month,day)
},
}
}else {
match day {
29|30|31=>{
format!("{}-{}-{}",dest_year,dest_month,28)
},
_=>{
format!("{}-{}-{}",dest_year,dest_month,day)
},
}
}
},
4|6|9|11=>{
match day {
31=>format!("{}-{}-{}",dest_year,dest_month,30),
_=>format!("{}-{}-{}",dest_year,dest_month,day)
}
},
_=>{"error".to_string()},
}
}

}

@esheppa
Copy link
Collaborator

esheppa commented Aug 17, 2022

@doivosevic and @dmitriibundin - I know it's been a while, but does #731 solve your use case?

@pitdicker
Copy link
Collaborator

Added in #731.

@djc djc closed this as completed Jun 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants