make one date bigger than other c# - c#

Hello so I have this condition:
if (DateTime.Now.Subtract(dateTimePicker_Doc_BirthDate.Value).Days/(365)<18)
{
this.errorProvider1.SetError(this.dateTimePicker_Doc_BirthDate, "Atleast 18 years old");
valid = false;
}
And I want to make another that contains graduation of this person and set restriction that at the time when he graduat must be atleast 18 years older.
I have tried this: but it does not work
if (DateTime.Now.Subtract(dateTimePicker_Doc_Graduation.Value).Days / (365) < 18 + (18))
{
this.errorProvider1.SetError(this.dateTimePicker_Doc_Graduation, "Atleast 18");
valid = false;
}

The main problem here is leap year. When a person born in 29 Feb 2004 will be 18 year old? There are two possible answers:
https://www.buzzfeed.com/lanesainty/leap-year-birthday-teenager-court-ruling
28 Feb 2022 (New Zealand for driving license; see xdtTransform's comment)
1 Mar 2022 (Australia)
In a simple case, we can just add 18 year to the birthDate and see if 18th birth day is before or after today. For 29 February we may well have to add 1 day as well:
DateTime birthDate = dateTimePicker_Doc_BirthDate.Value.Date;
DateTime today = DateTime.Today;
// 0 for 28 Feb 2022; 1 for 1 Mar 2022
int leapPolicy = 1;
if (birthDate.AddYears(18) <= today || // 18th birthday before today or today
birthDate.Day == 29 &&
birthDate.Day == 2 &&
birthDate.AddYears(18).AddDays(leapPolicy) == today) {
// At least 18 years old
}
Please, note, that year is not 365 but 365.2425 days (Gregorian calendar) that's why you can't put it as ...Days / 365...

Related

C# Time Period in weeks between 2 dates

I have a web application where the user will input 2 dates. A StartDate and an EndDate. Now I want to write it so that when StartDate and EndDate is selected to determine how many weeks there are and then to display the dates of those weeks for example if the user selects 01-11-2018 as the StartDate and 31-12-2018 as the EndDate then I want to display the following and keep in mind the Weeks are just for reference as to how it is going to look:
Week 98 : 01 November 2018 - 03 November 2018
Week 99 : 04 November 2018 - 10 November 2018
Week 100 : 11 November 2018 - 17 November 2018
I already have the amount of weeks by using this previous post.
Now I just want to be able to to display each individual weeks Start and End date in all the weeks. I tried creating a list with the weeks and then using a Foreach to check the weeks added but this is not quite right. I am just searching for the most efficient way of accomplishing this goal.
Links also checked with similar problems are :
Link1
I have made this snippet... not sure if everything is up to spec:
var startDate = new DateTime(2018, 11, 1);
var endDate = new DateTime(2018, 12, 31);
int diff = (7 + (startDate.DayOfWeek - DayOfWeek.Monday)) % 7;
var weekStartDate = startDate.AddDays(-1 * diff).Date;
var i = 1;
var weekEndDate = DateTime.MinValue;
while(weekEndDate < endDate) {
weekEndDate = weekStartDate.AddDays(6);
var shownStartDate = weekStartDate < startDate ? startDate : weekStartDate;
var shownEndDate = weekEndDate > endDate ? endDate : weekEndDate;
Console.WriteLine($"Week {i++}: {shownStartDate:dd MMMM yyyy} - {shownEndDate:dd MMMM yyyy}");
weekStartDate = weekStartDate.AddDays(7);
}
This assumes your weeks are "counting", starting on the week the start date is in, and uses monday as the first day of week and sunday as the last one (the ranges you see are monday - sunday except for the first/last week, which would use the start/end date instead if it doesn't happen to be monday or sunday)
You can run it online here: https://dotnetfiddle.net/jJ4Ydu
If you also need to know which week of the year it is, then it depends if you want the .NET style or the ISO8601 style... the typical one is the latter, and you can use, for example, the method found on this answer, so it'd look something like: https://dotnetfiddle.net/oJscjF
Notice how Dec-31st-2018 (which is monday) is the week 1 of 2019 on ISO8601, but week 53 for .NET

How can I do universal query for date range?

I'm using LINQ for getting list of objects which are in a specific date range. For example, I have current day in DateTime format: 21.05.2016 0:00:00 and I need to get news which were published after 1 day ago (5 day ago, 3 months ago, 1 year ago, 5 years ago) and until this moment. I did it the folowing way:
List<MyObject> data =
DataDownloader.myList.Where(s => s.Date.Year >= fromDate.Year
&& s.Date.Month >= fromDate.Month
&& s.Date.Day >= fromDate.Day
&& s.Date.Year <= toDate.Year
&& s.Date.Month <= toDate.Month
&& s.Date.Day <= toDate.Day).ToList();
toDate is my current date. I find the fromDate by the following:
1 day:
fromDate = toDate;
5 days:
fromDate = toDate.AddDays(-5);
3 months:
fromDate = toDate.AddMonths(-3);
etc.
But I get only 2 news for 3 months. It's 21.04.2016 0:00:00 and 21.05.2016 0:00:00. So you know they differ only numbers of months because my current date is 21.05.2016. What's I do wrong? I should get much more news I know it.
You're comparing each of the elements of a date, which isn't going to give you the right answer.
You're saying for the 'last 3 months' (from 21/02/2016 to 21/05/2016) that the day has to be between 21 and 21, the month between 2 and 5 and the year between 2016 and 2016
You're effectively searching for 21/02/2016, 21/03/2016, 21/04/2016 or 21/05/2016 rather than all dates between.
Just compare the date:
list.Where(x => x.Date >= fromDate && x.Date <= toDate).ToList();

Get the specific dates of moths considering a specific logic

I am doing a code where I am stuck in a case :-
I am having a date : 31 jan 2014, and i want to get dates after every 1 month in a way
that next date should be 28 feb,2014 but because feb does not have 31 so I should get 28.
Than march is having 31 so it should have 31 .
basically a list which have
31 jan 2014
28 feb 2014
31 march 2014
30 april 2014
31 may 2014
Now if that date is : 29 jan 2014 than a list
29 jan 2014
28 feb 2014
29 march 2014
29 april 2014
29 may 2014
and i want to consider leap years to that too.
I was trying to use addmonths(1) function but in a loop when i try to add it
31 jan 2014, 28 feb 2014, 28 march 2014,28 april 2014,28 may 2014.
which was wrong.
Can anyone tell me the correct way to get the thing done.
The approach works:
DateTime start = new DateTime(2014, 1, 31);
for(int i=0; i<12; i++)
Console.WriteLine(start.AddMonths(i));
To get last date of the month you can use,
var thisMonthStart = DateTime.Today.AddDays(1 - DateTime.Today.Day);
var thisMonthEnd = thisMonthStart.AddMonths(1).AddSeconds(-1);
So just give a try with.
AddMonths(1).AddSeconds(-1)
You can get last date of the next month.
Use Calendar class for adding months.
Calendar cal = CultureInfo.InvariantCulture.Calendar;
DateTime initialDT = new DateTime(2014,1,31,cal);
DateTime dt = cal.AddMonths(initialDT,1);
The below should work
static void Test5()
{
DateTime start = new DateTime(2014, 1, 29);
DateTime nextDate = start;
for (int i = 0; i < 5; i++)
{
nextDate = nextDate.AddMonths(1);
if (start.Day == DateTime.DaysInMonth(start.Year, start.Month))
{
// If the start date was the end of the month, then set the generated date to end of the month as well
// e.g. 31/1 -> 28/2 -> 31/3 -> 30/4 -> 31/5 ... and so on
int endDay = DateTime.DaysInMonth(nextDate.Year, nextDate.Month);
nextDate = new DateTime(nextDate.Year, nextDate.Month, endDay);
}
else
{
// Try to set the day to same as start day
if (start.Day <= DateTime.DaysInMonth(nextDate.Year, nextDate.Month))
{
nextDate = new DateTime(nextDate.Year, nextDate.Month, start.Day);
}
}
Console.WriteLine(nextDate.ToString("dd/MM/yyyy"));
}
}

ASP.NET Getting working weeks for every month

I have a form that accept input of 'Month' and 'Year', I am writing here to ask any idea on how will I get all 'working weeks'?
I mean 'Working weeks' as Monday - Friday
So basically I need week1 to week4 or if available including week5.
For example if I input January 2013:
week1 = January 1 to January 4
week2 = January 7 to January 11
week3 = January 14 to January 18
week4 = January 21 to January 25
week5 = January 28 to January 31
How can I achieve that? Thanks for any help! Any suggestions or ideas will be greatly appreciated. Thanks mates! :)
You could use this Linq query:
int month = 1;
int year = 2013;
var cal = System.Globalization.CultureInfo.CurrentCulture.Calendar;
IEnumerable<int> daysInMonth = Enumerable.Range(1, cal.GetDaysInMonth(year, month));
List<Tuple<int, DateTime, DateTime>> listOfWorkWeeks = daysInMonth
.Select(day => new DateTime(year, month, day))
.GroupBy(d => cal.GetWeekOfYear(d, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday))
.Select(g => Tuple.Create(g.Key, g.First(), g.Last(d => d.DayOfWeek != DayOfWeek.Saturday && d.DayOfWeek != DayOfWeek.Sunday)))
.ToList();
// Item1 = week in year, Item2 = first day, Item3 = last working day
int weekNum = 1;
foreach (var weekGroup in listOfWorkWeeks)
{
Console.WriteLine("Week{0} = {1} {2} to {1} {3}"
, weekNum++
, System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(month)
, weekGroup.Item2.Day
, weekGroup.Item3.Day);
}
output for January:
Week1 = January 1 to January 4
Week2 = January 7 to January 11
Week3 = January 14 to January 18
Week4 = January 21 to January 25
Week5 = January 28 to January 31
and for February:
Week1 = February 1 to February 1
Week2 = February 4 to February 8
Week3 = February 11 to February 15
Week4 = February 18 to February 22
Week5 = February 25 to February 28
Find the first Monday of the month and year.
int year = 2013;
int month = 1;
DateTime testDate = new DateTime(year,month,1);
while ( testDate.DayOfWeek != DayOfWeek.Monday )
{
testDate = testDate.AddDays(1);
}
Then iterate over each week until you reach a year that isn't 2013.
// Should have first monday now.
// Loop until the month changes
while ( testDate.Month == month)
{
var monday = testDate;
var friday = testDate.AddDays(4);
// You now have both dates. Do whatever you need to.
// here.
// Increment test date by a week
testDate = testDate.AddDays(7)
}
In pseudo code:
Start from the first day of the month
While (day != Monday) take next date (+1 day)
See this SO post (Jon Skeet answer!) for checking if a day is a Monday.
Add 4 days to find the end of the working week
If it's in the same month, than you have a working week for your answer.
Add 7 days to find the next Monday
If the new Monday is still within the same month: repeat 3. and 4.
EDIT The above finds all complete working weeks.
To find the other weeks as well:
If the first day of the month is already a working day, find the next Friday. -> 1st working week
If the last friday is in the next month, finish the last working week at the last day of the month. -> last working week

Quartz.Net - Every 3 months

I'm trying to call something every 3 months (quarterly) in Quartz.NET (using both stable and latest version 2 which is beta with same results).
I create cron trigger with 0 30 8 3 */3 ? * to be called every 3 months at 8.30am on third of the month it occurs.
So technically since its 2 of September today I would expect it to trigger tomorrow. However it next run time shows as being next month. Why is that so?
Updated: As per answers I got I created following method - could be useful for someone:
public static string CalculateMonthsWithInterval(int startMonth, int interval)
{
var months = new List<string>();
var monthNames = new [] {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
var monthSelector = startMonth % interval;
for (var i = 0; i < 12; i++)
{
if (i % interval == monthSelector)
{
months.Add(monthNames[i]);
}
}
return string.Join(",", months.ToArray());
}
Ps: I didn't use indexes for months because for some reason it wasn't working well with my Quartz (v2 BETA). Also its easier to read in DB level.
Example call - Every 3 months based on startDate:
var cronMonths = CronUtils.CalculateMonthsWithInterval((startDate.Month - 1), 3);
Well I think that's because the scheduler will verify which month can be divided by 3, since all month in Quartz are based 0 (according to: http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/tutorial-lesson-06), the month that will be scheduled will be january, april, july and october.
0 mod 3 = 0 -> JAN
1 mod 3 = 1 -> FEB
...
8 mod 3 = 2 -> SEP
9 mod 3 = 0 -> OCT
The Quartz scheduler will analyse your cron expression and keep only those where their modulus 3 equals to 0.
If you want it to be 1 month before that (march, june, september and october) you will have to set it to:
0 30 8 3 MAR,JUN,SEP,DEC ? *
A good page to create cron expressions: http://www.cronmaker.com/
Cron format:
0 0 12 1 1/3 ? *
Executes every:
1. Saturday, April 1, 2017 12:00 PM
2. Saturday, July 1, 2017 12:00 PM
3. Sunday, October 1, 2017 12:00 PM
4. Monday, January 1, 2018 12:00 PM
5. Sunday, April 1, 2018 12:00 PM

Categories

Resources