How to calculate 2nd Friday of Month in C# [duplicate] - c#

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to find the 3rd Friday in a month with C#?
Hi everyone,
I've wrote a little console utility that spits out a line into a text file. I want this line to include the second Friday of the current month. Is there any way to do this?
Thanks everyone!

Slight variation on #druttka: using an extension method.
public static DateTime NthOf(this DateTime CurDate, int Occurrence , DayOfWeek Day)
{
var fday = new DateTime(CurDate.Year, CurDate.Month, 1);
var fOc = fday.DayOfWeek == Day ? fday : fday.AddDays(Day - fday.DayOfWeek);
// CurDate = 2011.10.1 Occurance = 1, Day = Friday >> 2011.09.30 FIX.
if (fOc.Month < CurDate.Month) Occurrence = Occurrence+1;
return fOc.AddDays(7 * (Occurrence - 1));
}
Then called it like this:
for (int i = 1; i < 13; i++)
{
Console.WriteLine(new DateTime(2011, i,1).NthOf(2, DayOfWeek.Friday));
}

I would go for something like this.
public static DateTime SecondFriday(DateTime currentMonth)
{
var day = new DateTime(currentMonth.Year, currentMonth.Month, 1);
day = FindNext(DayOfWeek.Friday, day);
day = FindNext(DayOfWeek.Friday, day.AddDays(1));
return day;
}
private static DateTime FindNext(DayOfWeek dayOfWeek, DateTime after)
{
DateTime day = after;
while (day.DayOfWeek != dayOfWeek) day = day.AddDays(1);
return day;
}

Untested, but this should grab it.
DateTime today = DateTime.Today;
DateTime secondFriday =
Enumerable.Range(8, 7)
.Select(item => new DateTime(today.Year, today.Month, item))
.Where(date => date.DayOfWeek == DayOfWeek.Friday)
.Single();

fully tested:
for (int mo = 1; mo <= 12; mo++)
{
DateTime _date = new DateTime(yr, mo, 1);
DayOfWeek day = _date.DayOfWeek;
int d = 0;
if (day == DayOfWeek.Saturday)
d += 7;
var diff = DayOfWeek.Friday - day;
DateTime secFriday = _date.AddDays(diff + 7 + d);
Console.WriteLine(secFriday.ToString("MM\tddd\tdd"));
}
Final results:
Month Date
=====================
01 Fri 14
02 Fri 11
03 Fri 11
04 Fri 08
05 Fri 13
06 Fri 10
07 Fri 08
08 Fri 12
09 Fri 09
10 Fri 14
11 Fri 11
12 Fri 09

Related

DateTime get day of year

I want my new year to start at 14 March. Given any DateTime I want to get the day of year? How can I accomplish this with DateTime?
March 14 is the 73rd day of the year (74th in leap years) in the Gregorian calendar. 292 days remain until the end of the year. Is there a way I can define the new year of a year with DateTime?
int DayOfYear(DateTime date, int yearStartMonth, int yearStartDay)
{
var yearStart = new DateTime(d.Year, yearStartMonth, yearStartDay);
if(yearStart > d)
yearStart = yearStart.AddYears(-1);
return (d - yearStart).Days + 1;
}
try to use:
public static int DayOfYear(DateTime date)
{
var startDate= new DateTime(year:date.Year,month:3,day:14); //14 March
var diffDateDays=(date- startDate).Days;
if (diffDateDays > 0) return diffDateDays;
startDate= new DateTime(year:date.Year-1,month:3,day:14); //14 March of previous year
return (date- startDate).Days;
}

DateTime Setting dates for next day

I have a Google API that takes date and time and sets up a event in customers calendar and the problem is I am using date time to add hours to the event when I boot time for 12pm noon For whatever reason, it will be listed in my Google Calendar for the day after at 12am.
Here is the code that sets up the date and the time:
// dd is a drop down for hours 1 to 12 Central Time Zone
int iHour = Convert.ToInt32(dd.SelectedItem.Text);
// and this is the minutes values of 30 or 45
int iMinute = Convert.ToInt32(ddMinute.SelectedItem.Text);
var date = "Nov 19, 2017";
DateTime dt = new DateTime();
dt = Convert.ToDateTime(date);
// If its PM set 12 hours more to it because its a 24 hours clock
if (ddAptAmPm.SelectedValue == "PM")
iHour += 12;
dt = dt.AddHours(iHour);
dt = dt.AddMinutes(iMinute);
var startDate = dt;
var endDate = dt;
string sNotes = "TestingA PI";
string sTitle = "Testas" + " with: " + "ASP.NEt" + " " + "Last Name here";
int length = Convert.ToInt32("30");
endDate = endDate.AddMinutes(length);
var google = new GoogleCalendar();
int value = google.CreateCalendarEvent("email", startDate, endDate, sNotes, sTitle);
Can any one see where did I do this wrong
if (ddAptAmPm.SelectedValue == "PM") // If its PM set 12 hours more to it because its a 24 hours clock
iHour += 12;
should be:
if (ddAptAmPm.SelectedValue == "PM" && iHour < 12) // If its 1-11 PM set 12 hours more to it because its a 24 hours clock
iHour += 12;
else if (ddAptAmPm.SelectedValue == "AM" && iHour == 12)
iHour = 0;
Since 12 + 12 is 24, and today plus 24 hours is the next day.
Another way to write it:
if (iHour == 12) // 12 is **before** 1
iHour = 0;
if (ddAptAmPm.SelectedValue == "PM") // If its PM set 12 hours more to it because its a 24 hours clock
iHour += 12;
Another way you could do it is to construct a date string in a specific format (including the AM or PM designation), and then use DateTime.ParseExact to create your startDate. This way you don't have to do all the conversion from string to int, then add 12 hours if PM was specified, etc.
For example, this code would replace everything you currently have up to and including the startDate assignment:
// This assumes that ddAptAmPm.SelectedValue will be "AM" or "PM"
var dateString = string.Format("Nov 19, 2017 {0}:{1} {2}", dd.SelectedItem.Text,
ddMinute.SelectedItem.Text, ddAptAmPm.SelectedValue);
// In a format string, tt is a placeholder for AM/PM
var startDate = DateTime.ParseExact(dateString, "MMM dd, yyyy h:m tt",
CultureInfo.InvariantCulture);
You can read more about Date and Time Format Strings here.

Calculate 14 days sequence order

Can anyone please help me, how do I calculate fortnightly (14 days) logic using C#?, for a example 14 days start following sequence order on February
Monday start date 8 Feb (next 22 Feb, 7 March, 21 March etc..)
Thursday start date 11 February (next 25 Feb, 10 March, 24 March etc..)
Friday start date 12 February (next 26 Feb, 11 March, 25 March etc..)
My logic is not working for the 14 days day display, because 15 February will come 14 days add, it’ll display “First14days” date 29 February 2016, it is a wrong.
This is C# logic
Day.Days value are Monday, Thursday, Friday etc..
foreach (var Day in day)
{
Example Day.Days = Monday
Int 14days = (((int)Enum.Parse(typeof(DayOfWeek), Day.Days) - (int)today.DayOfWeek + 14) % 7);
DateTime First14days = today.AddDays(14days);
}
My output should be
Simply add TimeSpan.FromDays(14) to any date to get a fortnight further on
DateTime startDate = DateTime.Now;
TimeSpan fortnight = TimeSpan.FromDays(14);
for (int i = 0; i < 6; i++)
{
startDate += fortnight;
Console.WriteLine($"Date for fortnight {i}: {startDate:D}");
}
If I understand correct your question this code will be working for you.
DateTime 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);
}
// or with your example is possible to like this code.
foreach (var Day in day)
{
anotherTime = Day.AddDays(14);
time = anotherTime;
Console.WriteLine(anotherTime.ToLongDateString());
allTimes.Add(time);
}
First create two DataTime objects. then foreach few times, and in for loop statement set anotherTime = time.AddDays(14) after that set time = anotherTime.
//Output:
//Saturday, February 27, 2016
//Saturday, March 12, 2016
//Saturday, March 26, 2016
//Saturday, April 09, 2016
//Saturday, April 23, 2016
//Saturday, May 07, 2016
EDIT:
I create and HashSet where you can save all you DateTime who you make it.
So here's you all-in-one solution:
// determine the date of next given weekday
DateTime date = GetNextWeekday(DateTime.Today, DayOfWeek.Tuesday);
// create a list and add the start date (if you want)
List<DateTime> fortnights = new List<DateTime>() { date };
// add as many "fortnights" as you like (e.g. 5)
for (int i = 0; i < 5; i++)
{
date = date.Add(TimeSpan.FromDays(14));
fortnights.Add(date);
}
// use your list (here: just for printing the list in a console app)
foreach (DateTime d in fortnights)
{
Console.WriteLine(d.ToLongDateString());
}
Method to get the next weekday, from:
https://stackoverflow.com/a/6346190/2019384
public static DateTime GetNextWeekday(DateTime start, DayOfWeek day)
{
// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]
int daysToAdd = ((int) day - (int) start.DayOfWeek + 7) % 7;
return start.AddDays(daysToAdd);
}

Loop week based on culture info

How do I loop the whole week (monday-sunday) based on culture info, so in my case monday will be the first day of the week? And is it possible to find the int value of the day at the same time?
For some information: I need to make this in order to make some generel opening hours for a store.
I think what you need is the following loop.
DayOfWeek firstDay = CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;
for (int dayIndex = 0; dayIndex < 7; dayIndex++)
{
var currentDay = (DayOfWeek) (((int) firstDay + dayIndex) % 7);
// Output the day
Console.WriteLine(dayIndex + " " + currentDay);
}
The modulo 7 is important, because the firstdayofweek can vary by different cultures.
This would give you the first day of the week in a given culture.
DayOfWeek firstDay = CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;
this could subsequently be...
int firstDay = CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;
DayOfWeek.Sunday = zero
DayOfWeek.Saturday = 6
You would iterate it like any other int.
http://msdn.microsoft.com/en-us/library/system.dayofweek.aspx
DateTime Dt = new DateTime(2011,5,13,0,0,0);
int WeeklyOffValue = (int)Dt.DayOfWeek
The Time Period Library for .NET includes the class Week with support of the culture:
// ----------------------------------------------------------------------
public void WeekDaysSample()
{
Week week = new Week( new DateTime( 2011, 05, 13 ) );
foreach ( Day day in week.GetDays() )
{
Console.WriteLine( "Day: {0}, DayOfWeek: {1}, Int: {2}", day, day.DayOfWeek, (int)day.DayOfWeek );
// > Day: Montag; 09.05.2011 | 0.23:59, DayOfWeek: Monday, Int: 1
// > Day: Dienstag; 10.05.2011 | 0.23:59, DayOfWeek: Tuesday, Int: 2
// > Day: Mittwoch; 11.05.2011 | 0.23:59, DayOfWeek: Wednesday, Int: 3
// > Day: Donnerstag; 12.05.2011 | 0.23:59, DayOfWeek: Thursday, Int: 4
// > Day: Freitag; 13.05.2011 | 0.23:59, DayOfWeek: Friday, Int: 5
// > Day: Samstag; 14.05.2011 | 0.23:59, DayOfWeek: Saturday, Int: 6
// > Day: Sonntag; 15.05.2011 | 0.23:59, DayOfWeek: Sunday, Int: 0
}
} // WeekDaysSample
This works even today, Friday the 13th :)
for (int i = 1; i <= 7; i++)
Console.WriteLine(new DateTime(2014, 6, i).ToString("DDDD", culture));
July 1, 2014 - Sunday
I believe you want to loop through the weeks, something like this
foreach (DayOfWeek dy in Enum.GetValues(typeof(DayOfWeek)))
{
dy.ToString() // this would be Sunday, monday ......
}

How to chop a continuous date range list into a list of financial year in C#?

Example: given a continuous list of date range
List[0] = from 2001 Jan 01 to 2001 Aug 14
List[1] = from 2001 Aug 15 to 2002 Jul 10
Let’s assume that a financial year is from 1st of July to 30th of June (of next year) so the output should be
AnotherList[0] = from 2000 Jul 01 to 2001 Jun 30
period: 2001 Jan 01 to 2001 Jun 30
AnotherList[1] = from 2001 July 01 to 2002 Jun 30
period: 2001 Jul 01 to 2001 Aug 14
period: 2001 Aug 15 to 2002 Jun 30
AnotherList[2] = from 2002 July 01 to 2003 Jun 30
period: 2002 Jul 01 to 2002 Jul 10
Again it's very easy to work out by hand but my method contains close to 100 lines of code with the combination of if else, for each and while loops which I think it's ugly. I am trying to simplify the algorithm so that it's easier to maintain and debug. Thanks in advance.
You can be clever with GroupBy
// Beginning of earliest financial year
var start = new DateTime(2000,7,1);
var range = Enumerable.Range(0,365*2);
// Some random test data
var dates1 = range.Select(i => new DateTime(2001,1,1).AddDays(i) );
var dates2 = range.Select(i => new DateTime(2003,1,1).AddDays(i) );
// Group by distance in years from beginning of earliest financial year
var finYears =
dates1
.Concat(dates2)
.GroupBy(d => d.Subtract(start).Days / 365 );
This gives an IEnumerable<IGrouping<int, DateTime>> with each outer enumerable containing all the dates in the 2 lists in a single financial year.
EDIT: Changed to include clearer requirements.
Given a list that contains contiguous date ranges, the code doesn't have to be hard at all. In fact, you don't even have to write an actual loop:
public const int FYBeginMonth = 7, FYBeginDay = 1;
public static int FiscalYearFromDate(DateTime date)
{
return date.Month > FYBeginMonth ||
date.Month == FYBeginMonth && date.Day >= FYBeginDay ?
date.Year : date.Year - 1;
}
public static IEnumerable<DateRangeWithPeriods>
FiscalYears(IEnumerable<DateRange> continuousDates)
{
int startYear = FiscalYearFromDate(continuousDates.First().Begin),
endYear = FiscalYearFromDate(continuousDates.Last().End);
return from year in Enumerable.Range(startYear, endYear - startYear + 1)
select new DateRangeWithPeriods {
Range = new DateRange { Begin = FiscalYearBegin(year),
End = FiscalYearEnd(year) },
// start with the periods that began the previous FY and end in this FY
Periods = (from range in continuousDates
where FiscalYearFromDate(range.Begin) < year
&& FiscalYearFromDate(range.End) == year
select new DateRange { Begin = FiscalYearBegin(year),
End = range.End })
// add the periods that begin this FY
.Concat(from range in continuousDates
where FiscalYearFromDate(range.Begin) == year
select new DateRange { Begin = range.Begin,
End = Min(range.End, FiscalYearEnd(year)) })
// add the periods that completely span this FY
.Concat(from range in continuousDates
where FiscalYearFromDate(range.Begin) < year
&& FiscalYearFromDate(range.End) > year
select new DateRange { Begin = FiscalYearBegin(year),
End = FiscalYearEnd(year) })
};
}
This assumes some DateRange structures and helper functions, like this:
public struct DateRange
{
public DateTime Begin { get; set; }
public DateTime End { get; set; }
}
public class DateRangeWithPeriods
{
public DateRange Range { get; set; }
public IEnumerable<DateRange> Periods { get; set; }
}
private static DateTime Min(DateTime a, DateTime b)
{
return a < b ? a : b;
}
public static DateTime FiscalYearBegin(int year)
{
return new DateTime(year, FYBeginMonth, FYBeginDay);
}
public static DateTime FiscalYearEnd(int year)
{
return new DateTime(year + 1, FYBeginMonth, FYBeginDay).AddDays(-1);
}
This test code:
static void Main()
{
foreach (var x in FiscalYears(new DateRange[] {
new DateRange { Begin = new DateTime(2001, 1, 1),
End = new DateTime(2001, 8, 14) },
new DateRange { Begin = new DateTime(2001, 8, 15),
End = new DateTime(2002, 7, 10) } }))
{
Console.WriteLine("from {0:yyyy MMM dd} to {1:yyyy MMM dd}",
x.Range.Begin, x.Range.End);
foreach (var p in x.Periods)
Console.WriteLine(
" period: {0:yyyy MMM dd} to {1:yyyy MMM dd}", p.Begin, p.End);
}
}
outputs:
from 2000 Jul 01 to 2001 Jun 30
period: 2001 Jan 01 to 2001 Jun 30
from 2001 Jul 01 to 2002 Jun 30
period: 2001 Jul 01 to 2001 Aug 14
period: 2001 Aug 15 to 2002 Jun 30
from 2002 Jul 01 to 2003 Jun 30
period: 2002 Jul 01 to 2002 Jul 10
for each range in list
// determine end of this fiscal year
cut = new Date(range.start.year, 06, 31)
if cut < range.start
cut += year
end
if (range.end <= cut)
// one fiscal year
result.add range
continue
end
result.add new Range(range.start, cut)
// chop off whole fiscal years
start = cut + day
while (start + year <= range.end)
result.add new Range(start, start + year - day)
start += year
end
result.add new Range(start, range.end)
end
Sorry for mix of ruby and java :)
This is my simplest financial year list generate code
public void financialYearList()
{
List<Dictionary<string, DateTime>> diclist = new List<Dictionary<string, DateTime>>();
//financial year start from july and end june
int year = DateTime.Now.Month >= 7 ? DateTime.Now.Year + 1 : DateTime.Now.Year;
for (int i = 7; i <= 12; i++)
{
Dictionary<string, DateTime> dic = new Dictionary<string, DateTime>();
var first = new DateTime(year-1, i,1);
var last = first.AddMonths(1).AddDays(-1);
dic.Add("first", first);
dic.Add("lst", last);
diclist.Add(dic);
}
for (int i = 1; i <= 6; i++)
{
Dictionary<string, DateTime> dic = new Dictionary<string, DateTime>();
var first = new DateTime(year, i, 1);
var last = first.AddMonths(1).AddDays(-1);
dic.Add("first", first);
dic.Add("lst", last);
diclist.Add(dic);
}
}

Categories

Resources