2017-05-16 35 views
0

したがって、ユーザーから開始日と終了日を取得してグラフを作成しようとしています。私は日付の間に月の数を数える必要がありますし、各月の日数を計算し、月の名前も取得する必要があります。2つの日付間の月を計算し、毎月の計算日を計算する

2つの日付の間に月がありますが、残りをコードに変換できないようです。同様に、キッカーがたstartDateが月の途中である場合、それが結果リストに保存するべきであるということである

private List<MonthRange> GetRangeOfMonthsBetweenDates(DateTime startDate, DateTime endDate) { 

    List<MonthRange> result = new List<MonthRange>(); 
    int months = (endDate.Year - startDate.Year)*12 + endDate.Month - startDate.month; 

foreach(var m in months){ 
    //get the start and end date of that month with the name and add it to the result list. 
} 

} 

:私はMonthRange

と呼ばれるクラス
public class MonthRange 
{ 
    public DateTime startDate { get; set; } 

    public DateTime endDate { get; set; } 

    public string monthName { get; set; } 

    public MonthRange() { 
    } 

    public MonthRange(DateTime startDate, DateTime endDate, string monthName) { 
     this.startDate = startDate; 
     this.endDate = endDate; 
     this.monthName = monthName; 
    } 
} 

そして、私の方法を持っています終了日が月の途中であれば、それを保存する必要があります。私は少し失われており、どんな助けにも感謝します。

編集:これは私が達成しようとしているものの例です。私は、与えられた時間の範囲内で人が食べ物を食べた回数をプロットするグラフを作成しようとしています。

編集2:だから私はこの道を行くことになった:あなたが最初の日にすべてを変換するため

private List<MonthRange> GetRangeOfMonthsBetweenDates(DateTime startDate, DateTime endDate) { 

     List<MonthRange> result = new List<MonthRange>(); 

     DateTime holder = startDate; 

     var months = (endDate.Year - startDate.Year) * 12 + endDate.Month - startDate.Month; 


     for (int i = 0; i <= months; i++) { 
      if (i == 0) 
      { 
       result.Add(new MonthRange(startDate, CalculateStartOfMonth(endDate), startDate.ToString("MMM"))); 
      } 
      else if (i == months) 
      { 
       result.Add(new MonthRange(CalculateEndOfMonth(startDate), endDate, endDate.ToString("MMM"))); 
      } 
      else { 
       DateTime middleMonth = holder.AddMonths(1); 
       result.Add(new MonthRange(CalculateStartOfMonth(middleMonth), CalculateEndOfMonth(middleMonth), middleMonth.ToString("MMM"))); 
      } 
     } 

     return result; 
    } 

    private DateTime CalculateStartOfMonth(DateTime endDate) { 
     var startOfMonth = new DateTime(endDate.Year, endDate.Month, 1); 
     return startOfMonth; 
    } 

    private DateTime CalculateEndOfMonth(DateTime startDate) 
    { 
     var endOfMonth = new DateTime(startDate.Year, startDate.Month, DateTime.DaysInMonth(startDate.Year, startDate.Month)); 
     return endOfMonth; 
    } 
+0

任意の例入力と出力を? – Mark

+2

正しいものが正しいのですか?あなたが実際に入力した月の数として '1'を返したいのですか? 「Dec 31 2016 23:59」、「Jan 1 2017 00:01」をそれぞれ開始日と終了日としますか?あなたの説明の残りは同様に曖昧です。最初に、_precise_、_unambiguous_仕様書を書いて、実際にどの計算が正確に行われているかを詳述する必要があります。それで、コードは簡単に書くことができます。それがなければ、これを理解しようと数週間、あなたは円でさまようことができます。 –

+0

@マークEg:ユーザーがstartDateを16/05/2017、endDateを24/07/2017と入力した場合。その後、月数は3になり、最初の月は開始日が16日、2月が全体、3月が24日に終了します。それは理にかなっていますか? – bluebrigade23

答えて

1

注:これは質問に対する回答ではなく、別のアプローチの提案です。質問はある期間のある人の食事数をグラフ化することに関するものなので、(少なくともデータを表現するために)これにアプローチする自然な方法は、月単位ではなく日単位で行うことです。 (視覚的には、データを月単位で表示する必要があるかもしれませんが、データを最初に数日単位で整理してから月単位でレンダリングする方がずっと簡単です)。このクラスは、1日分の情報を格納するために使用できます。

class DayEntry 
{ 
    public DateTime Date { get; set; } 
    public string MonthName { get; set; } 
    public int NumberOfMeals { get; set; } 
} 

次の関数は、日付の範囲で、毎日のために初期化DayEntryオブジェクトのリストを作成する:データは指定された日付範囲のために準備されている場合

List<DayEntry> CreateDayEntries(DateTime dateStart, DateTime dateEnd) 
{ 
    var dateDiff = dateEnd - dateStart; 
    var dayCount = (int) Math.Ceiling(dateDiff.TotalDays) + 1; 
    var dayRange = new List<DayEntry>(dayCount); 

    for (var i = 0; i < dayCount; i++) 
    { 
     var date = dateStart.AddDays(i); 
     var dayEntry = new DayEntry 
     { 
      Date = date, 
      NumberOfMeals = 0, // TODO 
      MonthName = date.ToString("MMMM", CultureInfo.CurrentCulture) 
     }; 

     dayRange.Add(dayEntry); 
    } 

    return (dayRange); 
} 

、それはその後に示すことができます月ごとにグループ化されたUI - 毎日のエントリには独自の日付(所属する月の名前)があり、リスト内で順番に並んでいるので、繰り返し処理してUI出力を作成するのは簡単です。あなたのMonthRange構造に基づいて

+0

これはちょっと私が探していたものです。私はあなたの答えを使用しましたが、日付、名前などを計算する方法のいくつかの変更を加えました投稿への私の答えを追加する:) – bluebrigade23

+0

@ bluebrigade23いいえ、それは有用だった嬉しいです。 – xxbbcc

0

私は示唆している何があります。

例えば、 x= 361 ; // total number of days

そこから、あなたは月と年に分割することができます。

months = x/30; // find months 
days = x%30; // find the remainder of the days from the month 
years = months/12; // find years 

このように計算する方がずっと簡単です。

+0

'2017/01/31' - ' 2017/03/01'はどうですか? – xxbbcc

+0

が最初に表示されます。私の方法は、与えられた範囲で日付の数を見つけることです。これは、89日に相当する2017/01/31 - 2017/03/01です。そこからあなたは30で割って月= 2を見つけます。そこから、それは0年の2月と29日であることがわかります。 – Hank

+0

間違っています。その期間は、_3_ヶ月間に30日間の期間を表します。 2017年の2月は28日しかなかったが、1月の最終日を選び、3月の初日は30日間となる。あなたの方法は、いくつかの理由で正しくありません。 – xxbbcc

0

、これを試してみてください。たとえば

private IEnumerable<MonthRange> GetRangeOfMonthsBetweenDates(DateTime startDate, DateTime endDate) {   
    var start = startDate; 
    while(start<endDate) { 
     var end = start.AddMonths(1).AddDays(-start.Day);   
     yield return new MonthRange(start, end < endDate ? end : endDate, start.ToString("MMMM")); 

     start = end.AddDays(1); 
    } 
} 

を:

var start = new DateTime(2017,5,16); 
var end = new DateTime(2017,7,24); 

foreach(var m in GetRangeOfMonthsBetweenDates(start, end)) { 
    Console.WriteLine("{0}: {1:dd/MM/yyyy}-{2:dd/MM/yyyy}", m.monthName, m.startDate, m.endDate); 
} 

を印刷する必要があります:あなたが達成したい

May: 16/05/2017-31/05/2017 
June: 01/06/2017-30/06/2017 
July: 01/07/2017-24/07/2017 
関連する問題