Do not include weekends in date time - c#

I just want to know on how to compute DateTime without including weekends (currently making a library system). The library is not open during weekends that is why i need to calculate the date that will not include weekends.
Ex.
03/13/15 = friday and im borrowing it for 5 days. So, the return date should be in 03/20/15= friday( because i didnt include the weekends)
Can you please tell me or give me some ideas? Thanks!
EDIT: ( The program suddenly freezes when i type a number)
int days = 0;
DateTime deyt = DateTime.Now;
rd.Text = deyt.ToString("MM/dd/yy");
DateTime dt = deyt.AddDays(int.Parse(textBox3.Text));
DateTime span = deyt;
while (span < dt.AddDays(1))
{
if (span.DayOfWeek != DayOfWeek.Saturday && span.DayOfWeek != DayOfWeek.Sunday)
{
days++;
span = span.AddDays(1);
bd.Text = days.ToString("MM/dd/yy");
}
}

If you have a list of DateTimes you can filter out the weekend dates:
public static List<DateTime> GetDatesWithoutWeekends(List<DateTime> dates)
{
return
dates.Where(date => (date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday))
.ToList();
}

DateTime date = DateTime.Now // Set your Date
if (date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday)
{
//TODO
}

There are far more efficient ways of doing this for large numbers of days, but if your code is only ever going to deal with small values, you can just use:
static DateTime AddDaysExcludingWeekends(DateTime start, int days)
{
// Do you need this?
if (days < 0)
{
throw new ArgumentException("Not implemented yet...");
}
DateTime current = start;
for (int i = 0; i < days; days++)
{
current = current.AddDays(1);
if (current.DayOfWeek == DayOfWeek.Sunday ||
current.DayOfWeek == DayOfWeek.Saturday)
{
// Effectively force "go round again" behaviour.
i--;
}
}
return current;
}
Or an alternative approach:
static DateTime AddDaysExcludingWeekends(DateTime start, int days)
{
// Do you need this?
if (days < 0)
{
throw new ArgumentException("Not implemented yet...");
}
DateTime current = start;
for (int i = 0; i < days; days++)
{
// Loop at least once, and keep going until we're on
// a weekday.
do
{
current = current.AddDays(1);
}
while (current.DayOfWeek == DayOfWeek.Sunday ||
current.DayOfWeek == DayOfWeek.Saturday);
}
return current;
}
Note that if you pass in days=0, that will return the original date even if it is on a weekend. It's not clear whether or not you want that behaviour, or whether it should skip to the Monday.

This is your code... Try..
int days = 0;
DateTime deyt = DateTime.Now;
DateTime dt = deyt.AddDays(int.Parse(textBox3.Text));
DateTime span = deyt;
while (span <= dt)
{
if (span.DayOfWeek != DayOfWeek.Saturday && span.DayOfWeek != DayOfWeek.Sunday)
{
days++;
bd.Text = days.ToString();
Console.WriteLine(span.ToString("MM/dd/yy"));
}
span = span.AddDays(1);
}

Related

C# Converting values passed as arguments to variables

I am having trouble understanding the relationship between variables and arguments passed to a method. The program below is supposed to take three integers from the main method (M, D, Y) and use various methods to validate if it is a valid date. This includes ensuring the year is between 1900 and 2100, as well as making sure the month is 1-12, and the day is within that month's range of days (including Feb 29th on leap years). If the date from the main method is not valid, the program should say so and print the default date of 1/1/1900. The code below always prints the default no matter what arguments are provided. I believe that this is because there is an issue with how I am using either the variables M, D, Y or the variables Month, Day, Year. This program is for an assignment in which I have to use all methods and constructors in the code below. I am unsure how to have the arguments M, D, Y get turned into the variables Month, Day, and Year, so they can be printed by the ShowDate method which was provided for me.
class Date
{
private int Month;
private int Day;
private int Year;
// Sets date to 1/1/1900
public Date()
{
Month = 1;
Day = 1;
Year = 1900;
}
public Date(int M, int D, int Y)
{
SetDate(M, D, Y);
}
public Boolean SetDate(int M, int D, int Y)
{
if (ValidateDate(M, D, Y))
{
Month = M;
Day = D;
Year = Y;
return true;
}
else
{
Console.WriteLine("Invalide date");
SetDefaultDate();
return false;
}
}
private void SetDefaultDate()
{
Month = 1;
Day = 1;
Year = 1900;
}
// Determines if date is valid.
public Boolean ValidateDate(int M, int D, int Y)
{
ValidateMonth();
ValidateDay();
ValidateYear();
if (ValidateMonth() && ValidateDay() && ValidateYear())
{
ShowDate();
return true;
}
else
{
return false;
}
}
// Determines if month is valid.
public Boolean ValidateMonth()
{
if (Month >= 1 && Month <= 12)
{
return true;
}
else
{
return false;
}
}
// Determines if year is valid.
public Boolean ValidateYear()
{
if(Year >= 1900 && Year <= 2100)
{
return true;
}
else
{
return false;
}
}
// Determines if day is valid
public Boolean ValidateDay()
{
IsLeapYear();
if(Month == 1 || Month == 3 || Month == 5 || Month == 7 || Month == 8 || Month == 10 || Month == 12)
{
if (Day >= 1 && Day <= 31)
{
return true;
}
else
{
return false;
}
}
else if (Month == 4 || Month == 6 || Month == 9 || Month == 11)
{
if (Day >= 1 && Day <= 30)
{
return true;
}
else
{
return false;
}
}
else if (Month == 2 && IsLeapYear())
{
if (Day >= 1 && Day <= 29)
{
return true;
}
else
{
return false;
}
}
else if (Month == 2 && !IsLeapYear())
{
if (Day >= 1 && Day <= 28)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
// Determine if year is a leap year
public Boolean IsLeapYear()
{
if ((Year % 4 == 0 && Year % 100 != 0) || (Year % 400 == 0))
{
return true;
}
else
{
return false;
}
}
// Print date to screen in format M/D/Y
public void DisplayDate()
{
Console.WriteLine(ShowDate());
}
public String ShowDate()
{
StringBuilder myStringBuilder = new StringBuilder();
myStringBuilder.AppendFormat("{0} / {1} / {2}", Month, Day, Year);
Console.WriteLine("{0}", myStringBuilder);
return (myStringBuilder.ToString());
}
static void Main(string[] args)
{
Date NewDate = new Date();
NewDate.SetDate(11,11,2011);
Console.ReadLine();
}
}
You never assign M, D or Y to your Month, Day and Year fields, so you are checking against your default values, which will all be zero by default. You could assign M, D and Y to their corresponding intended variables, but then you wouldn't be validating the input, just validating your fields. Instead you could have your methods accept parameters and check what you pass to it:
public Boolean ValidateMonth(int month)
{
if (month >= 1 && month <= 12)
{
return true;
}
else
{
return false;
}
}
And then when you call it
ValidateMonth(M);
And then you can do the same thing for the other two methods.
Also in your ValidateDate() method you have three useless calls to ValidateMonth(), ValidateDay() and ValidateYear(). You call each of these methods twice. (Once in the beginning, and then again in the if statement.) You can remove these:
public Boolean ValidateDate(int M, int D, int Y)
{
//Remove these:
//ValidateMonth();
//ValidateDay();
//ValidateYear();
if (ValidateMonth() && ValidateDay() && ValidateYear())
{
ShowDate();
return true;
}
else
{
return false;
}
}
Your constructor should initialize the class with the values given. Currently your default constructor initializes M, D, and Y but the constructor that takes arguments does not.
You can address this by changing the constructors to be more like this:
public Date() : this(1,1,1900)
{
}
public Date(int M, int D, int Y)
{
Month = M;
Day = D;
Year = Y;
}
Once the class is initialized, it's just a question of exposing a property or method to validate the values that are already held in the class. You shouldn't need to pass the month, day, and year into a method again, since they're already set. So the validate method might look like this:
public bool IsValid
{
get
{
return ValidateDay() && ValidateMonth() && ValidateYear();
}
}
And in your main program:
Date newDate = new Date(11,11,2011);
if (newDate.IsValid)
{
Console.WriteLine("Date is valid.");
}
else
{
Console.WriteLine("Date is not valid.");
}

How to parse by one line?

I am looking for a solution about how to get all of my int Parses within one line. At the moment when I start my program I have to enter day, month and year. It is all done line by line. I want a solution or method where this does all of my parsing within one line and within a format of "dd/MM/yyyy".
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace date
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("please enter date as dd/MM/yyyy");
int day;
int month;
int year;
day = int.Parse(Console.ReadLine());
month = int.Parse(Console.ReadLine());
year = int.Parse(Console.ReadLine());
Date i = new Date(day, month, year);
Console.WriteLine("{0}/{1}/{2}", i.day, i.month, i.year);
Console.ReadLine();
}
class Date
{
public int month; // 1-12
public int day; // 1-31 depending on month
int value = 1;
public int year
{
get;
private set;
}
public Date(int day, int month, int year)
{
this.day = day;
this.month = month;
this.year = year;
}
public int GetYear()
{
return year;
}
public void SetYear()
{
if (value > 1900 && value <= 2020)
year = value;
else
throw new ArgumentOutOfRangeException("year", value, "out of bounds");
}
private int Month
{
get { return month; }
set
{
if (value > 0 && value <= 12)
month = value;
else
throw new ArgumentOutOfRangeException("Month", value, "Month must be 1-12");
}
}
public int GetDay()
{
return day;
}
public void SetDay()
{
int[] days = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (value > 0 && value <= days[month])
day = value;
else if (month == 2 && value == 29 &&
year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
day = value;
else
throw new ArgumentOutOfRangeException("days", value, "day is out of range");
}
}
}
}
You can use DateTime.Parse/TryParse or DateTime.ParseExact/TryParseExact:
string line = Console.ReadLine();
DateTime dt;
bool validDate = DateTime.TryParseExact(line,"dd/MM/yyyy", DateTimeFormatInfo.InvariantInfo,DateTimeStyles.None, out dt);
if(validDate)
Console.WriteLine(dt.ToLongDateString()); // now correctly initialized
With this format also DateTime.Parse/DateTime.TryParse works:
validDate = DateTime.TryParse(line, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out dt);
I use DateTimeFormatInfo.InvariantInfo to prevent that your local date separator is used instead of /(in case it's different).
Once it is parsed to DateTime it's trivial to create your Date instance:
Date d = new Date(dt.Day, dt.Month, dt.Year);
If you do NOT want to use DateTime.(Try)Parse, you can add a parse method with a Regex in your Date class:
public static Date ParseFromString(string s)
{
//string s = "24/12/2015";
Regex r = new Regex(#"(\d+)[\/](\d+)[\/](\d+)");
Match m = r.Match(s);
if (m.Success)
{
return new Date(m.Groups[1], m.Groups[2], m.Groups[3]);
}
else
{
// throw exception
}
}
You can't parse dd/MM/yyyy formatted string to int because it is not a valid string.
You need to parse it to DateTime first and you can use it's properties to get it's day, month and year as a numbers.
For example;
Console.WriteLine("please enter date as dd/MM/yyyy");
DateTime dt = DateTime.ParseExact(Console.ReadLine(), "dd/MM/yyyy",
CultureInfo.InvariantCulture);
int day = dt.Day;
int month = dt.Month;
int year = dt.Year;
Or you can use TryParseExact if you don't wanna throw exception if input is not dd/MM/yyyy format.
I am not wanting to use the preset DateTime class but I am using my
own "Date" class
If so, after you parse it, you can create your Date class instance with Date(int day, int month, int year) constructor based on this dt value as;
Date myDt = new Date(dt.Day, dt.Month, dt.Year);

Exclude non-working days in days to borrow [duplicate]

I just want to know on how to compute DateTime without including weekends (currently making a library system). The library is not open during weekends that is why i need to calculate the date that will not include weekends.
Ex.
03/13/15 = friday and im borrowing it for 5 days. So, the return date should be in 03/20/15= friday( because i didnt include the weekends)
Can you please tell me or give me some ideas? Thanks!
EDIT: ( The program suddenly freezes when i type a number)
int days = 0;
DateTime deyt = DateTime.Now;
rd.Text = deyt.ToString("MM/dd/yy");
DateTime dt = deyt.AddDays(int.Parse(textBox3.Text));
DateTime span = deyt;
while (span < dt.AddDays(1))
{
if (span.DayOfWeek != DayOfWeek.Saturday && span.DayOfWeek != DayOfWeek.Sunday)
{
days++;
span = span.AddDays(1);
bd.Text = days.ToString("MM/dd/yy");
}
}
If you have a list of DateTimes you can filter out the weekend dates:
public static List<DateTime> GetDatesWithoutWeekends(List<DateTime> dates)
{
return
dates.Where(date => (date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday))
.ToList();
}
DateTime date = DateTime.Now // Set your Date
if (date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday)
{
//TODO
}
There are far more efficient ways of doing this for large numbers of days, but if your code is only ever going to deal with small values, you can just use:
static DateTime AddDaysExcludingWeekends(DateTime start, int days)
{
// Do you need this?
if (days < 0)
{
throw new ArgumentException("Not implemented yet...");
}
DateTime current = start;
for (int i = 0; i < days; days++)
{
current = current.AddDays(1);
if (current.DayOfWeek == DayOfWeek.Sunday ||
current.DayOfWeek == DayOfWeek.Saturday)
{
// Effectively force "go round again" behaviour.
i--;
}
}
return current;
}
Or an alternative approach:
static DateTime AddDaysExcludingWeekends(DateTime start, int days)
{
// Do you need this?
if (days < 0)
{
throw new ArgumentException("Not implemented yet...");
}
DateTime current = start;
for (int i = 0; i < days; days++)
{
// Loop at least once, and keep going until we're on
// a weekday.
do
{
current = current.AddDays(1);
}
while (current.DayOfWeek == DayOfWeek.Sunday ||
current.DayOfWeek == DayOfWeek.Saturday);
}
return current;
}
Note that if you pass in days=0, that will return the original date even if it is on a weekend. It's not clear whether or not you want that behaviour, or whether it should skip to the Monday.
This is your code... Try..
int days = 0;
DateTime deyt = DateTime.Now;
DateTime dt = deyt.AddDays(int.Parse(textBox3.Text));
DateTime span = deyt;
while (span <= dt)
{
if (span.DayOfWeek != DayOfWeek.Saturday && span.DayOfWeek != DayOfWeek.Sunday)
{
days++;
bd.Text = days.ToString();
Console.WriteLine(span.ToString("MM/dd/yy"));
}
span = span.AddDays(1);
}

How to determine if given date falls in next week/month

for example I have to choose in datetimepicker May 16,2014 the messge box will pop out "This Week" and if I choose in datetimepicker May 20,2014 it will pop out "Next Week" and also June 20,2014 will pop out "Next Month".
I tried this..
System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
DayOfWeek firstDayOfWeek = ci.DateTimeFormat.FirstDayOfWeek;
int offset = firstDayOfWeek - DateTime.Now.DayOfWeek;
DayOfWeek lastDayOfWeek = DateTime.Now.AddDays(offset).AddDays(6).DayOfWeek;
DateTime nextmonth = DateTime.Now.AddMonths(1);
DateTime input = DateTime.Now.AddDays(1);
input = dateTimePicker1.Value;
DateTime startOfWeek = DateTime.Today;
while (startOfWeek.DayOfWeek != firstDayOfWeek)
startOfWeek = startOfWeek.AddDays(-1);
DateTime endOfWeek = DateTime.Now;
while (endOfWeek.DayOfWeek != lastDayOfWeek)
endOfWeek = endOfWeek.AddDays(1);
bool thisWeek = input >= startOfWeek && input <= endOfWeek;
bool Thismonth = input == startOfWeek && input < endOfWeek;
bool nextMonth = input == nextmonth;
if (thisWeek == true)
{
label1.Text = "This Week";
}
else if (thisWeek == false)
{
label1.Text = "Next Week";
}
else if (nextMonth == true)
{
label1.Text = "Next Month";
}
Not too much of a problem to do. C# provides lots of Date Time Functions, but not "Is this week" although you could write an extension method for this.
System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
DayOfWeek firstDayOfWeek = ci.DateTimeFormat.FirstDayOfWeek;
int offset = firstDayOfWeek - DateTime.Now.DayOfWeek;
DayOfWeek lastDayOfWeek = DateTime.Now.AddDays(offset).AddDays(6).DayOfWeek;
DateTime input = DateTime.Now.AddDays(1);
DateTime startOfWeek = DateTime.Today;
while (startOfWeek.DayOfWeek != firstDayOfWeek)
startOfWeek = startOfWeek.AddDays(-1);
DateTime endOfWeek = DateTime.Now;
while (endOfWeek.DayOfWeek != lastDayOfWeek)
endOfWeek = endOfWeek.AddDays(1);
Console.WriteLine("Week starts: " + startOfWeek);
Console.WriteLine("Week ends: " + endOfWeek);
Console.WriteLine("Input was: " + input);
Console.Write("Is input this week? ");
bool thisWeek = input >= startOfWeek && input <= endOfWeek;
Console.WriteLine(thisWeek);

Calculate DateTime for upcoming day of week

This is the code I have at the moment:
String getDayRequested;
public void setDay(String getDayFromForm1)
{
getDayRequested = getDayFromForm1;
{
if (getDayRequested.Contains("today"))
{
getDayRequested = DateTime.Today.DayOfWeek.ToString();
}
else if (getDayRequested.Contains("tomorrow"))
{
getDayRequested = DateTime.Today.AddDays(1).DayOfWeek.ToString();
}
}
This checks my TextBox.Text string from Form1, and checks to see if the text "today" or "tomorrow" is in it.
Can anyone help me in the right direction of how to check the string for information asked about upcoming days; ie: "What will be the date this saturday", and add the appropriate number of days depending on what the day is when asked.
UPDATE
Using the code in the accepted answer, I used the following in my above else if statement to complete what I was after:
else if (getDayRequested.Contains("monday"))
{
getDayRequested = GetFutureDay(DateTime.Now, DayOfWeek.Monday).ToString("dd");
}
This handy little method will return a future day of the week.
public DateTime GetFutureDay(DateTime start, DayOfWeek day)
{
int daysToAdd = (day - start.DayOfWeek + 7) % 7;
return start.AddDays(daysToAdd);
}
It would be called like:
var day = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), getDayFromForm1);
var getDayRequested = GetFutureDay(DateTime.Now, day);
Consider the following snippet of code...
DateTime date;
public void setDay(String day)
{
DayOfWeek futureDay = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), day);
int futureDayValue = (int)futureDay;
int currentDayValue = (int)DateTime.Now.DayOfWeek;
int dayDiff = futureDayValue - currentDayValue;
if (dayDiff > 0)
{
date = DateTime.Now.AddDays(dayDiff);
}
else
{
date = DateTime.Now.AddDays(dayDiff + 7);
}
}
Good Luck!

Categories