Get Date by passing dayofweek, weekofmonth, monthofyear and year using c# - c#

I need a method which can return a date after taking 4 inputs, dayofweek, weekofmonth, monthofyear and year. I have tried the following but it fails when 4th week of month doesn't have all days, so I return 28 to be at safer side. I would like to have a complete solution and better than this if possible. Please ignore my parameters, I know I can improve it by passing a date instead. Here is my code;
public static DateTime GetDateByDayOfWeekOfMonthOfYear(int dayOfWeek, int weekOfMonth, int monthOfYear, int year)
{
var firstDayOfMonth = new DateTime(year, monthOfYear, 1);
var firstDay = (int)firstDayOfMonth.DayOfWeek;
var addor = 0;
if (firstDay == (int)DayOfWeek.Monday)
addor = 0;
if (firstDay == (int)DayOfWeek.Tuesday)
addor = 6;
if (firstDay == (int)DayOfWeek.Wednesday)
addor = 5;
if (firstDay == (int)DayOfWeek.Thursday)
addor = 4;
if (firstDay == (int)DayOfWeek.Friday)
addor = 3;
if (firstDay == (int)DayOfWeek.Saturday)
addor = 2;
if (firstDay == (int)DayOfWeek.Sunday)
addor = 1;
var resultantDate = firstDayOfMonth.AddDays((7 * weekOfMonth + addor) - (7 - dayOfWeek) - 1);
return resultantDate.Month == monthOfYear
? resultantDate
: firstDayOfMonth.AddDays(27);
}

You can do it this way - for the weekday of your choice, and for the first or a later occurrence of this weekday:
// Select year, month, weekday, and occurrence of weekday.
int year = 2015;
int month = 10;
DayOfWeek dayOfWeek = DayOfWeek.Monday;
int occurrence = 1; // Valid values: 1 to 5.
// Constants.
const int daysInWeek = 7;
const int maximumWeek = 5;
const int minimumWeek = 1;
occurrence = occurrence < minimumWeek ? minimumWeek : occurrence;
occurrence = occurrence > maximumWeek ? maximumWeek : occurrence;
DateTime first = new DateTime(year, month, 1);
int primoOffset = (dayOfWeek - first.DayOfWeek + daysInWeek) % daysInWeek;
DateTime dayInMonth = first.AddDays(primoOffset + daysInWeek * --occurrence);
if (dayInMonth.Month != month)
{
// Week 5 belongs to the next month.
// Return value for the last occurrence.
dayInMonth = dayInMonth.AddDays(-daysInWeek);
}
return dayInMonth;

Related

Get the days of a week given day name

public class Date
{
public int mm;
public int dd;
public Date(int get_mm, int get_dd)
{
mm = get_mm;
dd = get_dd;
}
int day = (int)(daysofweek)Enum.Parse(typeof(daysofweek), DateTime.Now.DayOfWeek.ToString());
for (int i = 1; i < 8; i++)
{
int day_fetch = i - day;
Console.WriteLine(Date date = new Date(DateTime.Now.Month, DateTime.Now.Day + day_fetch));
}
I made this but it doesn't seems working well
What can i do to make it work and how can i solve that problem if the date is for example March 30(The first 2 days is on march but the others are on April)
Try this
// 30 March
var dateTime = DateTime.Now.AddDays(3);
var dayOfWeek = dateTime.DayOfWeek;
// Figure out the first day on the calendar
CultureInfo ci = CultureInfo.CurrentCulture;
Calendar calendar = ci.Calendar;
var firstDayOfWeek = ci.DateTimeFormat.FirstDayOfWeek;
// date (in this case Now) is exlcusive
var daysToBeginningOfWeek = dayOfWeek - firstDayOfWeek;
// Days from beginning of the week to date
for (var i = daysToBeginningOfWeek; i >= 0; i--)
{
var dt = dateTime.AddDays(-i);
Date date = new Date(dt.Month, dt.Day);
Console.WriteLine(date);
}
// Days after date to end of the week
var daysToEndOfWeek = 7 - daysToBeginningOfWeek - 1;
for (var i = 1; i <= daysToEndOfWeek; i++)
{
var dt = dateTime.AddDays(i);
Date date = new Date(dt.Month, dt.Day);
Console.WriteLine(date);
}
You will also need to take first day of the week into consideration because not all calendars are from Sunday to Saturday.

How to get DateOfBirth using age in c#?

I have user age, month and day something like 18 year 2 month and 5 days. I need to return user DateOfBirth using these params. How can I find user DateOfBirth from year, month and day?
I've found a solution and it's works for me.
public static DateTime GetDateOfBirth(int year, int month, int day)
{
var today = DateTime.Today;
int currentYear = today.Year;
int currentDay = today.Day;
int currentMonth = today.Month;
if (day >= currentDay)
{
currentMonth--;
currentDay += DateTime.DaysInMonth(currentYear, currentMonth);
}
if (month >= currentMonth)
{
currentMonth += 12;
currentYear--;
}
return new DateTime(currentYear - year, currentMonth - month, currentDay - day);
}
you can always use AddDays/Months/Years with negative number to actually subtract Days/Months/Years from date.
DateTime now = DateTime.Now;
Console.WriteLine("Today's Date:" + now.ToString());
int years = 18;
int months = 2;
int days = 5;
now = now.AddYears((-1) * years);
now = now.AddMonths((-1) * months);
now = now.AddDays((-1) * days);
Console.WriteLine("Date Of Birth:" + now.ToString());
return now;

previous, current and next 3 quarters?

I am trying to get previous, current and next 3 quarters base on current quarter and year.
Example : Current Quarter = 3 & Year = 2014
I want Output,
Q2-2014
Q3-2014
Q4-2014
Q1-2015
Q2-2015
I am trying as under but output is NOT correct and also how to club previous quarter?
static void Main(string[] args)
{
int generateQuater = 5;
int currentQuater = 3;
int currentYear = DateTime.Now.Year;
List<string> lstQuaterYear = new List<string>();
for (int i = generateQuater; i > 0; i--)
{
lstQuaterYear.Add(string.Format("Q{0}-{1}", currentQuater, currentYear));
if (--currentQuater == 0)
{
currentQuater = 4;
currentYear++;
}
}
Console.ReadLine();
}
Change your loop as follows:
for (int i = 0; i < generateQuater; i++)
{
if(currentQuater%5 ==0)
{
currentQuater = 1;
currentYear++;
}
lstQuaterYear.Add(string.Format("Q{0}-{1}", currentQuater%5, currentYear));
currentQuater++;
}
Modulo 5 will return values in the range [0,4]. Quarter 0 can be interpreted as quarter 1 of the next year. Therefore, we handle that case by setting currentQuater to 1 and incrementing currentYear. This will go through the 4 quarters of each year, and on the 5th one, it will move to next year and restart counting from 1.
Demo
Finally this code with help of Tieson.
Question : Any other/linq approach for subjected problem also welcome.
int generateQuater = 4;
int currentQuater = 3;
int currentYear = DateTime.Now.Year;
List<string> lstQuaterYear = new List<string>();
//previous Quater
lstQuaterYear.Add(String.Format("Q{0}-{1}", (currentQuater - 1) + (((1) / 4) * 4), currentYear - ((1) / 4)));
for (int i = 0; i < generateQuater; i++)
{
if (currentQuater % 5 == 0)
{
currentQuater = 1;
currentYear++;
}
//current and next 3 Quater
lstQuaterYear.Add(string.Format("Q{0}-{1}", currentQuater % 5, currentYear));
currentQuater++;
}

Count of quarter between dates

I want to calculate the count of total quarters (of a year) in the given time span.
for example:
start date = 1-june -2009
end date = 18-july-2011
count should be = 10.
one more
start date = 4-Jan-2009
end date = 27-oct -2010
count =8.
I have not been able to get the correct result.
Your example is wrong: there are only 7 quarters between 4-Jan-2009 and 27-oct -2010
You could simply add a reference to the Microsoft.VisualBasic.dll to your project and use DateDiff:
VB:
Public Shared Function getQuartersBetween(ByVal d1 As Date, ByVal d2 As Date) As Int32
Return DateDiff(DateInterval.Quarter, d1, d2)
End Function
C#:
public static int getQuartersBetween(System.DateTime d1, System.DateTime d2)
{
return Microsoft.VisualBasic.DateAndTime.DateDiff(DateInterval.Quarter, d1, d2);
}
or you could write your own implementation:
public class Quarter
{
public static long GetQuarters(DateTime dt1, DateTime dt2)
{
double d1Quarter = GetQuarter(dt1.Month);
double d2Quarter = GetQuarter(dt2.Month);
double d1 = d2Quarter - d1Quarter;
double d2 = (4 * (dt2.Year - dt1.Year));
return Round(d1 + d2);
}
private static int GetQuarter(int nMonth)
{
if (nMonth <= 3)
return 1;
if (nMonth <= 6)
return 2;
if (nMonth <= 9)
return 3;
return 4;
}
private static long Round(double dVal)
{
if (dVal >= 0)
return (long)Math.Floor(dVal);
return (long)Math.Ceiling(dVal);
}
}
or in VB.NET:
Public Class Quarter
Public Shared Function GetQuarters(ByVal dt1 As DateTime, ByVal dt2 As DateTime) As Long
Dim d1Quarter As Double = GetQuarter(dt1.Month)
Dim d2Quarter As Double = GetQuarter(dt2.Month)
Dim d1 As Double = d2Quarter - d1Quarter
Dim d2 As Double = (4 * (dt2.Year - dt1.Year))
Return Round(d1 + d2)
End Function
Private Shared Function GetQuarter(ByVal nMonth As Integer) As Integer
If nMonth <= 3 Then
Return 1
End If
If nMonth <= 6 Then
Return 2
End If
If nMonth <= 9 Then
Return 3
End If
Return 4
End Function
Private Shared Function Round(ByVal dVal As Double) As Long
If dVal >= 0 Then
Return CLng(Math.Floor(dVal))
End If
Return CLng(Math.Ceiling(dVal))
End Function
End Class
Code for you : Try below code
public static void Main()
{
//Application.Run(new XmlTreeDisplay());
int monthdiuff = monthDifference(Convert.ToDateTime("01/04/09"), Convert.ToDateTime("10/27/10"));
Console.WriteLine(monthdiuff);
int totalQuater = (monthdiuff / 3) + (monthdiuff%3);
Console.WriteLine(totalQuater);
Console.ReadLine();
}
private static int monthDifference(DateTime startDate, DateTime endDate)
{
int monthsApart = 12 * (startDate.Year - endDate.Year) + startDate.Month - endDate.Month;
return Math.Abs(monthsApart);
}
Without some code to look over I can't help you find your exact problem.
If it were me I would probably find the difference between the dates in days, then divide by number of days in a quarter (91 or so). I'm sure that C# has some kind of date parsing module that can read in the dates as a string, giving you two objects that you could then subtract to find the difference in days.
This is one crude form of calculating the quarters based on your assumptions, you can choose to modify as it is it works good enough
DateTime dt1 = new DateTime(2009, 1, 1);// new DateTime(2009, 6, 1);
DateTime dt2 = new DateTime(2010, 10, 27);// new DateTime(2011, 7, 18);
if (dt1.Month < 4)
dt1 = new DateTime(dt1.Year,1,1);
else if (dt1.Month < 7)
dt1 = new DateTime(dt1.Year,4,1);
else if (dt1.Month < 10)
dt1 = new DateTime(dt1.Year,7,1);
else
dt1 = new DateTime(dt1.Year,10,1);
if (dt2.Month < 4)
dt2 = new DateTime(dt2.Year, 3, DateTime.DaysInMonth(dt2.Year, 3));
else if (dt2.Month < 7)
dt2 = new DateTime(dt2.Year, 6, DateTime.DaysInMonth(dt2.Year, 6));
else if (dt2.Month < 10)
dt2 = new DateTime(dt2.Year, 9, DateTime.DaysInMonth(dt2.Year, 9));
else
dt2 = new DateTime(dt2.Year, 12, DateTime.DaysInMonth(dt2.Year, 12));
TimeSpan ts = dt2 - dt1;
int quarters = (int) ts.TotalDays/90;
Console.WriteLine(quarters);
I am baselining the dates to the start and end of the quarters as you want and then assuming for 90 day quarter transforming the diff as int. Works for your mentioned examples,see if it suits you well enough
If the definition of a quarter is a 90-day difference, it's easy of course:
internal static int GetNumberOfQuarters(DateTime p_DtStart, DateTime p_DtEnd)
{
TimeSpan span = p_DtEnd.Subtract(p_DtStart);
return (int)span.TotalDays % 90;
}
But that's not what you're looking for. What about this (not tested but you'll get the idea)
internal static class DateTimeTools
{
internal static int GetNumberOfQuartersBetweenDates(DateTime startDate, DateTime endDate)
{
int iYearStart, iYearEnd, iMonthStart, iMonthEnd, iDayStart, iDayEnd;
iYearStart = startDate.Year;
iYearEnd = endDate.Year;
iMonthStart = startDate.Month;
iMonthEnd = endDate.Month;
iDayStart = startDate.Day;
iDayEnd = endDate.Day;
int iYearDiff, iQuarterDiff, iDayDiff;
iYearDiff = iYearEnd - iYearStart;
iQuarterDiff = iMonthEnd % 3 - iMonthStart % 3;
iDayDiff = iDayEnd - iDayStart;
int iNumOfQuarters = 0;
// at least a year difference?
if ((iYearDiff > 0 && iQuarterDiff > 0) || iYearDiff > 0 && iQuarterDiff == 0 && iDayDiff >= 0)
{
iNumOfQuarters = iYearDiff * 4 + iQuarterDiff;
}
// at least a quarter difference?
// within different years
if ((iYearDiff > 0 && iQuarterDiff <= 0)) // eg, dec 2010 - feb 2011 iYearDiff 1 iQuarterDiff -3
{
if ((iQuarterDiff == -3 && iDayDiff >= 0) || iQuarterDiff > -3)
{
iNumOfQuarters = iQuarterDiff + 4;
}
}
// within the same year
if (iYearDiff == 0 && iQuarterDiff > 0)
{
if ((iQuarterDiff == 1 && iDayDiff >= 0) || iQuarterDiff > 1)
{
iNumOfQuarters = iQuarterDiff;
}
}
return iNumOfQuarters;
}
}
Regards,
Nico
public static string GetQuarter(this DateTime date)
{
var quarterList = new List<string>();
if (date.Month >= 1 && date.Month <= 3)
return "Q1";
else if (date.Month >= 4 && date.Month <= 6)
return "Q1,Q2";
else if (date.Month >= 7 && date.Month <= 9)
return "Q1,Q2,Q3";
else
return "Q1,Q2,Q3,Q4";
}
This too can be used as an extension method if you are expecting to get a list of Quarters, You can later on use GetQuarter().Split(new[] { ',' }).Count() to get the count.
Easy formula to get quarters difference:
{
int firstQuarter = getQuarter(first);
int secondQuarter = getQuarter(second);
return 1 + Math.Abs(firstQuarter - secondQuarter);
}
private static int getQuarter(DateTime date)
{
return (date.Year * 4) + ((date.Month - 1) / 3);
}

Parsing an RFC822-Datetime in .NETMF 4.0

I have an application written in .NETMF that requires that I be able to parse an RFC822-Datetime.
Normally, this would be easy, but NETMF does not have a DateTime.parse() method, nor does it have some sort of a pattern matching implementation, so I'm pretty much stuck.
Any ideas?
EDIT: "Intelligent" solutions are probably needed. Part of the reason this is difficult is that the datetime in question has a tendency to have extra spaces in it (but only sometimes). A simple substring solution might work one day, but fail the next when the datetime has an extra space somewhere between the parts. I do not have control over the datetime, it is from the NOAA.
Good ol' string manipulation:
Sun, 06 Jun 2010 20:07:44 +0000
1 2 3
0123456789012345678901234567890
string x = Sanitize(" Sun, 06 \t Jun 2010 \r\n 20:07:44 +0000 ");
int day = int.Parse(x.Substring(5, 2));
int month = Array.IndexOf(months, x.Substring(8, 3)) + 1;
int year = int.Parse(x.Substring(12, 4));
int hour = int.Parse(x.Substring(17, 2));
int minute = int.Parse(x.Substring(20, 2));
int second = int.Parse(x.Substring(23, 2));
int offsetSgn = (x[26] == "-") ? -1 : 1;
int offsetHour = int.Parse(x.Substring(27, 2));
int offsetMinute = int.Parse(x.Substring(29, 2));
DateTime result = new DateTime(year, month, day, hour, minute, second, 0);
TimeSpan offset = new TimeSpan(offsetHour, offsetMinute, 0);
// TODO: add offset...
with
string[] months = new string[12];
months[0] = "Jan";
months[1] = "Feb";
months[2] = "Mar";
months[3] = "Apr";
months[4] = "May";
months[5] = "Jun";
months[6] = "Jul";
months[7] = "Aug";
months[8] = "Sep";
months[9] = "Oct";
months[10] = "Nov";
months[11] = "Dec";
and
string Sanitize(string s)
{
if (s == null)
{
return null;
}
char[] buffer = new char[s.Length];
int pos = 0;
bool inSpace = true;
for (int i = 0; i < s.Length; i++)
{
if (s[i] == ' ' || s[i] == '\t' || s[i] == '\r' || s[i] == '\n')
{
if (!inSpace)
{
buffer[pos] = ' ';
pos++;
inSpace = true;
}
}
else
{
buffer[pos] = s[i];
pos++;
inSpace = false;
}
}
return new string(buffer, 0, pos);
}

Categories

Resources