So I'm back with another baffling DateTime question.
In C#, how would I return the (day) for every Friday from a start date (DateTime.Now) until the end of the current year?
So for example, today being Friday the 19th, it would return, 26, 2, 9, 16, 23, 30, 7, etc.
Does this work?
static IEnumerable<DateTime> GetFridays(DateTime startdate, DateTime enddate)
{
// step forward to the first friday
while (startdate.DayOfWeek != DayOfWeek.Friday)
startdate = startdate.AddDays(1);
while (startdate < enddate)
{
yield return startdate;
startdate = startdate.AddDays(7);
}
}
var start = DateTime.Today;
var startDay = ((int) start.DayOfWeek);
var nextFriday = startDay<6 //5 if today is friday and you don't want to count it
? start.AddDays(5 - startDay) //friday this week
: start.AddDays(12 - startDay); //friday next week
var remainingFridays = Enumerable.Range(0,53)
.Select(i => nextFriday.AddDays(7 * i))
.TakeWhile(d => d.Year == start.Year);
This would do what you want.
IList<int> getFridaysForYearFromPoint(DateTime startDate)
{
DateTime currentFriday = startDate;
List<int> results = new List<int>();
//Find the nearest Friday forward of the start date
while(currentFriday.DayOfWeek != DayOfWeek.Friday)
{
currentFriday = currentFriday.AddDays(1);
}
//FIND ALL THE FRIDAYS!
int currentYear = startDate.Year;
while (currentFriday.Year == currentYear)
{
results.Add(startDate.Day);
currentFriday = currentFriday.AddDays(7);
}
return results;
}
My Answer...
static void Main(string[] args)
{
DateTime begin = DateTime.Now;
DateTime end = DateTime.Now.AddDays(200);
while (begin <= end)
{
if (begin.DayOfWeek == DayOfWeek.Friday)
Console.WriteLine(begin.ToLongDateString());
begin = begin.AddDays(1);
}
Console.ReadKey();
}
You can use the CalendarPeriodCollector of the Time Period Library for .NET:
// ----------------------------------------------------------------------
public void FindRemainigYearFridaysSample()
{
// filter: only Fridays
CalendarPeriodCollectorFilter filter = new CalendarPeriodCollectorFilter();
filter.WeekDays.Add( DayOfWeek.Friday );
// the collecting period
CalendarTimeRange collectPeriod = new CalendarTimeRange( DateTime.Now, new Year().End.Date );
// collect all Fridays
CalendarPeriodCollector collector = new CalendarPeriodCollector( filter, collectPeriod );
collector.CollectDays();
// show the results
foreach ( ITimePeriod period in collector.Periods )
{
Console.WriteLine( "Friday: " + period );
}
} // FindRemainigYearFridaysSample
I'm expert in vb.net .. but there is no different ..
I wrote the code below in page_load of a asp.net web form ...
make an asp.net application
add a web form to it
write the code below in page_load
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim gc As New System.Globalization.GregorianCalendar
Dim d As New DateTime(gc.GetYear(DateTime.Now), 1, 1)
Dim i As Int16 = 1
While i <= gc.GetDaysInYear(gc.GetYear(DateTime.Now))
If gc.GetDayOfWeek(d) = DayOfWeek.Friday Then
Response.Write(d & "<br />")
d = gc.AddDays(d, 7)
i += 7
Else
d = gc.AddDays(d, 1)
i += 1
End If
End While
End Sub
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Can anyone please help me. What I need to C# logic for the display in advance and sequence order six date list on Monday. In advance date list should change after 12.00PM. For example on Monday 28 March, date will display same day(28 March) till 12.00pm. After 12.01 pm, first date start from 11 April 2016. Also same sequence(attached screen). It is never display 4th April, 18th April etc.. (sequence order )..
This is my effort C# code, it's only display single date list.
public static void Main(string[] args)
{
DateTime time = new DateTime(2016, 3, 25);
var breaks = DateTime.Today.AddHours(12D);
if (breaks>=DateTime.Now)
{
}
else if (time<DateTime.Now)
{
}
DateTime anotherTime = DateTime.Now;
var allTimes = new HashSet<DateTime>();
for (int i = 0; i < 6; i++)
{
anotherTime = time.AddDays(14);
time = anotherTime;
Console.WriteLine(anotherTime.ToLongDateString());
allTimes.Add(time);
}
}
}
This is my final out put in advance six date list
Try this
static void Main(string[] args)
{
DateTime today = DateTime.Now;
if ((today.DayOfWeek == DayOfWeek.Monday) && (today > new DateTime(today.Year, today.Month, today.Day, 12, 0, 0)))
{
today.AddDays(1);
}
int offsetToMonday = 7 - (((int)today.DayOfWeek - 1) % 7);
DateTime nextMonday = today.AddDays(offsetToMonday);
DateTime startDate = (nextMonday.DayOfYear / 7 % 2) == 0 ? nextMonday : nextMonday.AddDays(7);
DateTime endDate = startDate.AddDays(83);
List<DateTime> dates = new List<DateTime>();
for (DateTime date = startDate; date <= endDate; date = date.AddDays(1))
{
dates.Add(date);
}
var groupedDays = dates.AsEnumerable()
.GroupBy(x => x.Subtract(startDate).Days % 14)
.OrderBy(x => x.Key)
.Where(x => x.Key == 0);
foreach (var group in groupedDays)
{
foreach (DateTime day in group)
{
Console.WriteLine(day.ToString("dddd, dd MMMM yyyy"));
}
Console.WriteLine();
}
Console.ReadLine();
}
I am not sure if I understand what you exactly want. But I have a similar function in my repository.
public static DateTime GetNextDayOfWeek(DateTime _date, DayOfWeek _dayOfWeek)
{
DateTime Result;
int diff = _date.DayOfWeek - _dayOfWeek;
if (diff == 0 && _date.Hour * 100 + _date.Minute <= 1200)
return _date;
if (diff < 0)
{
diff += 7;
}
Result = _date.AddDays(-1 * diff).Date;
if (Result <= _date)
Result = Result.AddDays(7);
return Result;
}
I added this part for your needs
if (diff == 0 && _date.Hour * 100 + _date.Minute <= 1200) return _date;
This functions takes a date and a desired day of week and returns the closest next date when the desired day of week will be present.
Since I understand you want 6 packs of these, you can put it in a loop like this:
DateTime next;
next=DateTime.Now;
foreach(DayOfWeek dow in Enum.GetValues(typeof(DayOfWeek)))
{
for(var n=0;n<6;n++)
{
next=GetNextDayOfWeek(next, dow);
//do something with your date
}
}
You could add another parameter for how many days you wand advance. Currently it if fixed to 7. In your case you would need 14.
i want c# code for getting Last Date of week for given month and year.
suppose given month is 1 and year is 2016 then method should return me
--01/02/2016
--01/09/2016
--01/16/2016
--01/23/2016
--01/30/2016
--02/06/2016
So you want a method which takes a year and a month as parameter and returns dates. Those dates should be the last dates of all weeks in that month, optionally also of following months.
This should work then:
public static IEnumerable<DateTime> GetLastWeekDatesOfMonth(int year, int month, DayOfWeek firstDayOfWeek = DayOfWeek.Monday, bool includeLaterMonths = false)
{
DateTime first = new DateTime(year, month, 1);
int daysOffset = (int)firstDayOfWeek - (int)first.DayOfWeek;
if (daysOffset < 0)
daysOffset = 7 - Math.Abs(daysOffset);
DateTime firstWeekDay = first.AddDays(daysOffset);
DateTime current = firstWeekDay.AddDays(-1); // last before week start
if (current.Month != month)
current = current.AddDays(7);
yield return current;
if (includeLaterMonths)
{
while (true)
{
current = current.AddDays(7);
yield return current;
}
}
else
{
while((current = current.AddDays(7)).Month == month)
yield return current;
}
}
Your sample:
var lastDates = GetLastWeekDatesOfMonth(2016, 1, DayOfWeek.Sunday, true);
foreach (DateTime dt in lastDates.Take(6))
Console.WriteLine(dt.ToShortDateString());
public static DateTime GetLastDateofWeek(int yr, int mnth, int week)
{
DateTime dt = new DateTime(yr, mnth, 1);
DateTime newdate = new DateTime();
if (dt.DayOfWeek == DayOfWeek.Monday)
{
newdate = dt.AddDays(((week - 1) * 7) + 5);
}
else
{
newdate = dt.AddDays((8 - (int)dt.DayOfWeek) % 7 + ((week - 2) * 7) + 5);
}
return newdate;
}
First get month and year, example:
int year = 2016;
int month = 1;
And then create a new instance of the DateTime class that represents the first saturday.
DateTime firstsaturday = new DateTime(year,month,1);
while(firstsaturday.DayOfWeek != DayOfWeek.Saturday)
{
firstsaturday = firstsaturday.AddDays(1);
]
Then create a List of DateTime values.
List<DateTime> saturdays = new List<DateTime>();
saturdays.Add(firstsaturday);
And then cycle through all saturdays using a loop.
DateTime CurrentSaturday = firstsaturday;
while(CurrentSaturday.AddDays(7).Month == month)
{
CurrentSaturday = CurrentSaturday.AddDays(7);
Saturdays.Add(CurrentSaturday);
}
You may try this code.
using System;
public class Program
{
public static void Main()
{
DateTime thisMonthInLastYear = DateTime.Now.AddYears(-1);
DateTime endOfMonth = new DateTime(thisMonthInLastYear.Year,
thisMonthInLastYear.Month,
DateTime.DaysInMonth(thisMonthInLastYear.Year,
thisMonthInLastYear.Month));
Console.WriteLine("Today : "+DateTime.Now.ToString("dd-MM-yyyy"));
Console.WriteLine("This Month in last years : "+endOfMonth.ToString("dd-MM-yyyy"));
Console.WriteLine("Next month in last years : "+endOfMonth.AddMonths(1).ToString("dd-MM-yyyy"));
}
}
I have a flag enum for representing every day of the week. (Sunday, Monday etc.). Lets call this the WeekDay enum. Now given a interval find all dates for the days in the WeekDaysvariable.
For eg: WeekDays daysAll = WeekDays.Sunday | WeekDays.Friday;
Now find the dates for all the Sunday and Friday dates in a given interval.
So i thought of the following logic: Find the first Sunday, Friday, as in the above example.
Add these dates to a temporary dictionary. Now iterate that dictionary and keep on adding 7 days till the end interval is reached.
int dayCounter = 0;
WeekDays daysAll = WeekDays.Sunday | WeekDays.Friday;
Dictionary<DayOfWeek, DateTime> tempDict = new Dictionary<DayOfWeek, DateTime>();
for (var day = intervalStartDate.Date; (dayCounter < 7 && day.Date <= intervalEndDate.Date); day = day.AddDays(1))
{
WeekDays check = GetWeekDayFromDayOfWeek(day.DayOfWeek); //This Function converts from the DateTime DayOfweek enum to the WeekDays enum.
if ((check & daysAll) == check)
{
tempDict.Add(day.DayOfWeek, day);
}
dayCounter++;
}
Now keep adding 7 days for every date in the dict till end interval is reached:
if (tempDict.Keys.Count > 0)
{
List<DateTime> allDates = new List<DateTime>();
var keys = new List<DayOfWeek>(tempDict.Keys);
bool opComplete = false;
while (!opComplete)
{
foreach (DayOfWeek dayOfWeek in keys)
{
if (tempDict[dayOfWeek] > intervalEndDate.Date) { opComplete = true; break; }
allDates.Add(tempDict[dayOfWeek]);
tempDict[dayOfWeek] = tempDict[dayOfWeek].AddDays(7);
}
}
}
So my question is: Can this algorithm be improved? Can LinQ be used to make the intent more clearer in the code itself?
Performance optimization and clearer code are not the same in most cases.
The clearer LINQ version would be like this:
public IEnumerable<DateTime> IntervalDays(DateTime start, DateTime end)
{
if (start > end)
yield break;
var d = start.Date;
while (d <= end.Date)
{
yield return d;
d = d.AddDays(1);
}
}
and the you write the query as in this example:
IntervalDays(startDate, endDate)
.Where(d=>d.DayOfWeek==DayOfWeek.Friday || d.DayOfWeek==DayOfWeek.Sunday);
The good thing here is you can easily query other days of the week etc.
For the optimized code, if you mean performance, you'd better not iterate one by one but find the first Friday or Sunday and move along by adding 2 or 5 days depending on the date
Few ways, as a general method, pass in the day of week you want with start and end dates.
private List<DateTime> GetDates(DateTime startDate, DateTime endDate, DayOfWeek dayOfWeek)
{
var returnDates = new List<DateTime>();
for (DateTime dateCounter = startDate; dateCounter < endDate; dateCounter = dateCounter.AddDays(1))
{
if (dateCounter.DayOfWeek == dayOfWeek)
{
returnDates.Add(dateCounter);
}
}
return returnDates;
}
Or return full date range and query that using linq.
private List<DateTime> GetDates(DateTime startDate, DateTime endDate)
{
var returnDates = new List<DateTime>();
for (DateTime dateCounter = startDate; dateCounter < endDate; dateCounter = dateCounter.AddDays(1))
{
returnDates.Add(dateCounter);
}
return returnDates;
}
query:
var myDates = GetDates(DateTime.Now, DateTime.Now.AddDays(30)).Where(i => i.DayOfWeek == DayOfWeek.Friday);
I have two labels First day and Last day in which I want to update it on button click.
I need Function to Get First day and last day of current date so that I can display it on click of next and previous button.
Here is what I have so far:
CultureInfo cultureInfo = CultureInfo.CurrentCulture;
DayOfWeek firstDay = cultureInfo.DateTimeFormat.FirstDayOfWeek;
firstDayInWeek = dayInWeek.Date;
lastDayInWeek = dayInWeek.Date;
while (firstDayInWeek.DayOfWeek != firstDay)
firstDayInWeek = firstDayInWeek.AddDays(-1);
but does not give me the next week after this month.
This is what exactly i'm looking for :
Any one can help to make this working using a single function.
DateTime baseDate = DateTime.Now;
var thisWeekStart = baseDate.AddDays(-(int)baseDate.DayOfWeek);
var thisWeekEnd = thisWeekStart.AddDays(7).AddSeconds(-1);
Try this :
private static void GetWeek(DateTime now, CultureInfo cultureInfo, out DateTime begining, out DateTime end)
{
if (now == null)
throw new ArgumentNullException("now");
if (cultureInfo == null)
throw new ArgumentNullException("cultureInfo");
var firstDayOfWeek = cultureInfo.DateTimeFormat.FirstDayOfWeek;
int offset = firstDayOfWeek - now.DayOfWeek;
if (offset != 1)
{
DateTime weekStart = now.AddDays(offset);
DateTime endOfWeek = weekStart.AddDays(6);
begining = weekStart;
end = endOfWeek;
}
else
{
begining = now.AddDays(-6);
end = now;
}
}
Usage example:
DateTime begining;
DateTime end;
var testDate = new DateTime(2012, 10, 10);
GetWeek(testDate, new CultureInfo("fr-FR"), out begining, out end);
Console.WriteLine("Week {0} - {1}",
begining.ToShortDateString(),
end.ToShortDateString()); // will output Week 10/8/2012 - 10/14/2012
So, on a button click, you have a one week period. Lets say that is defined by a starting date. The DateTime structure has a property DayOfWeek that returns an enum like DayOfWeek.Sunday. So here is a code fragment that may help:
var startOfWeek = DateTime(xx, yy ...); // defined by your business code
var firstDayOfWeek = startOfWeek.DayOfWeek;
var lastDayOfWeek = firstDayOfWeek.AddDays(6).DayOfWeek;
I have not compiled this code, straight off my head, so hope it is okay.
I need to get a list of weeks for a given month, with Monday as the start day.
So for example, for the month of February 2009, this method would return:
2/2/2009
2/9/2009
2/16/2009
2/23/2009
// Get the weeks in a month
DateTime date = DateTime.Today;
// first generate all dates in the month of 'date'
var dates = Enumerable.Range(1, DateTime.DaysInMonth(date.Year, date.Month)).Select(n => new DateTime(date.Year, date.Month, n));
// then filter the only the start of weeks
var weekends = from d in dates
where d.DayOfWeek == DayOfWeek.Monday
select d;
public static List<DateTime> GetWeeks(
this DateTime month, DayOfWeek startOfWeek)
{
var firstOfMonth = new DateTime(month.Year, month.Month, 1);
var daysToAdd = ((Int32)startOfWeek - (Int32)month.DayOfWeek) % 7;
var firstStartOfWeek = firstOfMonth.AddDays(daysToAdd);
var current = firstStartOfWeek;
var weeks = new List<DateTime>();
while (current.Month == month.Month)
{
weeks.Add(current);
current = current.AddDays(7);
}
return weeks;
}
Here's a solution (effectively one line) using C# 3.0/LINQ, in case you're interested:
var month = new DateTime(2009, 2, 1);
var weeks = Enumerable.Range(0, 4).Select(n => month.AddDays(n * 7 - (int)month.DayOfWeek + 1)).TakeWhile(monday => monday.Month == month.Month);
int year = 2009;
int month = 2;
DateTime startDate = new DateTime(year, month, 1);
DateTime endDate = startDate.AddMonths(1);
while (startDate.DayOfWeek != DayOfWeek.Monday)
startDate = startDate.AddDays(1);
for (DateTime result = startDate; result < endDate; result = result.AddDays(7))
DoWhatYouWant(result);
How about this?
public IEnumerable<DateTime> GetWeeks(DateTime date, DayOfWeek startDay)
{
var list = new List<DateTime>();
DateTime first = new DateTime(date.Year, date.Month, 1);
for (var i = first; i < first.AddMonths(1); i = i.AddDays(1))
{
if (i.DayOfWeek == startDay)
list.Add(i);
}
return list;
}
Something like the following pseudo-code should work:
Determine the start date of the month (use month and year from a date and set the day to 1
Determine the end date of the month (start date + 1 month)
Determine the first date that is a monday (this is your first item in the list)
Add 7 days to find the next date and repeat until you read or pass the month end
Just change the response line to what ever you need to do with it
protected void PrintDay(int year, int month, DayOfWeek dayName)
{
CultureInfo ci = new CultureInfo("en-US");
for (int i = 1 ; i <= ci.Calendar.GetDaysInMonth (year, month); i++)
{
if (new DateTime (year, month, i).DayOfWeek == dayName)
Response.Write (i.ToString() + "<br/>");
}
}
Quick solution: i don't think there is a built in function for it....
I see you got your answer, but I wanted to share with you a helper class I created for one of my projects. It's far to be a comprehansive class, but might help...
public static class WeekHelper {
#region Public Methods
public static DateTime GetWeekStart(DateTime date) {
DateTime weekStart;
int monday = 1;
int crtDay = (int)date.DayOfWeek;
if (date.DayOfWeek == DayOfWeek.Sunday)
crtDay = 7;
int difference = crtDay - monday;
weekStart = date.AddDays(-difference);
return weekStart;
}
public static DateTime GetWeekStop(DateTime date) {
DateTime weekStart;
int sunday = 7;
int crtDay = (int)date.DayOfWeek;
if (date.DayOfWeek == DayOfWeek.Sunday)
crtDay = 7;
int difference = sunday - crtDay;
weekStart = date.AddDays(difference);
return weekStart;
}
public static void GetWeekInterval(int year, int weekNo,
out DateTime weekStart, out DateTime weekStop) {
GetFirstWeekOfYear(year, out weekStart, out weekStop);
if (weekNo == 1)
return;
weekNo--;
int daysToAdd = weekNo * 7;
DateTime dt = weekStart.AddDays(daysToAdd);
GetWeekInterval(dt, out weekStart, out weekStop);
}
public static List<KeyValuePair<DateTime, DateTime>> GetWeekSeries(DateTime toDate) {
//gets week series from beginning of the year
DateTime dtStartYear = new DateTime(toDate.Year, 1, 1);
List<KeyValuePair<DateTime, DateTime>> list = GetWeekSeries(dtStartYear, toDate);
if (list.Count > 0) {
KeyValuePair<DateTime, DateTime> week = list[0];
list[0] = new KeyValuePair<DateTime, DateTime>(dtStartYear, week.Value);
}
return list;
}
public static List<KeyValuePair<DateTime, DateTime>> GetWeekSeries(DateTime fromDate, DateTime toDate) {
if (fromDate > toDate)
return null;
List<KeyValuePair<DateTime, DateTime>> list = new List<KeyValuePair<DateTime, DateTime>>(100);
DateTime weekStart, weekStop;
toDate = GetWeekStop(toDate);
while (fromDate <= toDate) {
GetWeekInterval(fromDate, out weekStart, out weekStop);
list.Add(new KeyValuePair<DateTime, DateTime>(weekStart, weekStop));
fromDate = fromDate.AddDays(7);
}
return list;
}
public static void GetFirstWeekOfYear(int year, out DateTime weekStart, out DateTime weekStop) {
DateTime date = new DateTime(year, 1, 1);
GetWeekInterval(date, out weekStart, out weekStop);
}
public static void GetWeekInterval(DateTime date,
out DateTime dtWeekStart, out DateTime dtWeekStop) {
dtWeekStart = GetWeekStart(date);
dtWeekStop = GetWeekStop(date);
}
#endregion Public Methods
}
This works beautifully! All you have to do is get the first day of the month you want to get the weeks for and then this will give you the first day of every week. You need to get 5 weeks (not 4) so the Enumerable.Range counts out 5 instead of 4.
var date = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
var weeks = from n in Enumerable.Range(0, 5)
select date.AddDays(7 * n + (-1 * (int)date.DayOfWeek));
Here's what i did, using Chaowlert's code as a starting base. Basically i modified that you need to check if adding the days in the for overflows to the next month, so i don't add 4 days (monday to friday), but actually the minimum between 4 and the number of remaining days in the month. Also, i check if the current day is a weekend, otherwise add days until it's a weekday. My purpose is to print the weeks in a month, from monday to friday
DateTime fechaInicio = new DateTime(año, mes, 1);
DateTime fechaFin = fechaInicio.AddMonths(1);
int diasHastaFinMes = 0;
while (esFinDeSemana(fechaInicio))
fechaInicio = fechaInicio.AddDays(1);
for (DateTime fecha = fechaInicio; fecha < fechaFin; fecha = fecha.AddDays(7))
{
diasHastaFinMes = DateTime.DaysInMonth(fecha.Year, fecha.Month) - fecha.Day;
printWeeks(fecha, fecha.AddDays(Math.Min(4, diasHastaFinMes)));
}