At the moment I have a Reminder Date. In the UI I have two fields to create the reminder date. The first field is an int and the second field is a combo box.
public int Frequency {get; set;}
public ReminderComboItems item {get; set;}
public enum ReminderComboItems
{
Minutes, Hours, Days, Weeks, Months, Years
}
public static DateTime ReminderComboItem(ReminderComboItems item, DateTime activityDate, int frequency)
{
switch (item)
{
case ReminderComboItems.Minutes:
date = date.AddMinutes(frequency);
return date;
case ReminderComboItems.Hours:
date = date.AddHours(frequency);
return date;
case ReminderComboItems.Days:
date = date.AddDays(frequency);
return date;
case ReminderComboItems.Months:
date = date.AddMonths(frequency);
return date;
case ReminderComboItems.Years:
date = date.AddYears(frequency);
return date;
default:
return date;
}
}
Using the top function creates the Reminder Date, now I'm trying to do the reverse.
public static ReminderDTO ReverseAppointment(DateTime activityDate, DateTime reminderDate)
{
for (int i = 0; i < 100; i++)
{
var incrementedDate = reminderDate.AddYears(-i);
if (incrementedDate == activityDate)
return new reminderDTO{ ReminderComboItem = ReminderComboItems.Years, i};
}
for (int i = 0; i < 100; i++)
{
var incrementedDate = reminderDate.AddMonths(-i);
if (incrementedDate == activityDate)
return new ReminderDTO{ ReminderComboItem = ReminderComboItems.Months, i};
}
...
iterative loop for weeks, days, hours, minutes
...
//default
var minutes = activityDate.Subtract(reminderDate).TotalMinutes
return new ReminderDTO{ ReminderComboItem = ReminderComboItems.Months, minutes};
}
I'm trying to have something that's less iterative, the fact that years/months aren't static(diff month lengths and leap years) it makes it a bit difficult. May I get some thoughts/opinions on this please.
1 Answer 1
Here's how I would do it. First make sure the reminderDate
is after the activityDate
. Then check if the month, day, and time are the same. If so you can do the year difference. If not then you check if just the day and time are the same and do the month difference (along with the year difference times 12). Otherwise subtract the dates and look at the TimeSpan
. If the minutes are not zero then return the TotalMinutes
. If the hours are not zero return the TotalHours
. If the number of days is divisible by 7 then do the weeks. Otherwise just return the Days
.
public static ReminderDTO ReverseAppointment(
DateTime activityDate, DateTime reminderDate)
{
if (reminderDate <= activityDate)
throw new ArgumentException("reminder cannot be <= activity");
if (reminderDate.Month == activityDate.Month
&& reminderDate.Day == activityDate.Day
&& reminderDate.TimeOfDay == activityDate.TimeOfDay)
{
return new ReminderDTO
{
ReminderComboItem = ReminderComboItems.Years,
Frequency = reminderDate.Year - activityDate.Year
};
}
if (reminderDate.Day == activityDate.Day
&& reminderDate.TimeOfDay == activityDate.TimeOfDay)
{
return new ReminderDTO
{
ReminderComboItem = ReminderComboItems.Months,
Frequency =
(reminderDate.Month - activityDate.Month)
+ (12 * (reminderDate.Year - activityDate.Year))
};
}
var difference = reminderDate - activityDate;
if (difference.Minutes != 0)
{
return new ReminderDTO
{
ReminderComboItem = ReminderComboItems.Minutes,
Frequency = (int)difference.TotalMinutes
};
}
if (difference.Hours != 0)
{
return new ReminderDTO
{
ReminderComboItem = ReminderComboItems.Hours,
Frequency = (int)difference.TotalHours
};
}
if (difference.Days % 7 == 0)
{
return new ReminderDTO
{
ReminderComboItem = ReminderComboItems.Weeks,
Frequency = difference.Days / 7
};
}
return new ReminderDTO
{
ReminderComboItem = ReminderComboItems.Days,
Frequency = difference.Days
};
}
Note that if the dates differ by less than a minute you'll end up with 0 days, but I'm assuming all you're dates will differ by at least one minute based on how they are generated.
-
\$\begingroup\$ Almost, it's missing weeks. Thanks for the help! \$\endgroup\$Master– Master2015年11月11日 17:55:02 +00:00Commented Nov 11, 2015 at 17:55
-
\$\begingroup\$ @Master Yeah, fixed it to include the weeks as well. \$\endgroup\$juharr– juharr2015年11月11日 17:58:10 +00:00Commented Nov 11, 2015 at 17:58
-
\$\begingroup\$ Any difference between using Days and TotalDays? \$\endgroup\$Master– Master2015年11月11日 17:59:07 +00:00Commented Nov 11, 2015 at 17:59
-
\$\begingroup\$ @Master Well
TotalDays
will include a fraction portion for any hour/minute/second different, but since we've established there isn't a difference at those levels then the only difference is that one isint
and the other isdouble
. So better to useDays
at that point. \$\endgroup\$juharr– juharr2015年11月11日 18:00:50 +00:00Commented Nov 11, 2015 at 18:00 -
\$\begingroup\$ Also you don't have a case for adding weeks. To do that you can just do
date.AddDays(7 * frequency)
. And you could just reduce all of your cases to one return. \$\endgroup\$juharr– juharr2015年11月11日 18:08:22 +00:00Commented Nov 11, 2015 at 18:08
TimeSpan
. \$\endgroup\$