How to calculate when current pay period ends? - c#

I want to know how to calculate the last date of this pay period?
I know that the pay is bi-weekly and the first period started on 01/09/2012.
so far here what i have done
DateTime d = new DateTime();
d = Convert.ToDateTime("01/09/2012");
while (d <= Convert.ToDateTime("01/06/2013")) {
PayPeriod.Items.Add(new ListItem(d.ToString("MM/dd/yyyy"), d.ToString("MM/dd/yyyy")));
d = d.Date.AddDays(14);
}
And this work perfect, but it work perfect because I have manually put the ending of the current pay period "01/06/2013".
My question is how can I automatically figure out the last date of the current pay period?

You can easily do this with the following logic:
DateTime startTime = new DateTime(2012,09,01);
DateTime now = DateTime.Now;
var diff = now.Subtract (startTime);
int daysToEndPeriod = diff.Days % 14;
if (daysToEndPeriod == 0)
Console.WriteLine("end of pay period");
else
Console.WriteLine("end of pay period is: " + DateTime.Now.AddDays(14-daysToEndPeriod).Date);
This works because you'll always get the Modulo operator returns how many days past the pay period you have left.

Related

C# Time Subtraction With a Discord Bot

I'm making a funny discord bot that finds the next 4:20 on the clock, whether it's AM or PM, and tells you how long until 4:20. My code is working perfectly until an hour before 4:20 and then it skips ahead and tells how long until the next 4:20 instead of showing "0 hours 59 minutes". I'm thinking that there may be an issue with how I'm formatting the time output but I'm very new to C# and how no idea how to fix it. I have included my code and also a screenshot of the current output. In the screenshot the bot is also a minute off but I've since then figured out how to fix that. I know the code isn't the most efficient or clean but again, I'm very new to programming.
//Finds next 4:20 on the clock
[Command("420")]
public async Task WeedMinute()
{
DateTime currentTime = DateTime.Now; //Current time
DateTime weedMinuteMorning = Convert.ToDateTime("4:21:00"); //4:20am
DateTime weedMinuteEvening = Convert.ToDateTime("16:21:00"); //4:20pm
string weedMinutePM = "16:21:00"; //These variables are used in subtraction
string weedMinuteAM = "4:21:00";
if (currentTime <= weedMinuteEvening)
{
//chooseMorningEvening is the output time string
DateTime chooseMorningEvening = (DateTime.Parse(weedMinutePM).Subtract(currentTime.TimeOfDay));
await Context.Channel.SendMessageAsync("The next weed minute will happen in " + chooseMorningEvening.ToString(#"hh") + " hours " + chooseMorningEvening.ToString(#"mm") + " minutes.");
}
else if (currentTime >= weedMinuteMorning)
{
//chooseMorningEvening is the output time string
DateTime chooseMorningEvening = (DateTime.Parse(weedMinuteAM).Subtract(currentTime.TimeOfDay));
await Context.Channel.SendMessageAsync("The next weed minute will happen in " + chooseMorningEvening.ToString(#"hh") + " hours " + chooseMorningEvening.ToString(#"mm") + " minutes.");
}
}
The problem with your code is that it does not handle all the cases that can occur (there are three):
time is between 00:00:00 and 04:20:00 => calculate time to 04:20:00
time is between 04:20:00 and 16:20:00 => calculate time to 16:20:00
time is after 16:20:00 => calculate time to 04:20:00, next day.
You can simplify this a little if you observe that the time till your next toke should always be between 0 and 12 hours. So, if you just take the time until 16:20, if it is greater than 12 hours then you must be up before 04:20 and you can subtract 12 hours. If the time is less than 0 (that is, negative) then you must be later than 16:20 so you just add 12 hours. In code this looks like this:
public static TimeSpan CalculateTimeToWeed(DateTime from)
{
DateTime weedTime = Convert.ToDateTime("16:20:00");
TimeSpan twelveHours = TimeSpan.FromHours(12.0);
TimeSpan timeToWeed = weedTime - from;
double totalHours = timeToWeed.TotalHours;
if (totalHours > 12.0)
{
timeToWeed -= twelveHours;
}
else if (totalHours < 0.0)
{
timeToWeed += twelveHours;
}
return timeToWeed;
}
and you would integrate it into your Discord bot as follows:
[Command("420")]
public async Task WeedMinute()
{
DateTime currentTime = DateTime.Now;
TimeSpan timeToWeed = CalculateTimeToWeed(currentTime);
string message = "The next weed minute will happen in " + timeToWeed.ToString("hh' hours 'mm' minutes.'");
await Context.Channel.SendMessageAsync(message);
}
You could cut down the number of lines in this, but having these temporary variable makes thing easier to debug. You can check while stepping through with a debugger that currentTime is what you expect and timeToWeed makes sense and so on.
Breaking the code into two functions also has a number of advantages:
You can test the time calculation independent of the bot
The code is much clearer, you are not mixing up communication code with calculation code.
Hope this helps.
There's a DateTime.Compare function which can be used here to fix the error as below
//DateTime currentTime = DateTime.Now; //Current time
DateTime currentTime = Convert.ToDateTime("3:22:00"); // An example time for 0 hours and 59 mins
DateTime weedMinuteMorning = Convert.ToDateTime("4:21:00"); //4:20am
DateTime weedMinuteEvening = Convert.ToDateTime("16:21:00"); //4:20pm
string weedMinutePM = "16:21:00"; //These variables are used in subtraction
string weedMinuteAM = "4:21:00";
if(currentTime.CompareTo(weedMinuteMorning) < 1) //less than or same as Morning 4:20 am
{
var chooseMorningEvening = weedMinuteMorning - currentTime;
string m = "The next weed minute will happen in " + chooseMorningEvening.Hours + " hours " + chooseMorningEvening.Minutes + " minutes.";
}
else
{
var chooseMorningEvening = weedMinuteEvening - currentTime;
string m = "The next weed minute will happen in " + chooseMorningEvening.Hours + " hours " + chooseMorningEvening.Minutes + " minutes.";
}
Your formatting the time output seem ok, just for better formats see Custom TimeSpan format strings.
Your code have three problem:
1. If Conditions
if (currentTime <= weedMinuteEvening)
{
//this condition is true from 00:00:00 to 16:21:01 so for dates less than 4:21:00
//you get incorrect output, and next condition execute just for dates greater than 16:21:00.
...
}
else if (currentTime >= weedMinuteMorning)
{
//This code execute only for dates greater than 16:21:00.
...
}
As Adam suggested you must remove .TimeOfDay from currentTime but this not enough.
You must handle dates grater than 16:21:00
So i hope this code work for you:
[Command("420")]
public async Task WeedMinute()
{
DateTime currentTime = DateTime.Now; //Current time
DateTime weedMinuteMorning = Convert.ToDateTime("4:21:00"); //4:20am
DateTime weedMinuteEvening = Convert.ToDateTime("16:21:00"); //4:20pm
//I removed These variables, Don't need to parse same DateTime again. change it as you wish
//string weedMinutePM = "16:21:00";
//string weedMinuteAM = "4:21:00";
if (currentTime <= weedMinuteMorning)
{
TimeSpan timeSpan = weedMinuteMorning.Subtract(currentTime);
await Context.Channel.SendMessageAsync("The next weed minute will happen in " + timeSpan.ToString("hh' hours 'mm' minutes.'"));
}
else if (currentTime <= weedMinuteEvening)
{
TimeSpan timeSpan = weedMinuteEvening.Subtract(currentTime);
await Context.Channel.SendMessageAsync("The next weed minute will happen in " + timeSpan.ToString("hh' hours 'mm' minutes.'"));
}
else
{
//To handle dates greater than 16:21:00, we must calculate hours
//remaining until 4:20 next day.
weedMinuteMorning = weedMinuteMorning.AddDays(1);
TimeSpan timeSpan = weedMinuteMorning.Subtract(currentTime);
await Context.Channel.SendMessageAsync("The next weed minute will happen in " + timeSpan.ToString("hh' hours 'mm' minutes.'"));
}
}

Minute give wrong values on substract

I want to subtract minutes and get the difference. below is my code
double diff = currBlock.EndTime.Subtract(currBlock.StartTime).TotalMinutes;
In given code (currBlock.StartTime = 23:30:00) and (currBlock.EndTime= 00:20:00)
here starttime is time of today i.e.(09/26/2016 23:30:00), night time which will be consider as 11:30 PM and endtime is time of tomorrow i.e.(09/27/2016 00:20:00), morning time which will be consider as 12:20 Am. In my code i am getting values in minus which is -1390 and it is incorrect. So please help me to solve this.
Here i have attach image of data for further reference.
please explain me properly, how do i use it? it is just a time block for different shift so there is no date include in it
There is a date included in it. You're telling us that EndTime is something like 09/27/2016 00:20:00, while StartTime is something like 09/26/2016 23:30:00. The problem is that that knowledge is in your head and not in your code. If you subtract the values as TimeSpans, then you're literally saying: what is 30 minutes minus 23 hours and 30 minutes. The answer, of course is -23 hours. To get the real difference, you must include the dates, which means utilizing a DateTime or DateTimeOffset type for both StartTime and EndTime, so you can encode that whole date and time. Then, when you do the subtraction, it will return the right value.
Below Code works for me. Thanks friends for your support and help.
string strCurrDate = (DateTime.Now.Date + currBlock.EndTime).ToString();
DateTime dtYourDate = DateTime.Parse((DateTime.Now.AddDays(-1).Date + currBlock.StartTime).ToString());
string strYourDate = dtYourDate.ToShortDateString() + " " + dtYourDate.ToLongTimeString();
string strTotalMinsElapsed = TotalMinutesElapsed(dtYourDate).ToString();
private long TotalMinutesElapsed(DateTime dtYourDate)
{
long lTotalMinutesElapsed = 0;
//Find Current Date and Time
DateTime dtCurrent = DateTime.Now;
//Find Time Difference details between current date and your given date
TimeSpan tsDiff = dtCurrent.Subtract(dtYourDate);
//Add Total Minutes for Days difference
lTotalMinutesElapsed = lTotalMinutesElapsed + tsDiff.Days * (24 * 60);
//Add Total Minutes for Hour difference
lTotalMinutesElapsed = lTotalMinutesElapsed + tsDiff.Hours * 60;
//Add Minutes
lTotalMinutesElapsed = lTotalMinutesElapsed + tsDiff.Minutes;
return lTotalMinutesElapsed;
}

Making a countdown to multiple times of day

Current code:
while (true)
{
// Gets current time
DateTime farD = DateTime.Now;
//Gets the departure time
DateTime s = DateTime.Now;
TimeSpan ts = new TimeSpan(15, 30, 0);
s = s.Date + ts;
// Countdown to departure.
TimeSpan apa = s-farD;
//Writes time left and clears console. With a 1 second interval.
Console.Clear();
Console.WriteLine("{0}:{1}:{2} Till färjan går",apa.Hours,apa.Minutes,apa.Seconds);
Thread.Sleep(1000);
}
}
}
}
What I am aiming towards, is to do a countdown a specific times each day, when the ferry leaves.
Problem is that the ferry have 50+~ departure times each day, And with this solution for a countdown gets very messy.
So questions:
Is there a quicker way to make a countdown that is not dependent on what date of the month/year it is?
(Diffrent ferry times will later be controlled with DateTime.DayOfWeek)
Ill post a link with the ferry times so you can see how the times differ per time of day and weekday:
Ferry departure times
I know Ive not come close to a final solution, but I rather want to start with the right calculation for making a countdown to a time, that is independent of what day, month or year it is.
As BugFinder said, this is not stack overflow question, but i can give you a tip:
Create a List AllDepartures where you can store all departures time.
And use it:
List<DateTime> DayDepartures = AllDepartures.FindAll (
o => o.DayOfWeek == DateTime.Now.DayOfWeek
);
This is how you can get all the departures on today.
And like this you can get the departures that are after now, sorted by hour:
List<DateTime> NextHourDepartures = DayDepartures.FindAll (
o => o.Hour >= DateTime.Now.Hour
).OrderBy(o => o.Hour).ToList();
And you can get the next departures on current hour, sorted by time like this:
List<DateTime> NextMinuteDepartures = NextHourDepartures.FindAll(
o => o == NextHourDepartures[0]
).FindAll (
o => o.Minute >= DateTime.Now.Minute
).OrderBy(o=>o.Minute).ToList();
and then you next departure time is:
DateTime nextDeparture = NextMinuteDepartures [0];
Hope this helps, but next time try to represent your problem better.

Calculate the difference between two dates and times

I'm having problem in calculating the difference between two days using form in Visual Studio c#. I was trying to use TimeSpan but I want the messagebox to display a message. How to use if statement in this matter?
DateTime startDate = (DateTime)datePreviDate.Value;
DateTime endDate = (DateTime)datecurrentTime.Value;
TimeSpan ts = endDate.Subtract(startDate);
//Here i want to put if statemnet like
//if the difference of days are less than 2 AND PREVTIME + CURRENT TIME
//IS LESS THEN 24
//then MessageBox.Show.("you CANNOT CHANGE THE DATE")
//else MessageBox.Show.("you APPOINTMENT HAS BEEN CHANGED")
MessageBox.Show(ts.Days.ToString());
form image here
It's kind of hard to understand what you want. But this might help you. I am assuming "PREVTIME" and "CURRENTTIME" are assigned previously. I'm also just turning your comments into logic. Not sure if this is what you meant.
DateTime start = (DateTime)datePreviDate.Value;
DateTime end = (DateTime)datecurrentTime.Value;
var timespan = end - start
var totalTime = PREVTIME + CURRENTTIME;
if(timespan.TotalDays > 2 && totalTime < 24){
MessageBox.Show("You Cannot Change The Date");
//Continue Code Here
} else {
MessageBox.Show("Your Appointment Has Been Changed");
//Continue Code Here
}

Time Math Guidance needed

I have a DateTime object that is 10:00 AM
This time represents what time of day a report should be run.
I want to calculate the amount of time remaining from NOW until 10:00 AM
part of my confusion is NOW might be after 10:am or BEFORE 10am,
I keep playing around with TimeSpan, but my results are not quite right... I am sure this is simple, but it is one of those things I have been working of for a few hours and I need a push in the right direction...
I want the timespan object timeTillRun to be correct...here is what I have tried:
{
DateTime scheduledRun = DateTime.Today.AddHours(_timeToStart);//_timeToStart = 10
TimeSpan timeTillRun = DateTime.Now - scheduledRun;
}
This will work... but you need to reverse the order of subtraction:
TimeSpan timeTillRun = scheduledRun - DateTime.Now;
Note that if it's currently after 10AM, timeTillRun will be negative. You will presumably also need to check if the current time is on or after 10AM, then add 10 hours and one day to DateTime.Today to obtain the next run time. Alternatively, you could test if timeTillRun is negative; if so, just add one day to it (timeTillRun += new TimeSpan(1, 0, 0, 0)).
Try this
DateTime timeToStart = DateTime.Today.AddHours(10);
TimeSpan timeTillRun;
// Checking to see if current time is passed schedule run, if it is then we add a day (this is assuming this is run daily, if days are skipped like weekends for example then this would need some tweaking)
if (DateTime.Now > timeToStart)
timeTillRun = DateTime.Now.AddDays(1.0) - timeToStart;
else
timeTillRun = DateTime.Today - timeToStart;
double totalHoursRemaining = timeTillRun.TotalHours; // get total hours remaining
string prettyRemaining = String.Format("{0} day and {1} hours", timeTillRun.Days, timeTillRun.Hours); // can do some outputting here

Categories