Calculate DateTime for upcoming day of week - c#

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!

Related

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);
}

Do not include weekends in date time

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);
}

Calculating an elapsed Time

I want to calculate the elapsed time which a process needs to execute based on 2 strings with timestamps in the format HH:mm:ss:ff. Therefore I splitted those strings, turned them into an integer and subtracted them.
What I tried is to subtract the last timestamp from the first. It also works sometimes. But I also get a lot of weird feedback out of this - for example: 0:0:-3:-18 I think this is the result of not handling the case if a value is higher than another and they get divided.
Here is the function I use to subtract the strings:
static string calculateElapsedTime(string startTime, string endTime)
{
try
{
string[] startTimeSplit = startZeit.Split(new char[] { ':', '.' });
string[] endTimeSplit = endZeit.Split(new char[] { ':', '.' });
int[] elapsedTime = new int[4];
endTimeSplit[0] = Convert.ToInt32(endTimeSplit[0]) - Convert.ToInt32(startTimeSplit[0]);
endTimeSplit[1] = Convert.ToInt32(endTimeSplit[1]) - Convert.ToInt32(startTimeSplit[1]);
endTimeSplit[2] = Convert.ToInt32(endTimeSplit[2]) - Convert.ToInt32(startTimeSplit[2]);
endTimeSplit[3] = Convert.ToInt32(endTimeSplit[3]) - Convert.ToInt32(startTimeSplit[3]);
string elapsedTimeString = string.Format("{0}:{1}:{2}:{3}", endTimeSplit[0], endTimeSplit[1], endTimeSplit[2], endTimeSplit[3]);
return elapsedTimeString;
}
catch( Exception ex )
{
Console.WriteLine(ex.Message);
return "null";
}
}
And I got the value for the parameters by simply getting the time like:
DateTime.Now.ToString("HH:mm:ss:ff", System.Globalization.DateTimeFormatInfo.InvariantInfo);
SOLUTION:
There is a Function called Stopwatch in the Namespace System.Diagnostics.
You can use it as following:
Stopwatch watch = new Stopwatch();
watch.Start();
//Prozess
watch.Stop();
Console.WriteLine(watch.Elapsed);
You could convert to TimeSpan with the correct format and subtract them, for sample:
string format = "HH:mm:ss:ffff";
TimeSpan startTimeSpan = TimeSpan.ParseExact(startTime, format, null);
TimeSpan endTimeSpan = TimeSpan.ParseExact(endTime, format, null);
TimeSpan result = startTimeSpan - endTimeSpan;
string elapsedTimeString = string.Format("{0}:{1}:{2}:{3}",
result.Hours.ToString("00"),
result.Minutes.ToString("00"),
result.Seconds.ToString("00"),
result.Milliseconds.ToString("00"));
return elapsedTimeString;
Take a look at the TimeSpan Formats at MSDN documentation.
I came across this, and this is what I created. You can add the month's calculation if you wish. You can also use the total<days, hours...>, but it will defeat the code. Generate a converter to convert to DateTime. It helps a lot.
public static string TimeElapsed(DateTime start_Time, DateTime end_time)
{
string result = "";
var subtractedDate = end_time.Subtract(start_Time);
if (subtractedDate.Days >= 7)
{
var weeks = (int)(subtractedDate.Days / 7);
if (weeks >= 52)
{
var years = (int)(weeks / 52);
result = $"{years} years ago";
}
else
{
result = $"{weeks} weeks ago";
}
}
else if (subtractedDate.Days > 0 && subtractedDate.Days < 7)
{
result = $"{subtractedDate.Days} days ago";
}
else
{
if (subtractedDate.Hours> 0)
{
result = $"{subtractedDate.Hours} hours ago";
}
else
{
if (subtractedDate.Minutes > 0)
{
result = $"{subtractedDate.Minutes} mins ago";
}
else
{
result = "< 1 min ago";
}
}
}
return result;
}

How to find out number of installments between two dates? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Suppose a Bank-Customer pays RD installments at every last day of the month.
So there must be 2 installments between the dates 12th October, 2013 and 10th December, 2013.
How can I find out how many installments the customer paid during this period of tine?
Should I use NodaTime library?
Ok. Here is my effort:
public sealed class DateDifference
{
int years;
public int Years
{
get { return years; }
}
int months;
public int Months
{
get { return months; }
}
int days;
public int Days
{
get { return days; }
}
public override string ToString()
{
return string.Format("[DateDifference Years={0}, Months={1}, Days={2}]", years, months, days);
}
public DateDifference(DateTime earlier, DateTime later)
{
if (later < earlier)
throw new ArgumentException("later is earlier than 'earlier'.");
bool isleapday = (earlier.Month == 2 && earlier.Day == 29);
DateTime tmp = isleapday ? new DateTime(earlier.Year, 2, 28) : earlier;
while (true)
{
try
{
tmp = tmp.AddYears(1);
if (isleapday && DateTime.IsLeapYear(tmp.Year))
tmp = new DateTime(tmp.Year, 2, 29);
}
catch (ArgumentOutOfRangeException)
{
break;
}
if (tmp <= later)
{
years++;
earlier = tmp;
}
else
{
break;
}
}
// Add months
tmp = earlier;
while (true)
{
try
{
tmp = tmp.AddMonths(1);
if (isleapday && tmp.Day != 29 && tmp.Month != 2)
tmp = new DateTime(tmp.Year, tmp.Month, 29);
}
catch (ArgumentOutOfRangeException)
{
break;
}
if (tmp <= later)
{
months++;
earlier = tmp;
}
else
{
break;
}
}
tmp = earlier;
while (true)
{
try
{
tmp = tmp.AddDays(1);
}
catch (ArgumentOutOfRangeException)
{
break;
}
if (tmp <= later)
{
days++;
earlier = tmp;
}
else
{
break;
}
}
}
DateDifference dateDifference = new DateDifference(startDateTextBox.Value, endDateTextBox.Value);
this.noOfInstallmentsTextBox.Text = ((int)++dateDifference.Months).ToString();
So I'll start off by saying I'm not prioritizing speed here. Datetime issues are tricky. Writing methods that you can be sure will work in all sorts of corner cases all over the world is hard. This approach is designed to work despite all edge cases and for that to be clear to the reader. It does not attempt to make cleaver optimizations because the tend to not work in odd edge cases, which are simply too common to ignore in the datetime world.
So first off we'll start with a simple helper method to get all of the days between two dates:
public static IEnumerable<DateTime> Days(DateTime start, DateTime end)
{
DateTime current = start;
while (current < end)
{
yield return current;
current = current.AddDays(1);
}
}
(If you want something more general purpose here you might get the next date after start, if you want all returned values to be "midnight". You might also swap start and end if they are in the reverse order, or throw an exception, etc. Also consider the exact semantics that you want; I have the bounds inclusive on start and exclusive on end, you may want it entirely inclusive, entirely exclusive, etc.)
We'll also create a method to determine if a date is the last day of the month.
public static bool IsLastDayOfMonth(DateTime date)
{
return date.AddDays(1).Month != date.Month;
}
We can actually define the last day of the month as being the only date for which its month is different from the following day's month.
Now when we combine these together we have an implementation that is very simple and clear to the reader:
public static int InstallmentCount(DateTime start, DateTime end)
{
return Days(start, end)
.Where(day => IsLastDayOfMonth(day))
.Count();
}
I hope it will help you.
int foo(DateTime start, DateTime end)
{
int count = end.Month - start.Month;
if (count < 0)
count += 12;
count += 12 * (end.Year - start.Year);
return count;
}

Categories