I want to find the next leap year from today's date.
For ex.,
Date NextLeapDate
----- ------------
2016-01-01 2016-02-29
2016-05-24 2020-02-29
2017-02-03 2020-02-29
This is what I have so far to get the next leap year but it's getting me wrong value,
public int GetNextLeapYear(int year)
{
bool isLeapYear = false;
while (true)
{
if (DateTime.IsLeapYear(year))
{
isLeapYear = true;
}
else
{
year = year + 1;
GetNextLeapYear(year);
}
break;
}
return year;
}
Something like this:
DateTime GetNextLeapDate (DateTime baseDate)
{
int year = baseDate.Year;
// start in the next year if we’re already in March
if (baseDate.Month > 2)
year++;
// find next leap year
while (!DateTime.IsLeapYear(year))
year++;
// get last of February
return new DateTime(year, 2, 29);
}
Note that we need to skip checking the current year if (and only if) the base date is already ahead of March (i.e. a possible leap day is already over). That way, we don’t get a result of February 29th, 2016 for e.g. today (time of this post).
Used like this, it returns the desired dates:
Console.WriteLine(GetNextLeapDate(new DateTime(2016, 01, 01))); // 2016-02-29
Console.WriteLine(GetNextLeapDate(new DateTime(2016, 05, 24))); // 2020-02-29
Console.WriteLine(GetNextLeapDate(new DateTime(2017, 02, 03))); // 2020-02-29
You don't need recursion. Try this:
public int GetNextLeapYear(int year)
{
while (true)
{
if (DateTime.IsLeapYear(year))
{
return year;
}
year = year + 1;
}
}
Your current code is only a part of the program? The below code is copied from the question and changed with my suggestion edit (as well as other simplifications) to make it work correctly.
public int GetNextLeapYear(int year)
{
if (DateTime.IsLeapYear(year))
{
return year;
}
else
{
year = year + 1;
return GetNextLeapYear(year);
}
}
To use recursion to find the next leap year, you can change your method like so.
public int GetNextLeapYear(int year)
{
if (!DateTime.IsLeapYear(year))
{
return GetNextLeapYear(year + 1);
}
return year;
}
Using recursion, you don't need the While loop, you just need to check to see if you need to continue or return the value. This also allows you to get rid of variables that are not needed. #poke answer is more complete counting for the actual month that you are in and such. I only answered this way to keep with using recursion like you had done.
Related
I was looking for a way to fetch the same day of the current week as a year ago. For example, today is:
August 10th 2022 - Wednesday.
Assume this is the check-in date, the check-out date I expect to get is:
August 11, 2021 - Wednesday.
Because it's the same day (Wednesday) as last year. But I need to take leap years into account, so I need to see if the current year is a leap year and if it is, if it has passed the 29th of February, the same with the date last year.
How to do this using .net core ? I thought of something like:
private DateTime GetDayOneYearBefore()
{
if(DateTime.IsLeapYear(DateTime.Today.Year) && DateTime.Today.Month > 2){
return DateTime.Today.AddDays(-365);
}
else if(DateTime.IsLeapYear(DateTime.Today.Year) && DateTime.Today.Month <= 2){
return DateTime.Today.AddDays(-364);
}
}
Since you mention the "same week" I suppose you want to get the same day of the week in the same week number?
If so, you can do the following:
// In the System.DayOfWeek enum Sunday = 0, while Monday = 1
// This converts DateTime.DayOfWeek to a range where Monday = 0 and Sunday = 6
static int DayOfWeek(DateTime dt)
{
const int weekStart = (int)System.DayOfWeek.Monday;
const int daysInAWeek = 7;
return (daysInAWeek - (weekStart - (int)dt.DayOfWeek)) % daysInAWeek;
}
var calendar = CultureInfo.CurrentCulture.Calendar;
var weekNum = calendar.GetWeekOfYear(DateTime.Today, CalendarWeekRule.FirstFourDayWeek, System.DayOfWeek.Monday);
var todayLastYear = DateTime.Today.AddYears(-1);
var lastYearWeekNum = calendar.GetWeekOfYear(todayLastYear, CalendarWeekRule.FirstFourDayWeek, System.DayOfWeek.Monday);
var sameWeekLastYear = todayLastYear.AddDays(7 * (weekNum - lastYearWeekNum));
var sameDaySameWeekLastYear = sameWeekLastYear.AddDays(DayOfWeek(DateTime.Today) - DayOfWeek(sameWeekLastYear));
As you might notice there's a little convertion method, since I normally work with Monday being the first day of the week. If you prefer a different day to be the first day of the week, simply replace System.DayOfWeek.Monday with which ever day you'd like.
See this fiddle for a test run.
I have something odd requirement. I have Current Date and List of Week Days. And I want next all possible date till the target date.
For i.e. Today, its 22-04-2014 And Tuesday. Target date is 15-05-2014I have 2 week days, Monday and Thursday. So code should find near by Week Day, which will be Thursday here. So It should return date of Thursday which is 24-04-2014. Now, next turn is of Monday which comes from List. So now, It should return date of Monday which is 28-04-2014.
It should keep repeating till the target date.
So, final result will be
24-04-2014,
28-04-2014,
1-05-2014,
5-05-2014,
8-05-2014,
12-05-2014
Please help me to get this type of result. Here, Monday and Thursday is not fixed. It can be any Day and any number of Day.
Update : Link to the working example - Example
You can try this code, i have tested it and working correctly
private List<DateTime> ProcessDate(DateTime dtStartDate, DateTime targetDate)
{
DateTime dtLoop = dtStartDate;
//dtRequiredDates to hold required dates
List<DateTime> dtRequiredDates = new List<DateTime>();
for (int i = dtStartDate.DayOfYear; i < targetDate.DayOfYear; i++)
{
if (dtLoop.DayOfWeek == DayOfWeek.Monday || dtLoop.DayOfWeek == DayOfWeek.Thursday)
{
dtRequiredDates.Add(dtLoop);
}
dtLoop = dtLoop.AddDays(1);
}
return dtRequiredDates;
}
You may have to enhance this codes so that it doesn't throw any exception based on the requirement.
UPDATE 2:
You can have another method which will accept the days of week as follows
private List<DateTime> ProcessDate(DateTime dtStartDate, DateTime targetDate, List<DayOfWeek> daysOfWeek)
{
DateTime dtLoop = dtStartDate;
List<DateTime> dtRequiredDates = new List<DateTime>();
for (int i = dtStartDate.DayOfYear; i < targetDate.DayOfYear; i++)
{
foreach (DayOfWeek day in daysOfWeek)
{
if (dtLoop.DayOfWeek == day)
{
dtRequiredDates.Add(dtLoop);
}
}
dtLoop = dtLoop.AddDays(1);
}
return dtRequiredDates;
}
Here is the Example
Hence you can pass any number of week days as you wish.
Hope this helps
You could try something like this:
List<DayOfWeek> listOfDays = new List<DayOfWeek>{DayOfWeek.Monday, DayOfWeek.Thursday};
var end = new DateTime(2014,05,15);
var day = DateTime.Now.Date;
while (day < end)
{
day.AddDays(1); // adds +1 days to "day"
if (listOfDays.Contains(day.DayOfWeek)) Console.WriteLine(day.Date.ToString());
}
(I can't test the code right now, so maybe you need to modify a little ;-)
I am trying to list the next 10 weeks
The result should be like this:
Week Year
----------------
45: 2012
46: 2012
47: 2012
48: 2012
49: 2012
50: 2012
51: 2012
52: 2012
1: 2013
2: 2013
some years there is a week 53, and this year the 31st of December is on a Monday, is this week 1 or week 53??
Anyways, I want to skip week 53, whenever it occours. This means that 1 or 2 days will not be a part of any week on the list, but this doesn't matter.
some years there is a week 53, and this year the 31st of December is on a Monday, is this week 1 or week 53??
Assuming you mean "week of week-year", that would be week 1 of week-year 2013.
In the ISO calendar, the first week of a week-year is the first Monday-Sunday week which has 4 days or more in it.
It's not clear why you'd want to skip week 53 - it doesn't just skip 1 or 2 days, it skips a whole week.
Of course, this really is assuming you mean the ISO definition of "week of year". If you don't, it's a different matter. You need to clarify your requirements before you do anything else.
To obtain the week-of-week-year from .NET, you can use Calendar.GetWeekOfYear - for the ISO definition you'd use CalendarWeekRule.FirstFourDayWeek and DayOfWeek.Monday. I don't know whether there's anything to get the week-year itself though.
As a blatant plug, in my Noda Time there's support for both WeekYear and WeekOfWeekYear on dates, and you can construct a date for a given week-year/week-of-week-year/day-of-week combination.
i just wrote a small console app that does just that:
static void Main(string[] args)
{
System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
DateTime dt = DateTime.Now; //Use current date as starting point
for (int i = 0; i < 10; i++)
{
int weekNo = ci.Calendar.GetWeekOfYear(
dt,
ci.DateTimeFormat.CalendarWeekRule,
ci.DateTimeFormat.FirstDayOfWeek
);
int year = ci.Calendar.GetYear(dt);
if (weekNo == 53) //if week number==53, then go to next week
{
dt = dt.AddDays(7);
weekNo = ci.Calendar.GetWeekOfYear(
dt,
ci.DateTimeFormat.CalendarWeekRule,
ci.DateTimeFormat.FirstDayOfWeek
);
year = ci.Calendar.GetYear(dt);
}
dt = dt.AddDays(7);
Console.WriteLine(weekNo + "-" + year);
}
}
output today:
46-2012
47-2012
48-2012
49-2012
50-2012
51-2012
52-2012
1-2013
2-2013
3-2013
from msdn http://msdn.microsoft.com/en-us/library/system.globalization.calendar.getweekofyear.aspx
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
DateTime date1 = new DateTime(2011, 1, 1);
Calendar cal = dfi.Calendar;
Console.WriteLine("{0:d}: Week {1} ({2})", date1,
cal.GetWeekOfYear(date1, dfi.CalendarWeekRule,
dfi.FirstDayOfWeek),
cal.ToString().Substring(cal.ToString().LastIndexOf(".") + 1));
}
}
// The example displays the following output: // 1/1/2011: Week 1 (GregorianCalendar)
The following will work based off of the number of weeks since the start of the year.
if you want this to be based off of full weeks then you'll need to determine an offset of 0 or 1 at the start based on the day of the first week of the year.
public class Week
{
public Week(int weekOfYear, int year)
{
WeekOfYear = weekOfYear;
Year = year;
}
public int WeekOfYear { get; private set; }
public int Year { get; private set; }
}
public IEnumerable<Week> Next10Weeks(DateTime startDate)
{
DateTime tempDate = startDate;
for (int i = 0; i < 10; i++)
{
//add one to first parameter if you want the 1-indexed week instead of 0 indexed
yield return new Week(tempDate.DayOfYear % 7, tempDate.Year);
tempDate.AddDays(7);
}
}
using c# visual studio 2008.
Can anyone help with an algorithm to do this please
if i have a range of days selected for this week (eg monday to friday) i can find the dates for these using the datetime functions available.
What i want to do is compared to stored data for the same DAY range 1 year ago.
So basicly i need to go back 1 year and find the dates for the nearest Mon to fri DAY range from 1 year previous. I guess i also need to take into acount leap years.
Can anyone help with a suitable algorithm on how to achieve this.
Of course the DAY for todays date last year is not going to be the same day.
thanks in advance
Here's some code which might do what you want - but the test cases show that there are corner cases to consider:
using System;
public class Test
{
static void Main()
{
Console.WriteLine(SameDayLastYear(DateTime.Today));
Console.WriteLine(SameDayLastYear(new DateTime(2010, 12, 31)));
}
static DateTime SameDayLastYear(DateTime original)
{
DateTime sameDate = original.AddYears(-1);
int daysDiff = original.DayOfWeek - sameDate.DayOfWeek;
return sameDate.AddDays(daysDiff);
}
}
What would you want the result for the second call to be? This code returns January 1st 2010, because that's the closest date to "a year ago on the same day".
I strongly suggest that whatever you go with, you have unit tests checking leap years, start and end of year etc.
Let's say you select Wednesday 10-02-2010 - Friday 12-02-2010 this year.
Last year that would have been Tuesday 10-02-2009 - Thursday 12-02-2009.
So you can do the following: Go back a year by simply performing DateTime.AddYears(-1). Make sure you correct for leap years here.
Then you use .AddDays(1) until you end up on a Wednesday - Friday timeframe.
That way you only have to take leap years into account at one point and this should produce the result you need.
I just subtracted one year then ran backwards until I found a Monday. LastYear will end up being the first Monday before this date last year
DateTime LastYear = DateTime.Now.AddYears(-1)
DayOfWeek Check = LastYear.DayOfWeek;
while (Check != DayOfWeek.Monday)
{
LastYear = LastYear.addDays(-1);
Check = LastYear.DayOfWeek;
}
Console.WriteLine("{0}",LastYear);
DateTime now = DateTime.Now;
DateTime lastyear = now.AddYears(-1);
string dayOfWeek = lastyear.DayOfWeek.ToString();
if (dayOfWeek.Equals("Saturday")) { dayOfWeek = "Friday"; }
else if (dayOfWeek.Equals("Sunday")) { dayOfWeek = "Monday"; }
Console.WriteLine(dayOfWeek);
Console.ReadKey();
Get a datetime object for last year, then use the DayOfWeek property.
This was pretty fun.
// today's info
DateTime today = DateTime.Now;
DayOfWeek today_name = today.DayOfWeek;
// this day one year ago
DateTime year_ago = today - new TimeSpan( ((today.Year - 1) % 4) ? 365 : 366, 0, 0, 0);
// find the closest day to today's info's name
DayOfWeek today_name_a_year_ago = year_ago.DayOfWeek;
DateTime current_range_a_year_ago = year_ago - new TimeSpan( year_ago.DayOfWeek - today_name, 0, 0, 0);
Console.WriteLine( "Today is {0}, {1}", today_name, today);
Console.WriteLine( "One year from today was {0}, {1}", today_name_a_year_ago, year_ago);
Console.WriteLine( "New date range is {0}", current_range_a_year_ago);
I would highly recommend using the unit testing features built into VS2008 to make sure you account for corner cases.
How can i learn next wednesday, monday in a week? Forexample Today 06.02.2009 next Monday 09.02.2009 or wednesday 11.02.2009 there is any algorithm?
i need :
which day monday in comingweek?
findDay("Monday")
it must return 09.02.2009
=====================================================
findDay("Tuesday")
it must return 10.02.2009
public static DateTime GetNextDayDate(DayOfWeek day) {
DateTime now = DateTime.Now;
int dayDiff = (int)(now.DayOfWeek - day);
if (dayDiff <= 0) dayDiff += 7;
return now.AddDays(dayDiff);
}
DateTime now = DateTime.Now;
DateTime nextMonday = now.AddDays((int)now.DayOfWeek - (int)DayOfWeek.Monday);
Hum it seems that I answered too quickly. Actually there are more checking to do. Have a look at nobugz or peterchen answers.
I found a simpler solution:
DayOfWeek is an enum, as: Monday=1, Tuesday=2, etc.
So, to get next Monday (from today) you should use:
DateTime.Today.AddDays(8-(int)DateTime.Today.DayOfWeek)
where "8" is next week's Monday(according to the enum-> 1+7).
Replace the 8 for a 10 (i.e. Wednesday, 3+7) and you'll get next week's Wednesday, and so on...
Like Tyalis, but some extra checking is required:
int daysUntilMonday = ((int)DayOfWeek.Monday - (int)today.DayOfWeek;
if (daysUntilMonday <= 0)
daysUntilMonday += 7;
Monday = DateTime.Now.AddDays(daysUntilMonday);
Just iterate a bit:
DateTime baseDate = ...;
DayOfWeek requiredDayOfWeek = ...;
while(baseDate.DayOfWeek != requiredDayOfWeek)
baseDate = baseDate.AddDays(1);
You can also write an extension method if those are available:
static Next(this DateTime date, DayOfWeek requiredDayOfWeek) { ... }
and you'll get pretty syntax: today.Next(DayOfWeek.Saturday).