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);
}
Related
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.
I have a code 2014P07W4 which means:
2014 = year
P07 = 7th month of the year
W4 = 4th week of the month.
I would like to work out the date of the First day of the 4th week in July 2014. In this example I would expect to see a date of 21/7/2014.
July 2014 weeks
Week 1 - 1st to 6th
Week 2 - 7th to 13th
Week 3 - 14th to 20th
Week 4 - 21st to 27th
Week 5 - 28th to 31st
From the code I know the week no = 4 then I want to be able to calculate the date 21/7/2014. I am assuming the first day of the week is a Monday
I am asking how to read that code and get the first day of the week specified
Hope this is clearer it has been a long day
You need to parse the code and extract the year, month, and weekNo an numbers.
Then, you can use this method to get the start day of the week:
int WeekStartDay(int year, int month, int weekNo)
{
DateTime monthStart = new DateTime(year, month, 1);
int monthStart_DayOfWeek = ((int)monthStart.DayOfWeek + 6) % 7;
int weekStart_DayOfMonth = 1;
if (1 < weekNo) {
weekStart_DayOfMonth += 7 - monthStart_DayOfWeek;
}
if (2 < weekNo) {
weekStart_DayOfMonth += 7 * (weekNo - 2);
}
return weekStart_DayOfMonth;
}
Take first day of month (2014/07/01), find next Monday (first day of 2nd week), add 14 days (first day of 4th week).
DateTime date = new DateTime(2014, 7, 1);
int daysToFirstDayOf2ndWeek = date.DayOfWeek == DayOfWeek.Monday
? 7
: ((int)DayOfWeek.Monday - (int)date.DayOfWeek + 7) % 7;
DateTime firstDayOf2ndWeek = date.AddDays(daysToFirstDayOf2ndWeek);
DateTime firstDayOf4thWeek = firstDayOf2ndWeek.AddDays(14);
may be this will works
string code = "2014P07W4";
int yr = int.Parse(code.Substring(0, 4));
int mnth = int.Parse(code.Substring(5, 2));
int week = int.Parse(code.Substring(8));
DateTime dt = new DateTime(yr, mnth, 1);
if (dt.DayOfWeek == DayOfWeek.Monday)
{
DateTime newdate = dt.AddDays((week - 1) * 7);
}
else
{
DateTime newdate = dt.AddDays((8 - (int)dt.DayOfWeek) % 7 + ((week - 2) * 7));
}
I need to return year and week of a given date. Sounds simple. But to be right 2012-01-01 have to return 2011-52, because week 1 in 2012 starts January 2th.
To find the week, I use:
GregorianCalendar calw = new GregorianCalendar(GregorianCalendarTypes.Localized);
return calw.GetWeekOfYear(DateTime.Parse("2012-01-01"), CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday).ToString();
this return 52. (correct)
But how do I get the Year?
edit:
With the help from here: http://codebetter.com/petervanooijen/2005/09/26/iso-weeknumbers-of-a-date-a-c-implementation/
This seems to work:
private int weekYear(DateTime fromDate)
{
GregorianCalendar cal = new GregorianCalendar(GregorianCalendarTypes.Localized);
int week = weekNumber(fromDate);
int month = cal.GetMonth(fromDate);
int year = cal.GetYear(fromDate);
//week starts after 31st december
if (week > 50 && month == 1)
year = year - 1;
//week starts before 1st January
if (week < 5 && month == 12)
year = year + 1;
return year;
}
private int weekNumber(DateTime fromDate)
{
// Get jan 1st of the year
DateTime startOfYear = fromDate.AddDays(-fromDate.Day + 1).AddMonths(-fromDate.Month + 1);
// Get dec 31st of the year
DateTime endOfYear = startOfYear.AddYears(1).AddDays(-1);
// ISO 8601 weeks start with Monday
// The first week of a year includes the first Thursday
// DayOfWeek returns 0 for sunday up to 6 for saterday
int[] iso8601Correction = { 6, 7, 8, 9, 10, 4, 5 };
int nds = fromDate.Subtract(startOfYear).Days + iso8601Correction[(int)startOfYear.DayOfWeek];
int wk = nds / 7;
switch (wk)
{
case 0:
// Return weeknumber of dec 31st of the previous year
return weekNumber(startOfYear.AddDays(-1));
case 53:
// If dec 31st falls before thursday it is week 01 of next year
if (endOfYear.DayOfWeek < DayOfWeek.Thursday)
return 1;
else
return wk;
default: return wk;
}
}
Noda Time handles this for you very easily:
Noda Time v1.x
using System;
using NodaTime;
public class Test
{
static void Main()
{
LocalDate date = new LocalDate(2012, 1, 1);
Console.WriteLine($"WeekYear: {date.WeekYear}"); // 2011
Console.WriteLine($"WeekOfWeekYear: {date.WeekOfWeekYear}"); // 52
}
}
Noda Time v2.x
using System;
using NodaTime;
using NodaTime.Calendars;
public class Test
{
static void Main()
{
LocalDate date = new LocalDate(2012, 1, 1);
IWeekYearRule rule = WeekYearRules.Iso;
Console.WriteLine($"WeekYear: {rule.GetWeekYear(date)}"); // 2011
Console.WriteLine($"WeekOfWeekYear: {rule.GetWeekOfWeekYear(date)}"); // 52
}
}
That's using the ISO calendar system where the week year starts in the first week with at least 4 days in that year. (Like CalendarWeekRule.FirstFourDayWeek.) If you want a different calendar system, specify it in the LocalDate constructor. Week year rules are handled slightly differently between 1.x and 2.x.
EDIT: Note that this gives the right value for both this situation (where the week-year is less than the calendar year) and the situation at the other end of the year, where the week-year can be more than the calendar year. For example, December 31st 2012 is in week 1 of week-year 2013.
That's the beauty of having a library do this for you: its job is to understand this sort of thing. Your code shouldn't have to worry about it. You should just be able to ask for what you want.
You can get the weeknumber according to the CalendarWeekRule in this way:
var d = new DateTime(2012, 01, 01);
System.Globalization.CultureInfo cul = System.Globalization.CultureInfo.CurrentCulture;
var firstDayWeek = cul.Calendar.GetWeekOfYear(
d,
System.Globalization.CalendarWeekRule.FirstDay,
DayOfWeek.Monday);
int weekNum = cul.Calendar.GetWeekOfYear(
d,
System.Globalization.CalendarWeekRule.FirstFourDayWeek,
DayOfWeek.Monday);
int year = weekNum >= 52 && d.Month == 1 ? d.Year - 1 : d.Year;
You probably want to compare CalendarWeekRule.FirstDay with CalendarWeekRule.FirstFourDayWeek. On this way you get the weeknumber and the year (DateTime.Year-1 if they differ).
CultureInfo.Calendar Property
Calendar.GetWeekOfYear Method
CalendarWeekRule Enumeration
That is just an edge case which you will have to add special code for. Get the year from the date string and then if the week = 52 and the month = 1 then subtract one from the year.
I have solving similar problem where the result should be in "YYYYWW" format. I wanted avoid hardcoded dates and using 3rd party libraries.
My test case was date 1.1.2017 which should return week 201652 (Iso YearWeek)
To get week number I have used thread: Get the correct week number of a given date which returns week number without the year.
Finally the correct year I got from Monday(first day of iso week) of required date:
// returns only week number
// from [Get the correct week number of a given date] thread
public static int GetIso8601WeekOfYear(DateTime time)
{
// Seriously cheat. If its Monday, Tuesday or Wednesday, then it'll
// be the same week# as whatever Thursday, Friday or Saturday are,
// and we always get those right
DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
{
time = time.AddDays(3);
}
// Return the week of our adjusted day
var week = CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return week;
}
// returns int YearWeek in format "YYYYWW"
public static int GetIso8601YearWeekOfYear(DateTime time)
{
var delta = (-((time.DayOfWeek - CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek + 7) % 7));
var firstDayofWeek = time.AddDays(delta); // takeMonday
var week = GetIso8601WeekOfYear(time);
var yearWeek = (firstDayofWeek.Year * 100) + week;
return yearWeek;
}
In my approach I'm taking advantage of the fact, that GetWeekOfYear() displays a correct ISO-8601 week number for days with the same year as Thursday of the same week. So I look for Thursday that belongs to the same week as a given date, and then call GetWeekOfYear() on it.
I can't do that trick to get a correct year, as there's no iso8601-compliant method for this, so I make a year adjustment if Thursday belongs to a different year than a given date.
The solution is basically a three-liner:
using System.Globalization;
namespace TESTS
{
class Program
{
static void Main(string[] args)
{
//sample dates with correct week numbers in comments:
string[] dats = new string[] {
"2011-12-31","2012-01-01" //1152
,"2012-12-31","2013-01-01" //1301
,"2013-12-31","2014-01-01" //1401
,"2014-12-31","2015-01-01" //1501
,"2015-12-31", "2016-01-01" //1553
};
foreach (string str in dats)
{
Console.WriteLine("{0} {1}", str, GetCalendarWeek(DateTime.Parse(str)));
}
Console.ReadKey();
}
public static int GetCalendarWeek(DateTime dat)
{
CultureInfo cult = System.Globalization.CultureInfo.CurrentCulture;
// thursday of the same week as dat.
// value__ for Sunday is 0, so I need (true, not division remainder %) mod function to have values 0..6 for monday..sunday
// If you don't like casting Days to int, use some other method of getting that thursday
DateTime thursday = dat.AddDays(mod((int)DayOfWeek.Thursday-1,7) - mod((int)dat.DayOfWeek-1,7));
//week number for thursday:
int wk = cult.Calendar.GetWeekOfYear(thursday, cult.DateTimeFormat.CalendarWeekRule, cult.DateTimeFormat.FirstDayOfWeek);
// year adjustment - if thursday is in different year than dat, there'll be -1 or +1:
int yr = dat.AddYears(thursday.Year-dat.Year).Year;
// return in yyww format:
return 100 * (yr%100) + wk;
}
// true mod - helper function (-1%7=-1, I need -1 mod 7 = 6):
public static int mod(int x, int m)
{
return (x % m + m) % m;
}
}
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
I have a date value varFinishDate that I pull form an SQL database and I want to get the 30th of the month after varFinishDate. Except if it’s going to be in February when I want it to be the 28th. What is the best way to do this in C#?
To put it in context, we have programs running and the reports are due at the end of the month after they finish (on the 30th even if there are 31 days). So if it finished any time in April the report is due on the 30th of May and so on, except where they finish in January then the reports are due on the 28th of February.
How about this?
var nextMonth = varFinishDate.AddMonths(1);
var targetDate = new DateTime(
nextMonth.Year,
nextMonth.Month,
nextMonth.Month == 2 ? 28 : 30);
Use DaysInMonth();
So you would have something like
var nextMonth = varFinishDate.AddMonths(1);
if(nextMonth.DaysInMonth() < 30)
nextMonth = new DateTime(nextMonth.Year, nextMonth.Month, 28);
else
nextMonth = new DateTime(nextMonth.Year, nextMonth.Month, 30);
int day = 30;
if (finishedDate.Month == 1)
day = 28;
DateTime nextMonth = finishedDate.AddMonths(1);
DateTime reportDate = new DateTime(nextMonth.Year, nextMonth.Month, day);
This should allow for leap years to also use day 29:
var dueDate = varFinishDate.AddMonths(1);
if ( DateTime.DaysInMonth(dueDate.Year, dueDate.Month) < 30 ) {
dueDate.AddDays(DateTime.DaysInMonth(dueDate.Year, dueDate.Month) - dueDate.Day);
} else {
dueDate = new DateTime(dueDate.Year,dueDate.Month,30);
}