I am given two dates as strings like this:
Beginning month: 10
Beginning year: 2010
Ending month: 01
Ending Year 2020
I want to query my entity and get everything that is equal or between these ranges.
So, I want everything from 10/2010 to 01/2020.
I have this code and I got stuck on how to convert the date correctly and the comparison:
dollartotals = (from x in se.AchBatches
where x.CompanyCode == company &&
DbFunctions.TruncateTime(x.DateTimeSubmitted) >=
// stuck here
select x.DollarTotal).Sum();
How do I handle the individual month/year strings and make a date comparison without a day?
Thanks for any assistance!
You want to check against the actual datetime submitted, not a truncated version of it.
The key is to build actual datetimes in advance, then just do a regular date window check.
Assume you have four strings as listed in your question:
//you might use TryConvert or a Try block here to validate your string data...
int beginYear = Integer.Convert(strBeginYear);
int beginMonth = Integer.Convert(strBeginMonth);
int endYear = Integer.Convert(strEndYear);
int endMonth = Integer.Convert(strEndMonth);
DateTime start = new DateTime(beginYear, beginMonth, 1);
DateTime endLimit = new DateTime(endYear, endMonth, 1).AddMonths(1);
dollartotals = (from x in se.AchBatches
where x.CompanyCode == company &&
x.DateTimeSubmitted >= start &&
x.DateTimeSubmitted < endLimit
select x.DollarTotal).Sum();
I want everything from 10/2010 to 01/2020.
Not sure if you want a DateTime sequence with every Tick between those dates, or every second, or every Day. Let's assume you want every Day: All Days from startDate.Date until and inclusive endDate.Date.
I use StartDate.Date, so if StartDate is 2020-02-05 13:20:14, then you still get February 5th 2020 at 00:00:00
IEnumerable<DateTime> GetDateRange(DateTime startDate, DateTime endDate)
{
DateTime lastDate = endDate.Date;
DateTime date = startDate.Date;
while (date <= lastDate)
{
yield return date;
date = date.AddDays(+1);
}
}
Usage:
var allDaysOfFebruary2020 = GetDateRange(new DateTime(2020, 01, 01),
new DateTime(2020, 02, 29));
You'll get the sequence from 1st February 2020 until and inclusive 29th February 2020.
Related
I am attempting to use the DateTime function in C# to calculate the last day of next month.
For example, today is December 17th 2015. I want the DateTime function to return January 31st 2016 (the last day of next month).
I am using the following to calculate the first day of next month (this works):
DateTime firstDayNextMonth = DateTime.Today.AddDays(-DateTime.Now.Day+1).AddMonths(1);
DateTime reference = DateTime.Now;
DateTime firstDayThisMonth = new DateTime(reference.Year, reference.Month, 1);
DateTime firstDayPlusTwoMonths = firstDayThisMonth.AddMonths(2);
DateTime lastDayNextMonth = firstDayPlusTwoMonths.AddDays(-1);
DateTime endOfLastDayNextMonth = firstDayPlusTwoMonths.AddTicks(-1);
Demo: http://rextester.com/AKDI52378
//system date or any date u want this case it is a calendar picker - 22/03/2016
DateTime today = dtpFrom.Value;
//Add a month to your date example , it now becomes - 22/04/2016
DateTime endOfMonth = new DateTime(today.Year, today.Month,today.Day).AddMonths(1);
//Get the last date off the above which is - 30
int getlastday = DateTime.DaysInMonth(endOfMonth.Year, endOfMonth.Month);
//Now set the date to the value which will be the last day off the next month - 30/04/2016
DateTime newDate = new DateTime(endOfMonth.Year, endOfMonth.Month, getlastday);
DateTime.DaysInMonth(DateTime.Now.AddMonths(1).Year, DateTime.Now.AddMonths(1).Month);
var lastDayInNextMonth = DateTime.DaysInMonth(DateTime.Now.AddMonths(1).Year, DateTime.Now.AddMonths(1).Month );
# Ben : DateTime.Now.AddMonths(1) will add 1 month to the current date not substract 11 months.
DateTime.Now.AddMonths(1).Year will give 2016 not 2015 refer the attached image
try this:
int Day= DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month+1>12 ? 01 : DateTime.Now.Month+1 );
I am wondering if i can get the date of every alternate friday starting with 13th of April, 2012 to give it as a parameter to a stored procedure using c#, asp.net?
It should also be most recently passed date. Thank you!
Just set a DateTime with the date you want to start at, and then keep adding 14 days:
So to get every other Friday after 4/13 until the end of the year:
DateTime dt = new DateTime(2012, 04, 13);
while (dt.Year == 2012)
{
Console.WriteLine(dt.ToString());
dt = dt.AddDays(14);
}
More info after comment:
If you want the most recent alternate Friday since 2012/04/13, you can compute the number of days between now and 2012/04/13, take the remainder of that divided by 14, and subtract that many days from today's date:
DateTime baseDate = new DateTime(2012, 04, 13);
DateTime today = DateTime.Today;
int days = (int)(today - baseDate).TotalDays;
int rem = days % 14;
DateTime mostRecentAlternateFriday = today.AddDays(-rem);
You can easily make a generator method that would give you the set of fridays:
public IEnumerable<DateTime> GetAlternatingFridaysStartingFrom(DateTime startDate)
{
DateTime tempDate = new DateTime(startDate.year, startDate.Month, startDate.Day);
if(tempDate.DayOfWeek != DayOfWeek.Friday)
{
// Math may be off, do some testing
tempDate = tempDate.AddDays((7 - ((int)DayOfWeek.Friday - (int)tempDate.DayOfWeek) % 7);
}
while(true)
{
yield return tempDate;
tempDate = tempDate.AddDays(14);
}
}
Then, simply use some LINQ to determine how much you want:
var numberOfFridays = GetAlternatingFridaysStartingFrom(DateTime.Today).Take(10);
Why do you need a stored proc?
If you have a date that is Friday, why not just use AddDays(14) in a loop?
If you want to find the nearest Friday from a start date, just use this:
while(date.DayOfWeek != DayOfWeek.Friday)
{
date.AddDays(1);
}
Then use the 14 day loop to get every other Friday.
You can create simple method that will enumerate them like so:
public static IEnumerable<DateTime> GetAlternatingWeekDay(DateTime startingDate)
{
for (int i = 1; ; i++)
{
yield return startingDate.AddDays(14*i);
}
}
Which you can call like this:
DateTime startingDate = DateTime.Parse("2012-04-13");
foreach (var date in GetAlternatingWeekDay(startingDate).Take(10))
{
Console.WriteLine(date.ToString("R"));
}
Alternately, if you need to know the date for a given number of weeks out, you could use code like this:
DateTime date = DateTime.Parse("2012-04-13").AddDays(7 * numberOfWeeks);
tl;dr;
How would you take StartDate-DateTime: Dec 10th 2011, EndDate-DateTime Jan 15th 2012, and determine whether or not Dec 1, Dec 9,Dec 17,Dec 25, Jan 1, and Jan 9 fit into that TimeSpan, Year excluded and get a Bool for each one?
I have a visual timespan consisting of a linear graph showing when a specific activity is active.
I am given an object with a start date, and an end date.
I have covered the timespan with a DIV having a red background representing 1/4 of each month, naming them JanQ1, JanQ2, etc..
These start off as visibility:hidden, but need to be altered in the event that the activity is active during the part of the year.
The problem I'm having is getting a true/false value that ignores the year being given.
For example, an event that goes from Dec 10th 2011 to Jan 15th 2012, I would want this result set:
DecQ1=False,
DecQ2=True,
DecQ3=True,
DecQ4=True,
JanQ1=True,
JanQ2=True,
JanQ3=False
Would a function like this work for you?
bool IsDateContained(DateTime startDate, DateTime endDate, int month, int day) {
bool retVal = false;
if (startDate < endDate) {
do {
if (startDate.Month == month && startDate.Day == day) {
retVal = true;
break;
}
startDate = startDate.AddDays(1);
} while (startDate < endDate);
} else {
//crazy world!!
}
return retVal;
}
Make new DateTime objects before comparison by setting them to the same year - http://msdn.microsoft.com/en-us/library/wb249tb7.aspx.
I have a collection of dates that are business days and I have a Start Date. When I add a TimeSpan to the Start Date DateTime I have to ensure that when adding the days in TimeSpan, I skip over holidays. Any suggestions on how I can do this?
You add the timespan as it is. When that is done, you iterate search for dates in your collection that falls between the original date and the new date. For each time you encounter for each hit you add another day to the new date, and repeat until you are through your collection of dates. This can be optimized if your datecollection is sorted.
You need to take into account how many non-business days there are in any added date range.
In a 20 day range, there may be 6 non-business days.
You can't just add this number of days to the last day because the new date range may contain non-business days too. You have to add the days, and then figure out how many of those days you've added are also holidays:
Here's some non-tested pcode
Add Timespan to date (DateIn,timespan)
finalDateTime = (fromDate + timespan)
fromDate = DateIn.date
toDate = finalDateTime.date
repeat
iDays = GetHolidaysBetween (fromDate, toDate)
finalDateTime = (finalDateTime + iDays)
fromDate = (toDate+1)
toDate = (toDate+iDays)
until (iDays=0)
return finalDateTime
end_function
What about something like this?
public DateTime AddBusinessDays(List<DateTime> businessDays, DateTime startDate, TimeSpan span)
{
// Add the initial timespan
DateTime endDate = startDate.Add(span);
// Calculate the number of holidays by taking off the number of business days during the period
int noOfHolidays = span.Days - businessDays.Where(d => d >= startDate && d <= endDate).Count();
// Add the no. of holidays found
endDate.AddDays(noOfHolidays);
// Skip the end date if it lands on a holiday
while (businessDays.Contains(endDate))
endDate = endDate.AddDays(1);
return endDate;
}
I'm creating a scheduler and need to be able to do the following in C#:
Find the 1st Tuesday of June 2012
Find the last Friday of March 2008
Find every Saturday in January 2013
Find the 3rd Friday in July 2009
Find every Saturday over the next 3 months
Find every day in March 2018
The results should come back as DateTime or List<DateTime>.
Here are methods to find the first/last specified day of week in a given month:
public DateTime GetFirstDayOfWeekInMonth(int year, int month, DayOfWeek dayOfWeek)
{
DateTime dt = new DateTime(year, month, 1);
int first = (int)dt.DayOfWeek;
int wanted = (int)dayOfWeek;
if (wanted < first)
wanted += 7;
return dt.AddDays(wanted - first);
}
public DateTime GetLastDayOfWeekInMonth(int year, int month, DayOfWeek dayOfWeek)
{
int daysInMonth = CultureInfo.CurrentCulture.Calendar.GetDaysInMonth(year, month);
DateTime dt = new DateTime(year, month, daysInMonth);
int last = (int)dt.DayOfWeek;
int wanted = (int)dayOfWeek;
if (wanted > last)
last += 7;
return dt.AddDays(wanted - last);
}
From those, you can easily find the answers to the other questions... just add 7 days to find the next occurence of the day you're looking for
EDIT: thinking more about it, it would be pretty handy to have that in the form of extension methods, such as :
Console.WriteLine("Next monday : {0}", DateTime.Today.Next(DayOfWeek.Monday));
Console.WriteLine("Last saturday : {0}", DateTime.Today.Previous(DayOfWeek.Saturday));
Here is the implementation :
public static class DateExtensions
{
public static DateTime Next(this DateTime from, DayOfWeek dayOfWeek)
{
int start = (int)from.DayOfWeek;
int wanted = (int)dayOfWeek;
if (wanted < start)
wanted += 7;
return from.AddDays(wanted - start);
}
public static DateTime Previous(this DateTime from, DayOfWeek dayOfWeek)
{
int end = (int)from.DayOfWeek;
int wanted = (int)dayOfWeek;
if (wanted > end)
end += 7;
return from.AddDays(wanted - end);
}
}
It's probably more flexible than the first methods I suggested... With that, you can easily do things like that :
// Print all Sundays between 2009/01/01 and 2009/03/31
DateTime from = new DateTime(2009, 1, 1);
DateTime to = new DateTime(2009, 3, 31);
DateTime sunday = from.Next(DayOfWeek.Sunday);
while(sunday <= to)
{
Console.WriteLine(sunday);
sunday = sunday.AddDays(7);
}
Inspired by this question it seemed like a fun thing to make something that allows you to treat dates as sequences and query them with LINQ. I've made a simple project that can be downloaded here from GitHub. Don't know if it was necessary to add it to source control as I doubt I'll be working on it, but had to upload it somewhere and uploading it to RapidShare seemed a little dodgy :)
Your first questions solved with my "Linq-to-DateTime":
/*
* 1. Find the 1st Tuesday of June 2012
2. Find the last Friday of March 2008
3. Find every Saturday in January 2013
4. Find the 3rd Friday in July 2009
5. Find every Saturday over the next 3 months
6. Find every day in March 2018
*/
var firstTuesday = (from d in DateSequence.FromYear(2012).June()
where d.DayOfWeek == DayOfWeek.Tuesday
select d).First();
var lastFriday = (from d in DateSequence.FromYear(2008).March()
where d.DayOfWeek == DayOfWeek.Friday
select d).Last();
var saturdays = (from d in DateSequence.FromYear(2013).January()
where d.DayOfWeek == DayOfWeek.Saturday
select d);
var thirdFriday = (from d in DateSequence.FromYear(2009).July()
where d.DayOfWeek == DayOfWeek.Friday
select d).Skip(2).First();
var nextSaturdays = (from d in DateSequence.FromDates(DateTime.Today, DateTime.Today.AddMonths(3))
where d.DayOfWeek == DayOfWeek.Saturday
select d);
var allDays = (from d in DateSequence.FromYear(2018).March()
select d);
Not shown in this example is that you can choose the granularity of your queries. Meaning that if you do this:
var days = (from d in DateSequence.FromYears(2001, 2090).AsYears()
where d.Year % 2 == 0
select d.Year).ToList();
You will iterate through the dates with an increment of a year. The default is AsDays() if you don't specify anything.
The project is pretty barebone, no commentary or unit tests, but I hope this can still help you. If not, then it was fun writing anyway :)
Here is an example on how to do the first day of a month.
public enum Month
{
January = 1,
Febuary = 2,
March = 3,
April = 4,
May = 5,
June = 6,
July = 7,
August = 8,
September = 9,
October = 10,
November = 11,
December = 12
}
public static Nullable<DateTime> FindTheFirstDayOfAMonth(DayOfWeek dayOfWeek, Month month, int year)
{
// Do checking of parameters here, i.e. year being in future not past
// Create a DateTime object the first day of that month
DateTime currentDate = new DateTime(year, (int)month, 1);
while (currentDate.Month == (int)month)
{
if (currentDate.DayOfWeek == dayOfWeek)
{
return currentDate;
}
currentDate = currentDate.AddDays(1);
}
return null;
}
You call it like
Nullable<DateTime> date = Program.FindTheFirstDayOfAMonth(DayOfWeek.Monday, Month.September, 2009);
So you get the idea. You will have to do various functions do get what you want to achieve.
YO YO YO - You guys are making this too hard:
int DaysinMonth = DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month);
When I wrote a scheduler I pretty much copied SQL Servers sysschedules table
http://msdn.microsoft.com/en-us/library/ms178644.aspx
Using things like Frequency Type, Frequency Interval, etc... really made it easy to compute the values in code, but I am guessing there is a sproc to do it for you. I am searching for that now.
Yes, the .NET Framework will support that without any problems ;)
But seriously - you should be able to write code that does that fairly easily. If not, ask a question when you get stuck, and we'll help out. But you won't need any external assemblies - just go with a standard C# class =)