How to subtract two Datetime values in C#? - c#

I want to subtract two Datetime values. I collected them separately from the form and concatenate it in C#. The result shows in Hour format in textbox like "23:00".
Here is what I tried:
string start = StartDateTxtBox.Text+" "+StartHourDrop.Text+":"+StartMinuteDrop.Text+":00";
string End = EndDateTxtBox.Text + " " + EndHourDrop.Text + ":" + EndMinuteDrop.Text + ":00";
DateTime allstart = DateTime.Parse(start);
DateTime allEnd = DateTime.Parse(End);
Int32 MinuteDiff = Convert.ToInt32(allEnd.Subtract(allstart).TotalMinutes);
Int32 Hour = MinuteDiff / 60 / 24;
DateTime conversiontotime = System.Convert.ToDateTime(Hour);
LastID.Text = conversiontotime.ToString();
But it doesn`t work.
Is there another (easy) way to do this, or can anybody tell me what the problem in my code is?

DateTime allstart = DateTime.Parse("03/04/2015 09:15");
DateTime allEnd = DateTime.Parse("03/04/2015 09:37");
TimeSpan tsdiff = allEnd - allstart;
LastID.Text = tsdiff.ToString();

Related

Sum of multiple TimeSpan

I have to do the sum of more time spans in a DataTable to use the code below, but the total sum is wrong, what is due to this:
DataTable(dt) values:
09:21
08:28
08:46
04:23
Total hours: 30,97 //97 minutes is not correct
C# Code:
TimeSpan totaleOreMarcaTempo = TimeSpan.Zero;
int conta = 0;
foreach (DataRow dr in dt.Rows)
{
String OreMarcaTempo = tm.ConteggioOreGiornaliere(dr["Data"].ToString()); //This string contains at each cycle 09:21 08:28 08:46 04:23
TimeSpan oreMarcatempo = TimeSpan.Parse(OreMarcaTempo.ToString());
totaleOreMarcaTempo = totaleOreMarcaTempo + oreMarcatempo;
conta++;
}
labelTotaleOreMarcaTempoMod.Text = "" + (int)totaleOreMarcaTempo.TotalHours + ":" + totaleOreMarcaTempo.Minutes.ToString(); //30:58
30.97 is the correct number of hours. It does not mean "30 hours and 97 minutes".
30.97 hours is 30 hours and 58 minutes. 58 / 60 is roughly 0.97.
I think you just need to format your string properly. One way to format it is:
#"{(int)yourTimeSpan.TotalHours}:{yourTimeSpan.Minutes}"
Value 30.97 is correct (30.97 hours, where 0.97 is hour (60 minutes * 0.97 = 58 minutes),
you just need convert fraction of TotalHours to minutes.
var raw = "09:21 08:28 08:46 04:23";
var totalTimespan =
raw.Split(" ")
.Select(TimeSpan.Parse)
.Aggregate(TimeSpan.Zero, (total, span) => total += span);
// Use integer value of TotalHours
var hours = (int)totalTimespan.TotalHours;
// Use actual minutes
var minutes = totalTimespan.Minutes
var output = $"{hours}:{minutes}";
var expected = "30:58";
output.Should().Be(expected); // Pass Ok
You have to change the Format. 0,98 hours = 58,2 minutes
labelTotaleOreMarcaTempoMod.Text =string.Format ("{0:00}:{1:00}:{2:00}",
(int)totaleOreMarcaTempo.TotalHours,
totaleOreMarcaTempo.Minutes,
totaleOreMarcaTempo.Seconds);
To print out a TimeSpan "correctly", just use the correct formatting:
labelTotaleOreMarcaTempoMod.Text = totaleOreMarcaTempo.ToString("c");
or
labelTotaleOreMarcaTempoMod.Text = totaleOreMarcaTempo.ToString("hh':'mm");
EDIT Do note (thanks, Basin) that the second form ignores days.
Reference: Standard TimeSpan Format Strings and Custom TimeSpan Format Strings
30.97 is the correct value but not HH:mm format.
For me the correct solution is :
var total = Math.Floor( totaleOreMarcaTempo.TotalMinutes / 60).ToString() + ":" + Math.Floor( totaleOreMarcaTempo.TotalMinutes % 60).ToString();

Unity C#, How to addition X days to a date?

In this part of code sDate show current date 2016/11/16, Now what is best way to add 7 days to current date? for example if current date is 2016/11/29 + 7 change to 2016/12/06. I'm looking for a way to addition an int value to a date.
string Year;
string Month;
string Day;
float time;
string sDate;
void Start ()
{
Year = System.DateTime.Now.Year.ToString();
Month = System.DateTime.Now.Month.ToString();
Day = System.DateTime.Now.Day.ToString();
int Y = int.Parse (Year);
int M = int.Parse (Month);
int D = int.Parse (Day);
if (Y >= 2016 & M >= 11 & D >= 21)
{
sDate = Year + "/" + Month + "/" + Day + " | Expired";
Debug.Log (sDate);
Application.Quit ();
}
else
{
sDate = Year + "/" + Month + "/" + Day + " | Working";
Debug.Log ("System date: " + sDate);
}
}
All you need to do is use the standard DateTime function AddDays:
DateTime result = original.AddDays(n);
where original is the original date and n is the number of days you want to add.
I'd also check the rest of the documentation on the DateTime structure as there are a lot simpler ways of doing what you are trying here. As mentioned in the comments you can construct a DateTime object from it's components:
DateTime referenceDate = new DateTime(2016, 11, 15);
and then do comparisons on that:
if (testDate >= referenceDate)
{
// Do something
}
etc.

Text box string not recognized as valid DateTime

const double PERCENT = 0.25;
DateTime t1 = Convert.ToDateTime(txtB_StartT.Text);
DateTime t2 = Convert.ToDateTime(txtB_EndT.Text);
TimeSpan ts = t1.Subtract(t2);
I cant seem to get this to parse into a DateTime
double tsMin = Convert.ToDouble(ts);
double tsMinTot = ts.TotalMinutes;
short tsMinPercent = (short)(((double)tsMinTot) * PERCENT);
double tsAndPercentTot = tsMinPercent + tsMinTot;
My goal here was to find a timediff, find what 25% of that timediff is and add it to the timediff.
DateTime newTimeMinTot = Convert.ToDateTime(tsAndPercentTot);
int hours = newTimeMinTot.Hour;
int minutes = newTimeMinTot.Minute;
An attempt to get a calculated new Datetime
string newTimeStrg = string.Format("{0:d1}:{1:d2}", hours, minutes);
txtB_NewDelivT.Text = newTimeStrg;
Attempt to output new DateTime to TextBox.
Someone please explain. How can I make the user input in military time and make this work.
Do it like this:
const double PERCENT = 0.25;
DateTime t1 = Convert.ToDateTime(txtB_StartT.Text);
DateTime t2 = Convert.ToDateTime(txtB_EndT.Text);
TimeSpan ts = t1.Subtract(t2);
long tsMinPercent = ts.Ticks + (long)(ts.Ticks * PERCENT);
var tsAndPercentTot = TimeSpan.FromTicks(tsMinPercent);
string newTimeStrg = string.Format("{0:d1}:{1:d2}", tsAndPercentTot.Hours, tsAndPercentTot.Minutes);
txtB_NewDelivT.Text = newTimeStrg;
Here I am using DateTime.Ticks to calculate percentage of time of difference and TimeSpan.FromTicks to find DateTime again from calculated percentage DateTime.
Instead using TextBox you can use TimePicker.
to force your date/datetime format
DateTime mydate = DateTime.ParseExact(TextBox1.Text.Trim(), "dd/MM/yyyy", null);
Based on your comment where you write that the input values are "0945" and "1445", I suggest you to replace your TextBox controls with DateTimePicker controls.
Just to have them display values as you are doing right now, you'll have to set some properties as I show you here.
picker.Format = DateTimePickerFormat.Custom;
picker.CustomFormat = "HHmm";
picker.ShowUpDown = true;
later, the picker.Value will return a whole date with time, where minutes and seconds will resemble the input values.
You can obvously set the properties' values from the designer.
Regards,
Daniele.
Since I don't have your form, I'll leave out the UI interaction. Here's how you can parse an input stream. I've show how to parse a hh:mm format, as well as a hhmm format:
var start = TimeSpan.ParseExact("10:00", "hh\\:mm", CultureInfo.InvariantCulture);
var finish = TimeSpan.ParseExact("1100", "hhmm", CultureInfo.InvariantCulture);
Once you have the start and finish, all we have to do is the math. We'll create a new TimeSpan from the ticks (the smallest unit of measurement on a TimeSpan) multiplied by our percentage (0.25). Then we just add the adjustment to our start time and we're done! You can then assign that into where ever you need the output.
var diff = finish - start;
var adjustment = TimeSpan.FromTicks((long)(diff.Ticks * 0.25));
var adjustedStart = start + adjustment;
You can run the code out at dotNetFiddle. I've included output there so you can see the intermediate results along the way.
Ok well i took a different approach and it worked out fairly easy.
I'm not sure if I'm allowed to answer my own question but i figure it
will help someone with the same issue i had.
// Set Constant values.
const double PERCENT = .25;
const int HUN_PART = 100, SIXTY = 60, one = 1;
// Parse start time textbox value as int
// Calculate start time hours and minutes
int sT = int.Parse(textBox1.Text);
int sH = sT / HUN_PART;
int sM = sT % HUN_PART;
// Calculate total start time in minutes
int sH_M = sH * SIXTY;
int sTotM = sH_M + sM;
// Parse end time textbox value as int
// Calculate end time hours and minutes
int eT = int.Parse(textBox2.Text);
int eH = eT / HUN_PART;
int eM = eT % HUN_PART;
// Calculate total end time in minutes
int eH_M = eH * SIXTY;
int eTotM = eH_M + eM;
// Calculate time difference in minutea
// Calculate percent of time difference
double dT_M = Convert.ToInt32(eTotM - sTotM);
int perc = Convert.ToInt32(dT_M * PERCENT);
// Calculate new arrival time in total min then in hours
double newD_M = perc + eTotM;
double newD_H = newD_M / SIXTY;
// Calculate new arrivaltime in remaining minutes
double nD_H_Convert = Math.Truncate(newD_H);
int nD_H = Convert.ToInt32(nD_H_Convert);
int nD_Hours = nD_H * HUN_PART;
double nD_Min = nD_H * SIXTY;
int nD_M = Convert.ToInt32(newD_M - nD_Min);
int newDeliveryTime = (nD_H * HUN_PART) + nD_M;
// Put values for new arive time hours and minutes in appropriate string format
string newTime = string.Format("{0:d4}", newDeliveryTime);
// Output arrival time string in textbox
textBox3.Text = newTime;
I was apparently trying to do more than was actually required, so by using a few simple calculations the issue was resolved.
Thank you for the help everyone.

How do I represent date range for months that donot have 31 days in c#?

I want to find the leaves taken by an employee in a month.
The code works perfectly for all the dates.
Now, if I want to find the leaves taken by the employee in January, the range is:
DateTime first = Convert.ToDateTime(DateTime.Now.Month + "01" + DateTime.Now.Year);
DateTime end = Convert.ToDateTime(DateTime.Now.Month + "31" + DateTime.Now.Year);
The problem is that some months do not have 31 days. Is there an easy way with which I could assign the variables From and To the range. An error would be given when the months's Feburary or April because they donot have 31 days.
The code for executing the search is :
returnedRows = LeaveDS.Tables["Leave"].Select("LeaveDate >= #" + first + "# AND LeaveDate <= #" + end + "#");
You could do something like this:
DateTime end = first.AddMonths(1).AddDays(-1);
DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month)
it'll give you the days in a month.
Use DateTime.DaysInMonth(int year, int month)
int days = DateTime.DaysInMonth(2012, 2);
int days2 = DateTime.DaysInMonth(2011, 2);
output:
days = 29
days2 = 28
You can get the number of days in a month by DateTime.DaysInMonth(year,month), and use this as basis for your query.
The alternative is to use the first of each month but alter your select query to be less than the end date.
DateTime first = Convert.ToDateTime(DateTime.Now.Month + "01" + DateTime.Now.Year);
DateTime end = first.AddMonths(1); // Becomes 01 of next month
returnedRows = LeaveDS.Tables["Leave"].Select("LeaveDate >= #" + first + "# AND LeaveDate < #" + end + "#");
There is a great method to get the days in a month, it's called DateTime.DaysInMonth
DateTime end = new DateTime(first.Year, first.Month, DateTime.DaysInMonth(first.Year, first.Month);
var enddate = DateTime.Now.AddMonths(1);
DateTime end = new DateTime(enddate.Year,enddate.Month,1);
By the way, if you're using .NET 3.5 or greater Linq-To-DataSet will simplify and improve the code:
int month = 2; // f.e. for february
var currentCalendar = System.Globalization.CultureInfo.CurrentCulture.Calendar;
int daysInMonth = currentCalendar.GetDaysInMonth(month);
DateTime start = new DateTime(DateTime.Now.Year, month, 1);
DateTime end = new DateTime(DateTime.Now.Year, month, daysInMonth);
var filteredRows = LeaveDS.Tables["Leave"].AsEnumerable()
.Where(r => r.Field<DateTime>("LeaveDate").Date >= start
&& r.Field<DateTime>("LeaveDate").Date <= end );
// use ToArray for an array, CopyToDataTable for a DataTable etc.

Divide timespan by 2?

I have two times, and their values are picked up from a XML from web.
XElement xmlWdata = XElement.Parse(e.Result);
string SunRise = xmlWdata.Element("sun").Attribute("rise").Value;
string SunSet = xmlWdata.Element("sun").Attribute("set").Value;
DateTime sunrise = Convert.ToDateTime(SunRise.Remove(0,11));
DateTime sunset = Convert.ToDateTime(SunSet.Remove(0, 11));
This gives med the time: 04:28 for sunrise, and 22:00 for sunset.
How to then do a calculation where i take:
(sunrise + (sunset-sunrise)/2)
I think you want to do this:
TimeSpan span = sunset-sunrise;
TimeSpan half = new TimeSpan(span.Ticks / 2);
DateTime result = sunrise + half;
It can be written in one line if you want.
TimeSpan sunnyTime = TimeSpan.FromTick(sunrise.Ticks + (sunset.Ticks - sunrise.Ticks) / 2);

Categories