2017-01-16 5 views
0

В Python3, я могу цикл по диапазону дат, как этотЦикл по диапазону дат

import datetime 

dt0 = datetime.datetime(2017, 1, 1, 0, 0, 0) 
dt1 = datetime.datetime(2017, 1, 5, 0, 0, 0) 
dt = dt0 
while dt <= dt1: 
    print(dt.strftime("%Y-%m-%d %H:%M:%S")) 
    dt += datetime.timedelta(days=1) 

Есть ли подобный способ перебрать дат в Rust? Я знаю, что я мог писать вложенную петлю в течение месяцев, затем в дни месяца. Например:

let days = [1, 2, 3, 4, 5, 6, 7, 
      8, 9, 10, 11, 12, 13, 14, 
      15, 16, 17, 18, 19, 20, 21, 
      22, 23, 24, 25, 26, 27, 28, 29, 30, 31]; 
let months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; 
let months_30_days = [4, 6, 9, 11]; 

for month in months.iter() { 
    for day in days.iter() { 
     if month == &2 { 
      if is_leap_year(year) { 
       if day > &29 { 
        continue; 
       } 
      } else if day > &28 { 
       continue; 
      } 
     } else if months_30_days.contains(&month) && day > &30 { 
      continue; 
     } 

     print!("{:04}-{:02}-{:02} ", year, month, day); 
    } 
} 

fn is_leap_year(year: i32) -> bool { 
    if year % 100 == 0 { 
     return year % 400 == 0; 
    } else { 
     return year % 4 == 0; 
    } 
} 

Есть ли более деревенский способ сделать это?

+0

Если у вас есть код, который ** ** рабочая, но вы хотите его улучшить, что это лучший вопрос [Code] (Review.SE http://meta.codereview.stackexchange.com/questions/5777/a-guide-to-code-review-for-stack-overflow-users). – Shepmaster

+0

Вы, кажется, пропустили цикл внешнего года. – ljedrz

+0

Это фрагмент. Год был объявлен ранее в основной функции. Но вы правы, цикл года может быть добавлен в качестве внешнего цикла, если диапазон дат включал несколько лет. –

ответ

0

Может быть ящик, который уже предоставляет такую ​​функциональность, но если вы хотите реализовать это самостоятельно, вы можете ввести новый тип данных и реализовать Iterator - это будет способ Rust-y сделать это ,

struct MyDate { 
    year: usize, // or allow negatives for B.C. 
    month: u8, // or a dedicated Month type limited to 12 
    day: u8 // or a dedicated Day type limited to 31 
} 

impl Iterator for Date { 
    type Item = Date; 

    fn next(&mut self) -> Option<Date> { 
     // conditions for incrementing day, month and year 
    } 
} 

Тогда вы могли бы увеличить его в цикле, используя next().

3

Вы можете использовать chrono клеть для этого:

extern crate chrono; 

use chrono::{Duration, UTC, TimeZone}; 

fn main() { 
    let dt0 = UTC.ymd(2017, 1, 1); 
    let dt1 = UTC.ymd(2017, 1, 5); 

    let mut dt = dt0; 
    while dt <= dt1 { 
     println!("{:?}", dt); 
     dt = dt.checked_add(Duration::days(1)) 
      .expect("Overflow happend!"); 
    } 
} 
+1

mstlr Это работает очень хорошо. Я не знал, как добавить день в datetime. Я все еще не понимаю, что делает «.expect», но он не будет работать без него. –

+0

@ joeschmoe2 'expect' имеет то же поведение, что и' unwrap', за исключением того, что он также позволяет указать настраиваемое сообщение, если оно паникует. Это необходимо, потому что 'checked_add' возвращает' Option ', но значение присваивается' dt', которое является простым «UTC». –

Смежные вопросы