Get days of week between two selected dates - c#

I have two datetimepickers. So I want to get the days of the week between the selected values.
Example: date1 = 14/1/2015 and date2 = 17/1/2015
So the result should be: days = Wed. Thu. Fri. Sat.

You want to get the DayOfWeeks of all DateTimes between two dates?
int daysDiff = (date2 - date1).Days;
List<DayOfWeek> days = Enumerable.Range(0, daysDiff + 1) // +1 because you want to include start and end date
.Select(d => date1.AddDays(d).DayOfWeek)
.ToList();
You need to add using System.Linq;

You can easily iterate your DateTime values like;
var dt1 = new DateTime(2015, 1, 14);
var dt2 = new DateTime(2015, 1, 17);
while (dt2 >= dt1)
{
Console.WriteLine(dt1.DayOfWeek);
dt1 = dt1.AddDays(1);
}
Result will be;
Wednesday
Thursday
Friday
Saturday
If you wanna their abbreviated day names as Wed, Thu, Fri, Sat, you can use "ddd" custom format specifier with a english-based culture (like InvariantCulture) like;
var dt1 = new DateTime(2015, 1, 14);
var dt2 = new DateTime(2015, 1, 17);
while (dt2 >= dt1)
{
Console.WriteLine(dt1.ToString("ddd", CultureInfo.InvariantCulture));
dt1 = dt1.AddDays(1);
}

Another alternative, which includes non-usual use of a for-loop and the yield return statement:
void Main()
{
var daysOfWeek = DaysBetween(
new DateTime(2015, 1, 14),
new DateTime(2015, 1, 17));
Console.WriteLine(
String.Join(", ", daysOfWeek.Select(d => d.ToString().Substring(0, 3))));
// prints: Wed, Thu, Fri, Sat
}
IEnumerable<DayOfWeek> DaysBetween(DateTime start, DateTime end)
{
for (var dateTime = start; dateTime <= end; dateTime = dateTime.AddDays(1))
{
yield return dateTime.DayOfWeek;
}
}

Related

How calculate if a Date is 6 month later birthdate in C#

how can I calculate if a date (in DateTime format) is 6 month later or not from my BirthDate (in DateTime format)?
Use DateTime AddMonth method
https://msdn.microsoft.com/ru-ru/library/system.datetime.addmonths(v=vs.110).aspx
var dat = new DateTime(2015, 12, 31);
var dat2 = new DateTime(2015, 12, 31);
if (dat.AddMonths(6) < dat2) { ... }
You should use DateTime.AddMonths :
DateTime dt;
DateTime birthDate;
if (dt <= birthDate.AddMonths(6))
{
}
enter your birth date, calculate your next birthday and compare the dates,
var born = new DateTime(1900, 02, 01);
var checkdate = DateTime.Now;
var nextBirthday = new DateTime(DateTime.Now.Year, born.Month, born.Day);
if (nextBirthday < DateTime.Now)
{
nextBirthday = new DateTime(DateTime.Now.Year + 1, born.Month, born.Day);
}
if (checkdate.AddMonths(6) < nextBirthday)
{
Console.WriteLine("date is 6 months later then birthday");
}
else
{
Console.WriteLine("wait for it");
}
DateTime birthDate=new DateTime(year,month,day);
DateTime dateToCompare = new DateTime(year, month, day);
if(dateToCompare >= birthdate.AddMonths(6))
{
//DoSomething
}
You could calculte the difference between dates using Subtract method and calculate how many months you have between these dates, for sample:
DateTime birthDay = /* some date */;
DateTime someDate = /* some date */;
var months = someDate.Subtract(birthDay).Days / (365.25 / 12);
This answer provides a good helper for Dates:
https://stackoverflow.com/a/33287670/316799

DateTime handling day+month

I have need to make a Week start and week end row with month names.
I have a calendar control where i set date.
And have this function:
public string DateToString(DateTime date)
{
string callback = "";
return callback;
}
I have problems figuring out how to handle week start and week end date and month.
I need string to look like< if end and beginning are different months:
29 July - 4. August, 2013
And the same month:
15 - 21. July, 2013 if the mounth is the same. Could you help me?
Perhaps you want to pass two DateTime arguments to the method, then it makes more sense:
public static string DateToString(DateTime dateStart, DateTime dateEnd)
{
if (dateStart.Year == dateEnd.Year && dateStart.Month == dateEnd.Month)
{
return string.Format("{0} - {1}, {2}"
, dateStart.ToString("dd")
, dateEnd.ToString("dd MMMM", CultureInfo.InvariantCulture)
, dateStart.Year);
}
else if (dateStart.Year == dateEnd.Year)
{
return string.Format("{0} - {1}, {2}"
, dateStart.ToString("dd MMMM", CultureInfo.InvariantCulture)
, dateEnd.ToString("dd MMMM", CultureInfo.InvariantCulture)
, dateStart.Year);
}
else
{
return string.Format("{0} - {1}"
, dateStart.ToString("dd MMMM yyyy", CultureInfo.InvariantCulture)
, dateEnd.ToString("dd MMMM yyyy", CultureInfo.InvariantCulture));
}
}
Your sample data:
var dt1 = new DateTime(2013, 07, 29);
var dt2 = new DateTime(2013, 08, 04);
Console.Write(DateToString(dt1, dt2));
dt1 = new DateTime(2013, 07, 15);
dt2 = new DateTime(2013, 07, 21);
Console.Write(DateToString(dt1, dt2));
Output:
29 July - 04 August, 2013:
15 - 21 July, 2013
So according to your comments you have a DateTime and you need to find the start and end of the week first. Then you want to build the string from these two dates:
public static DateTime StartOfWeek(DateTime dt, DayOfWeek startOfWeek)
{
int diff = dt.DayOfWeek - startOfWeek;
if (diff < 0)
{
diff += 7;
}
return dt.AddDays(-1 * diff).Date;
}
now you can use this method to find both dates:
var givenDate = new DateTime(2013, 08, 14);
var startWeekdate = StartOfWeek(givenDate, DayOfWeek.Monday);
var endWeekdate = startWeekdate.AddDays(6);
Console.WriteLine(DateToString(startWeekdate, endWeekdate));
prints:
12 - 18 August, 2013

How to get all Dates given "Day Name" Between 2 Dates in c#

How to get All Days between given two Dates, given "Day Name"?
Ex: Start_Date = Jan 1, 2011
End_Date = Jan 20, 2011
Day Name = Sunday
Here we need to get all Dates with dayname as "SUNDAY"
Ex:
Jan 02, 2011
Jan 09, 2011
Jan 16, 2011
I like to use Enumerable.Range for tasks like that:
DateTime start = new DateTime(2011,1,1);
DateTime end = new DateTime(2011,1,20);
var datesThatAreSundays = Enumerable
.Range(start.DayOfYear, end.Subtract(start).Days + 1)
.Select(n => start.AddDays(n - start.DayOfYear))
.Where(d => d.DayOfWeek == DayOfWeek.Sunday);
DateTime startDate = new DateTime(2011, 1, 1);
DateTime endDate = new DateTime(2011, 1, 20);
while (startDate < endDate)
{
if (startDate.DayOfWeek == DayOfWeek.Sunday)
{
// Do something
}
startDate = startDate.AddDays(1);
}
How about something like
DateTime startDate = new DateTime(2011, 01, 01);
DateTime endDate = new DateTime(2011, 01, 20);
string dayName = "sunday";
List<DateTime> list = new List<DateTime>();
for (DateTime runDate = startDate; runDate <= endDate; runDate = runDate.AddDays(1))
{
if (runDate.DayOfWeek.ToString().ToLower() == dayName)
list.Add(runDate);
}
or even using Enum.TryParse
DateTime startDate = new DateTime(2011, 01, 01);
DateTime endDate = new DateTime(2011, 01, 20);
string dayName = "sunday";
DayOfWeek dow;
Enum.TryParse(dayName, true, out dow);
List<DateTime> list = new List<DateTime>();
for (DateTime runDate = startDate; runDate <= endDate; runDate = runDate.AddDays(1))
{
if (runDate.DayOfWeek == dow)
list.Add(runDate);
}
Without having tested:
DateTime start = x;
DateTime end = y;
while (start.DayOfWeek != z)
start = start.AddDays(1);
while (start <= end)
{
//DoStuff
start = start.AddDays(7);
}
You may try this
var firstDate = new DateTime(2011, 1, 1);
var lastDate = new DateTime(2011, 1, 20);
var result = (from el in Enumerable.Range(0, (lastDate - firstDate).Days)
let date = firstDate.AddDays(el)
where date.DayOfWeek == DayOfWeek.Sunday
select date).ToArray();

Find missing dates for a given range

I'm trying to find missing dates between two DateTime variables for a collection of DateTimes.
For example.
Collection
2010-01-01
2010-01-02
2010-01-03
2010-01-05
DateRange
2010-01-01 -> 2010-01-06
would give me a List<DateTime> of
2010-01-04
2010-01-06
I can think of a few was of implementing this but nothing clean and simple
Any ideas?
I can think of a lot of ways of implementing this, e.g.:
DateTime[] col = { new DateTime(2010, 1, 1),
new DateTime(2010, 1, 2),
new DateTime(2010, 1, 3),
new DateTime(2010, 1, 5)};
var start = new DateTime(2010, 1, 1);
var end = new DateTime(2010, 1, 6);
var range = Enumerable.Range(0, (int)(end - start).TotalDays + 1)
.Select(i => start.AddDays(i));
var missing = range.Except(col);
And you could put the range-stuff into an Extension-Method
public static class extensions
{
public static IEnumerable<DateTime> Range(this DateTime startDate, DateTime endDate)
{
return Enumerable.Range(0, (int)(endDate - startDate).TotalDays + 1)
.Select(i => startDate.AddDays(i));
}
}
Then it would be simply
DateTime[] col = { new DateTime(2010, 1, 1),
new DateTime(2010, 1, 2),
new DateTime(2010, 1, 3),
new DateTime(2010, 1, 5)};
var start = new DateTime(2010, 1, 1);
var end = new DateTime(2010, 1, 6);
var missing = start.Range(end).Except(col);
But maybe this is not a high-performance-solution :-)
Depending on exactly what you are looking for and the sizes of the sets of data. A simple way would be to load the dates into a collection, then use a simple loop. I'll add a code sample here in a second.
DateTime currentDate = new DateTime(2010, 1, 1);
DateTime endDate = new DateTime(2010, 1, 6);
List<DateTime> existingDates = new List<DateTime>; //You fill with values
List<DateTime> missingDates = new List<DateTime>;
while(currentDate <= endDate)
{
if(existingDates.contains(currentDate))
missingDates.Add(currentDate);
//Increment date
currentDate = currentDate.AddDays(1);
}
Using this example you just need to load "existingDates" with the proper values, then the "missingDates" list will have your results
In .NET 2.0 :)
static void Main(string[] args)
{
List<DateTime> dates = new List<DateTime>();
dates.Add(new DateTime(2010, 01, 27));
dates.Add(new DateTime(2010, 01, 30));
dates.Add(new DateTime(2010, 01, 31));
dates.Add(new DateTime(2010, 02, 01));
DateTime startDate = new DateTime(2010, 01, 25);
DateTime endDate = new DateTime(2010, 02, 02);
List<DateTime> missingDates = new List<DateTime>(GetMissingDates(dates, startDate, endDate));
}
private static IEnumerable<DateTime> GetMissingDates(IList<DateTime> dates, DateTime startDate, DateTime endDate)
{
TimeSpan _timeStamp = endDate - startDate;
DateTime _tempDateTime = startDate;
IList<DateTime> _dateTimeRange = new List<DateTime>();
IList<DateTime> _missingDates = new List<DateTime>();
for (int i = 0; i <= _timeStamp.Days; i++)
{
_dateTimeRange.Add(_tempDateTime);
_tempDateTime = _tempDateTime.AddDays(1);
}
foreach (DateTime dt in _dateTimeRange)
{
if (!dates.Contains(dt))
yield return dt;
}
}
Lazy evaluated helper method aids in generating the list of dates to compare with. Might want to performance profile this method for large collections.
void Main()
{
var dates = new[] {new DateTime(2000,1,1), new DateTime(2000,1,5)};
DateHelper.Range(new DateTime(2000,1,1), new DateTime(2000,1,5)).Except(dates).Dump();
}
// Define other methods and classes here
public static class DateHelper {
public static IEnumerable<DateTime> Range(DateTime start, DateTime end) {
var days = end.Subtract(start).Days;
var next = start;
for(var i = 0; i<days; i++) {
next = next.AddDays(1);
yield return next;
}
}
}
var dates = new List<DateTime>
{
new DateTime( 2010, 01, 01 ),
new DateTime( 2010, 01, 02 ),
new DateTime( 2010, 01, 03 ),
new DateTime( 2010, 01, 05 )
};
var targetDate = new DateTime( 2010, 01, 01 );
var missingDates = new List<DateTime>();
while ( targetDate <= new DateTime( 2010, 01, 06 ) )
{
if ( !dates.Contains( targetDate ) )
missingDates.Add( targetDate );
targetDate = targetDate.AddDays( 1 );
}
foreach ( var date in missingDates )
Debug.WriteLine( date.ToString() );
If you were thinking of solving this is LINQ, I do not believe it is possible unless you also had a list of all dates between the min and max date. In SQL, this amounts to a calendar table that contains all dates across a given time period.
Here is a LINQ solution where I create the Calendar list I mentioned above and then query for missing dates:
var dates = new List<DateTime>
{
new DateTime( 2010, 01, 01 ),
new DateTime( 2010, 01, 02 ),
new DateTime( 2010, 01, 03 ),
new DateTime( 2010, 01, 05 )
};
var calendar = new List<DateTime>();
var targetDate = new DateTime( 2010, 01, 01 );
while ( targetDate <= new DateTime( 2010, 01, 06 ) )
{
calendar.Add( targetDate );
targetDate = targetDate.AddDays( 1 );
}
var missingDates = ( from date in calendar
where !dates.Contains( date )
select date ).ToList();
foreach ( var date in missingDates )
Debug.WriteLine( date.ToString() );

How to check if a DateTime range is within another 3 month DateTime range

Hi I have a Start Date and End Date per record in a db.
I need to check to see where the time period falls in a 2 year period broken into two lots of quarters then display what quarters each record falls into.
Quarter 1 includes June 09, Jul 09, Aug 09
Quarter 2 includes Sept 09, Oct 09, Nov 09
Quarter 3 includes Dec 09, Jan 10, Feb 10
Quarter 4 includes Mar 10, Apr 10, May 10
Quaretr 5 includes Jun 10, Jul 10...
e.g. 01/10/09 - 01/06/10 would fall into quarters 2, 3, 4 & 5
I am very new to .NET so any examples would be much appreciated.
This should work for you also.
class Range
{
public DateTime Begin { get; private set; }
public DateTime End { get; private set; }
public Range(DateTime begin, DateTime end)
{
Begin = begin;
End = end;
}
public bool Contains(Range range)
{
return range.Begin >= Begin && range.End <= End;
}
}
and then to use it
List<Range> ranges = new List<Range>();
ranges.Add(new Range(DateTime.Now, DateTime.Now.AddMonths(3)));
ranges.Add(new Range(DateTime.Now.AddMonths(3), DateTime.Now.AddMonths(6)));
Range test = new Range(DateTime.Now.AddMonths(1), DateTime.Now.AddMonths(2));
var hits = ranges.Where(range => range.Contains(test));
MessageBox.Show(hits.Count().ToString());
You would call IntervalInQuarters as follows:
IntervalInQuarters(new DateTime(2007, 10, 10), new DateTime(2009, 10, 11));
The function returns a list of quarter start dates. Note that the range of quarters searched is defined within the function itself. Please edit as appropriate for your situation. They key point is to make sure the interval/quarter intersection logic is right.
private List<DateTime> IntervalInQuarters(DateTime myStartDate, DateTime myEndDate)
{
DateTime quarterStart = new DateTime(2006, 06, 01);
DateTime nextQuarterStart = new DateTime(2006, 09, 01);
DateTime finalDate = new DateTime(2011, 01, 01);
List<DateTime> foundQuarters = new List<DateTime>();
while (quarterStart < finalDate)
{
// quarter intersects interval if:
// its start/end date is within our interval
// our start/end date is within quarter interval
DateTime quarterEnd = nextQuarterStart.AddDays(-1);
if (DateInInterval(myStartDate, quarterStart, quarterEnd) ||
DateInInterval(myEndDate, quarterStart, quarterEnd) ||
DateInInterval(quarterStart, myStartDate, myEndDate) ||
DateInInterval(quarterEnd, myStartDate, myEndDate))
{
foundQuarters.Add(quarterStart);
}
quarterStart = nextQuarterStart;
nextQuarterStart = nextQuarterStart.AddMonths(3);
}
return foundQuarters;
}
private bool DateInInterval(DateTime myDate, DateTime intStart, DateTime intEnd)
{
return ((intStart <= myDate) && (myDate <= intEnd));
}
private void Form1_Load(object sender, EventArgs e)
{
DateTime[,] ranges = new DateTime[3,2];
//Range 1 - Jan to March
ranges[0, 0] = new DateTime(2010, 1, 1);
ranges[0, 1] = new DateTime(2010, 3, 1);
//Range 2 - April to July
ranges[1, 0] = new DateTime(2010, 4, 1);
ranges[1, 1] = new DateTime(2010, 7, 1);
//Range 3 - March to June
ranges[2, 0] = new DateTime(2010, 3, 1);
ranges[2, 1] = new DateTime(2010, 6, 1);
DateTime checkDate = new DateTime(2010, 4, 1);
string validRanges = string.Empty;
for (int i = 0; i < ranges.GetLength(0); i++)
{
if (DateWithin(ranges[i,0], ranges[i,1], checkDate))
{
validRanges += i.ToString() + " ";
}
}
MessageBox.Show(validRanges);
}
private bool DateWithin(DateTime dateStart, DateTime dateEnd, DateTime checkDate)
{
if (checkDate.CompareTo(dateStart) < 0 || checkDate.CompareTo(dateEnd) > 0)
{
return false;
}
return true;
}
You may have to take a look at: http://msdn.microsoft.com/en-us/library/03ybds8y(v=VS.100).aspx
This may start you up
FindQuarter(DateTime startDate, DateTime endDate) // 01-10-09, 01-06-10
{
startDateQuarter = GetQuarter(startDate.Month); // 2
endDateQuarter = GetQuarter(endDate.Month); // 1
endDateQuarter += (endDate.Year - startDate.Year) * 4; // 5
// fill up startDateQuarter to endDateQuarter into a list
// and return it // 2,3,4,5
}
GetQuarter(int month) // 6
{
int quarter;
// check the month value and accordingly assign one of the basic quarters
// using if-else construct ie, if(month>=6 && month<=8){ quarter = 1 };
return quarter; // 1
}
Instead of GetQuarter() method, you can also use a dictionary to store your month to quarter mappings
Dictionary<int, int> quarter = new Dictionary<int, int>();
quarter.Add(1,1); //of the format Add(month,quarter)
quarter.Add(2,1);
...
Now instead of GetQuarter(someDate.Month); you can use quarter[someDate.Month];
If you want to compare two dates you should find out the first day of the quarter corresponds every of this dates, then you can compare this two dates:
using System;
namespace DataTime {
class Program {
static int GetQuarter (DateTime dt) {
int Month = dt.Month; // from 1 to 12
return Month / 3 + 1;
}
static DateTime GetQuarterFirstDay (DateTime dt) {
int monthsOfTheFirstDayOfQuarter = (GetQuarter (dt) - 1) * 3 + 1;
return new DateTime(dt.Year, monthsOfTheFirstDayOfQuarter, 1);
// it can be changed to
// return new DateTime(dt.Year, (dt.Month/3)*3 + 1, 1);
}
static void Main (string[] args) {
DateTime dt1 = new DateTime (2009, 6, 9),
dt2 = new DateTime (2009, 7, 9),
dt3 = new DateTime (2009, 8, 9),
dt4 = new DateTime (2009, 8, 9);
Console.WriteLine ("dt1={0}", dt1.AddMonths (1));
Console.WriteLine ("dt2={0}", dt2.AddMonths (1));
Console.WriteLine ("dt3={0}", dt3.AddMonths (1));
DateTime startDate = DateTime.Now,
endDate1 = startDate.AddMonths(24).AddDays(1),
endDate2 = startDate.AddMonths(24).AddDays(-1),
endDate3 = startDate.AddMonths(28);
Console.WriteLine ("Now we have={0}", startDate);
Console.WriteLine ("endDate1={0}", endDate1);
Console.WriteLine ("endDate2={0}", endDate2);
Console.WriteLine ("endDate3={0}", endDate3);
Console.WriteLine ("GetQuarterFirstDay(startDate)={0}", GetQuarterFirstDay (startDate));
Console.WriteLine ("GetQuarterFirstDay(endDate1)={0}", GetQuarterFirstDay (endDate1));
Console.WriteLine ("GetQuarterFirstDay(endDate2)={0}", GetQuarterFirstDay (endDate2));
Console.WriteLine ("GetQuarterFirstDay(endDate3)={0}", GetQuarterFirstDay (endDate3));
if (DateTime.Compare (GetQuarterFirstDay (endDate2), GetQuarterFirstDay (startDate).AddMonths (24)) > 0)
Console.WriteLine ("> 2 Yeas");
else
Console.WriteLine ("<= 2 Yeas");
if (DateTime.Compare (GetQuarterFirstDay (endDate3), GetQuarterFirstDay (startDate).AddMonths (24)) > 0)
Console.WriteLine ("> 2 Yeas");
else
Console.WriteLine ("<= 2 Yeas");
}
}
}
produce
dt1=09.07.2009 00:00:00
dt2=09.08.2009 00:00:00
dt3=09.09.2009 00:00:00
Now we have=22.04.2010 11:21:45
endDate1=23.04.2012 11:21:45
endDate2=21.04.2012 11:21:45
endDate3=22.08.2012 11:21:45
GetQuarterFirstDay(startDate)=01.04.2010 00:00:00
GetQuarterFirstDay(endDate1)=01.04.2012 00:00:00
GetQuarterFirstDay(endDate2)=01.04.2012 00:00:00
GetQuarterFirstDay(endDate3)=01.07.2012 00:00:00
<= 2 Yeas
> 2 Yeas
EDITED: I fixed an error from the first version. Now it should works correct.

Categories

Resources