Calculation algorithm for Dates - c#

I have previously posted this question. However I was not specific enough, so I am trying to explain it better in this post.
I am currently writing a small program to create invoices. The invoices should be calculated on account of storage time of items e.g. costPerDay * numberOfDaysInStorage.
The invoice is created on a monthly basis, e.g. InvoiceDate = 31/05/2013.
The items start date and end date (in storage) is extracted from a database.
So, I have:
Variables:
DateTime StartInStorageDate;
DateTime EndOfStorageDate;
DateTime InvoiceDate; //(always last date of month)
Rules
The first five days in storage should always be free.
Calculation of days, should only be made for a given invoice date.
If the date prior to the InvoiceDate exist, the days should be taken
into account, in order to calculate the "free days". If month date prior has 5 or more days, to the end of its month, we have to assume that these have been calculated, and therefore not take them into account in the invoice month.
Examples
Example 1:
DateTime StartInStorageDate = 07/04/2013;
DateTime EndOfStorageDate = 08/06/2013;
DateTime InvoiceDate = 31/05/2013;
Calculation of days = 31 days (Because Invoice date has a date prior, which has more than five days, the "free days" are already
subtracted in that month)
Example 2:
DateTime StartInStorageDate = 28/04/2013
DateTime EndOfStorageDate = 08/06/2013
DateTime InvoiceDate = 31/05/2013
Calculation of days = (11 days total - 5 "free days") = 6 days
(Because Invoice date has a date prior, which does not have 5 days to
end of its month, we have to add these days to the invoice month, and
subtract 5 "free days" from the total)
Example 3:
DateTime StartInStorageDate = 28/04/2013
DateTime EndOfStorageDate = 08/05/2013
DateTime InvoiceDate = 31/04/2013
Calculation of days = 0 (Because the invoiceDate does not have more than 5 days, and does not have a month prior)
I hope someone can provide me with some pointers, or some code to help calculate the days. The part I find tricky, is to "look into" a previous month (if one exists) from the invoice date, to check for days.
Thank you.

It requires only a few simple actions:
DateTime endDate = Min(invoiceDate, endOfStorageDate ); // Min() is pseudo code
int daysInStorage = (endDate - StartInStorageDate).Days;
daysInStorage -= 5;
if (daysInStorage < 0) daysInStorage = 0;

You need to calculate two dates: the start and end of the invoice period:
DateTime invoiceStart = StartInStorageDate.AddDays(5);
DateTime invoiceEnd = InvoiceDate < EndOfStorageDate ? InvoiceDate : EndOfStorageDate;
double billedDays = Math.Max(0, (invoiceEnd - invoiceStart).TotalDays);

Related

First and Last Day of 4 Weeks in C# DateTime Objects

I'm trying to Get the First and Last Day of 4 Weeks based on the given Date.
For Example:
If the given Date is 8-Jan-2023 then the week start and end should be 1-Jan-2023 and 28-Jan-2023 respectively.
If the given Date is 10-Jan-2023 then the week start and end should be 1-Jan-2023 and 28-Jan-2023 respectively.
If the given Date is 30-Jan-2023 then the week start and end should be 29-Jan-2023 and 25-Jan-2023 respectively.
Basically, the use case depends on the very first input. If the first input is 15-Jan then the first 4 weeks are recorded in the database as 15-Jan to 11-Feb. In that case, 17-Jan belongs to that week
How to do this?
I'm getting the Start Day & end Date of the week as below:
public static DateTime FirstDayOfWeek(this DateTime dt)
{
var culture = Thread.CurrentThread.CurrentCulture;
var diff = dt.DayOfWeek - culture.DateTimeFormat.FirstDayOfWeek;
if (diff < 0)
{
diff += 7;
}
return dt.AddDays(-diff).Date;
}
public static DateTime LastDayOfFourWeeks(this DateTime dt) =>
dt.FirstDayOfWeek().AddDays(27);

c# adding correct month based on previous month

I am trying to add a month to a date and populate textboxes based on the previous month. For months that end on the 31st (and even February 28th) this works. But, if the previous month ended on the 30th and the next month ends on the 31st, it is either one day short or one day long. For example:
Previous start date: 4/1/2017
Previous end date: 4/30/2017
New start date: 5/1/2017
New end date: SHOULD BE 5/31/2017
Here is the code I have:
// Set the Start Date
DateTime dtNewStartDate;
dtNewStartDate = Convert.ToDateTime(txtRecentBeginDate.Text).AddMonths(1);
txtNewStartDate.Text = dtNewStartDate.ToString();
// Set the End Date
DateTime dtNewEndDate;
dtNewEndDate = Convert.ToDateTime(txtNewStartDate.Text).AddMonths(1);
txtNewEndDate.Text = dtNewEndDate.ToString();
This produces an end date of 6/1/2017 instead of 5/31/2017
EDIT: I was able to find what I was looking for from https://social.msdn.microsoft.com/Forums/en-US/218260ec-b610-4fa6-9d1b-f56f3438b721/how-to-get-the-last-day-of-a-particular-month?forum=Vsexpressvcs.
This solution accounts for leap years and getting the correct last day of the month for any circumstance. This is what I came up with:
// Set the End Date
int intYear = dtNewStartDate.Year;
int intMonth = dtNewStartDate.Month;
int intNumberOfDays = DateTime.DaysInMonth(intYear, intMonth);
DateTime dtNewEndDate = new DateTime(intYear, intMonth, intNumberOfDays);
txtNewEndDate.Text = dtNewEndDate.ToString();
You can just get the last day of the month for that month.
DateTime today = DateTime.Today;
DateTime endOfMonth = new DateTime(today.Year,
today.Month,
DateTime.DaysInMonth(today.Year,
today.Month));
This is what I typically do: Just take the year and month from the start date, create a new date based on that, add a month and subtract a day which ends up being the last day of the next month::
DateTime dtNewEndDate = new DateTime(dtNewStartDate.Year, dtNewStartDate.Month, 1)
.AddMonths(1)
.AddDays(-1);

How to corectly Loop over days

I am trying to make a string with start dates and end dates. That can loop over X number of days.
int nrOfDaysToLoopBy = 3;
List<string> Dates = new List<string>();
string startDate = "2014-01-01"; //this date is given to me by an api I am just hard codeing for testing
string endDate = "2014-01-30";
DateTime StartDate = DateTime.ParseExact(startDate, "yyyy-MM-dd", CultureInfo.InvariantCulture);
DateTime EndDate = DateTime.ParseExact(endDate, "yyyy-MM-dd", CultureInfo.InvariantCulture);
DateTime myDate = StartDate; // setting the initial date
for (DateTime date = StartDate.AddDays(nrOfDaysToLoopBy); date.Date <= EndDate.Date; date = date.AddDays(nrOfDaysToLoopBy))
{
Dates.Add("start-date=" + myDate.ToString("yyyy-MM-dd") + "&end-date=" + date.ToString("yyyy-MM-dd"));
myDate = date.AddDays(1);
}
// Dealing with any left over days.
if (myDate != EndDate && EndDate > myDate)
{
Dates.Add("start-date=" + myDate.ToString("yyyy-MM-dd") + "&end-date=" + EndDate.ToString("yyyy-MM-dd"));
}
My results:
start-date=2014-01-01&end-date=2014-01-04
start-date=2014-01-05&end-date=2014-01-07
The problem here is that there is 4 days between 2014-01-01 and 2014-01-04 not 3.
Results I am trying to get:
start-date=2014-01-01&end-date=2014-01-03
start-date=2014-01-04&end-date=2014-01-06
Update:
Can we agree that the days between 2014-01-01&end-date=2014-01-04 are
2014-01-01, 2014-01-02, 2014-01-03, and 2014-01-04 That's 4
I have been playing with this for a few hours now and nothing I have done has fixed the problem.
The problem here is that there is 4 days between 2014-01-01 and 2014-01-04 not 3.
One could argue that there's 3 days between 2014-01-01 and 2014-01-04: Between 2014-01-01 and 2014-01-04, three 24h periods pass:
2014-01-01 -- 2014-01-02
2014-01-02 -- 2014-01-03
2014-01-03 -- 2014-01-04
You see, the problem is how you define between. If you want to include the start and the end date, you need to adjust the number of dates you add.
Edit:
This fixed the problem. nrOfDaysToLoopBy-1
for (DateTime date = StartDate.AddDays(nrOfDaysToLoopBy-1); date.Date <= EndDate.Date; date = date.AddDays(nrOfDaysToLoopBy))
{
}
Simply change the statement:
DateTime date = StartDate.AddDays(nrOfDaysToLoopBy);
in your for loop initialization to
DateTime date = StartDate.AddDays(nrOfDaysToLoopBy-1);
The issue is that when you add days, the number of days "between" as you're calling it is actually the number of days you add + 1. So monday->monday (zero days added) is 1 day, monday->tuesday (one day added) is 2 days, etc. That's why you need the -1 modification for the start date.
The reason you don't need this alteration on every other iteration on the loop is because of the myDate = date.AddDays(1) line. This reduces the difference between myDate and date by one, bringing it back to the correct difference

Calculate End Date Given Start Date & duration (in days)

I am developing a c#.net solution with a Store Procedure in oracle that calculates End Date based on provided Start date and Duration with weekends.
i.e. Start Date: 01/3/2013 Forward days: 10
Start Date = (05/5/2011) - 10 days (includes weekends)
Start Date = 06/02/2013
thank you,
Use of AddDays method of DateTime
DateTime startDate = new DateTime(2013,3,1);
var endDate = startDate.AddDays(10);
You can do this a bunch of ways in Oracle. I'd suggest the INTERVAL way because it's standard-ish:
SELECT yourdate + INTERVAL '10' DAY, ...
The single quote around the 10 is required.
The "old" way is to just add 10 to the date; Oracle treats this as days:
SELECT yourdate + 10, ...
//DateTime start_date = ...
DateTime end_date = start_date.AddDays(10);

Get datetime from given day

user just enter the day of week. For instance user enter friday. I need to find the exact date of given day and format will be like dd.MM.yyyy.
But I don't know how I do it.
Example:
label1 - Friday (entered by user)
label2 - 08.06.2012 (found by system)
label1 is just a string (just Friday). It's coming from webservice as a string variable. I need to find the date and compare with today, If it's not equal or small than today I give date of upcoming Friday, else I give the date of the Friday the week after.
"If it's not equal or small than today I give exact date, else I give next week date. "
Assuming that means that you return always the next date in future with the given day of week, the only exception is when today is the given day of week.
public static DateTime getNextWeekDaysDate(String englWeekDate)
{
var desired = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), englWeekDate);
var current = DateTime.Today.DayOfWeek;
int c = (int)current;
int d = (int)desired;
int n = (7 - c + d);
return DateTime.Today.AddDays((n >= 7) ? n % 7 : n);
}
Let's test:
DateTime Monday = getNextWeekDaysDate("Monday"); // 2012-06-11
DateTime Tuesday = getNextWeekDaysDate("Tuesday"); // 2012-06-05 <-- !!! today
DateTime Wednesday= getNextWeekDaysDate("Wednesday"); // 2012-06-06
DateTime Thursday = getNextWeekDaysDate("Thursday"); // 2012-06-07
DateTime Friday = getNextWeekDaysDate("Friday"); // 2012-06-08
Create enum of days (i.e. monday - 0, tuesday - 1, etc);
Get DateTime.Now DayOfWeek and cast in some way it to your enum value.
Calculate difference between Now.DayOfWeek and user's day of the week;
Use DateTime.AddDays(difference).DayofTheWeek;
get current time with DateTime.now
Current day is DateTime.Now.DayOfWeek
Then get the day of week your user entered
Then your result is DateTime.now.AddDays( NowDayOfWeek - UserDayOfWeek).

Categories