所以我试图通过从用户那里获取开始和结束日期来创建图表。我需要计算日期之间的月数,然后每个月计算天数并获取月份的名称。
我已经获得了两个日期之间的月份数,但似乎无法将剩余的日期转换为代码。我有一个名为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;
}
}
我的方法:
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.
}
}
踢球者是如果startDate在月中途,那么应该保存在结果列表中,同样如果endDate是月份的中间,那就应该保存。我有点迷茫,会感激任何帮助。
编辑:所以这是我想要实现的一个例子。我正在尝试创建一个图表,绘制一个人在给定时间范围内食物的次数。
编辑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 :(得分: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输出。
答案 1 :(得分: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
这种方式更容易计算。
答案 2 :(得分:0)
根据您的MonthRange
结构,试试这个:
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