How to return long after Date Subtract? - c#

DateTime dtLastUse = date1.Subtract(date2);
Long lSubtract = dtLastUse.Ticks;
The Result I Get:
My Result return something like this { 14433.14:02:30 }
How to return me only 14434?

The result of subtracting a date from another date is a TimeSpan. This is to prevent exactly the kind of confusion you're having. If you want to get the total number of days, use TotalDays. You can round that value the way you want (e.g. use Math.Floor if you want the number of complete days) and cast to int to get an integer value.
Just because Ticks has the same data type you want doesn't mean it's what you want. It essentially gives you the full time resolution possible of the data in the TimeSpan (which happens to be tenths of microseconds).

Related

Converting a double to a time that makes sense

Basically I am setting a limit of hours a user can use. Now every time a button is press, whatever time that person accrued gets taken away from this total value.
However because a limit would be represented as say 156 hours, and the datetime representation of 5 minutes would be 00.05 the result would be 155.95, rather than 155.55 .
I work this out like so
string date2 = TotalMonthlyHours.ToString("HH.mm");
double date = double.Parse(date2);
RunningTotal = date + RunningTotal;
Total = limit - RunningTotal;
Any ideas?
I think you are trying to represent 5 minutes as 0.05. The way to do that is to first of all obtain the minutes as an integer. And then simply convert to double.
double floatmins = minutes/100.0;
And you convert in the other direction like this:
int minutes = (int) (floatmins*100.0);
However, I urge you not to go any further with this. You cannot expect to perform arithmetic on a quantity like that. What is the result of 2.20-1.50? You and I know it's 30 minutes, but the computer says 0.70 which is no use at all.
Store the hours using a true fractional representation. So 5 minutes is 5/60.0. Or store the total minutes in an integer. Or total seconds in an integer. Or a TimeSpan.
The key is that you can write your own helper routines to convert from a sane storage format to a value that is human readable. But you must store the raw data in a representation that will admit arithmetic operations.
I think I worked it out by doing something like this
string[] times = date.ToString().Split('.');
if (date != 0.0)
{
string minutesString = times[1];
string hoursString = times[0];
double minutes = Convert.ToDouble(minutesString);
double hours = Convert.ToDouble(hoursString);
// end of splitting
TimeSpan Limit = TimeSpan.FromHours(limit);
TimeSpan Hours = TimeSpan.FromHours((int)hours);
TimeSpan Minutes = TimeSpan.FromMinutes((int)minutes);
TimeSpan SubTotal = Hours + Minutes;
Time = Limit - SubTotal;
}
Edit: Glad you came up with the same as me,Just read your reply David, let's hope it works
I would convert it to minutes first than add as minutes to the date
var min = Convert.ToDouble(Convert.ToDecimal(textbox.Text) * 60);
DateTimePickerEnd.DbSelectedDate = e.NewDate.Value.AddMinutes(min);

Data Structure for caching (Key = DateTime, Value = decimal)

I have a function which calculates employee hours in a day. But, it's slow because it considers carry hours and other things.
I figure I can optimize this by caching the hours in a day and only update on change.
I'm looking for something that can quickly do:
Set(date,hours)
HasHoursFor(date)
GetHoursFor(date)
What should I use for this?
I could use a Dictionary, but I am wondering if there is not some sort of hash way to set, get, and contains quickly.
You could use a Dictionary<DateTime,int> and cache the hours against the date, like so:
Dictionary<DateTime,int> dict = new Dictionary<DateTime,int>();
void Set(DateTime date, int hours)
{
if (dict.Contains(date)) dict.Remove(date);
dict.Add(date.Date,hours);
}
bool HasHoursForDate(DateTime date)
{
return dict.Contains(date.Date);
}
int GetHoursForDate(DateTime date)
{
return dict[date.Date];
}
Set(DateTime.Now,8);
I normalise the date so that's its JUST the date and doesn't care about the time part, otherwise that would throw off the comparison. I'm also assuming you have whole hours otherwise you might want to change int to double etc.

Check difference in seconds between two times

Hi all I am currently working on a project where when a certain event happens details about the event including the time that the event occurred is added into a list array.
Once the method has finished I then pass on the list to another method that checks its values. Before I go through the loop I check the current time of my PC and I need to check whether the difference between the time saved in the list array and the current time is greater than 5 seconds.
How would I go about doing this.
Assuming dateTime1 and dateTime2 are DateTime values:
var diffInSeconds = (dateTime1 - dateTime2).TotalSeconds;
In your case, you 'd use DateTime.Now as one of the values and the time in the list as the other. Be careful of the order, as the result can be negative if dateTime1 is earlier than dateTime2.
DateTime has a Subtract method and an overloaded - operator for just such an occasion:
DateTime now = DateTime.UtcNow;
TimeSpan difference = now.Subtract(otherTime); // could also write `now - otherTime`
if (difference.TotalSeconds > 5) { ... }
This version always returns the number of seconds difference as a positive number (same result as #freedeveloper's solution):
var seconds = System.Math.Abs((date1 - date2).TotalSeconds);
I use this to avoid negative interval.
var seconds = (date1< date2)? (date2- date1).TotalSeconds: (date1 - date2).TotalSeconds;
The built-in DateTime.Subtract method can be used as follows
double diffInSeconds = dateTime1.Subtract(dateTime2).TotalSecond;
if (diffInSeconds > 5) { /* do stuff */ } ;

Cut-/Rounding down a DateTime to a Whole i.e. Hour/Day?

Is there any kind of mathematical way to cut DateTime down to a exact Hour, Day or so? Similiar to round of a decimal to int.
Period.Day
If the original value was 2011-01-01 13:00:00, it ends up in 2011-01-01 00:00:00
if Period.Hour
If the original value was 2011-03-11 13:32:00, it ends up in 2011-03-11 13:00:00
I think about something like below. This are of course works fine, but the range-array are iterated through anyway, later. Better if I was possible to calculate directly on that iteration, instead of it's own. But someType can't be put into that iteration (it depends on someType).
if (someType == Period.Day)
range.ForEach(d => d.time = new DateTime(d.time.Year, d.time.Month, d.time.Day,0,0,0));
if (someType == Period.Hour)
range.ForEach(d => d.time = new DateTime(d.time.Year, d.time.Month, d.time.Day, d.time.Hour, 0, 0));
Rounding down to a day is equivalent to time.Date, rounding to nearest (up on midpoint) is simply ( time + 12hours ).Date.
For rounding down to a full hour I can't think of code that's nicer to read than yours. For rounding up to the nearest hour you can apply your code to time + 30mins.
There is probably a faster method for rounding to the nearest hour:
const Int64 HourInTicks=...;
Int64 timeInTicks=time.Ticks;
Int64 trucatedToHour=timeInTicks-timeInTicks%HourInTicks;
But I'd avoid that, unless you really need the performance, which is unlikely.
(My round to nearest might have issues on days where the local time offset changes if you're using local time)
To round down to day you can use the DateTime.Date Property.
To round down to hour, I'm afraid you'll have to either use what you did in your example or something like:
d.Date.AddHours(d.Hour)
I'll do the following:
private static readonly DateTime Epoch = new DateTime(1970, 1, 1);
public static DateTime Round(this DateTime d, Period p)
{
var ts = d - Epoch;
if (p == Period.Hour)
{
var hours = (long)ts.TotalHours;
return Epoch.AddHours(hours);
}
else if (p == Period.Days)
{
var days = (long)ts.TotalDays;
return Epoch.AddDays(days);
}
// ...
}
I believe the following C# code will round a DateTime value to nearest minute, and I think it will be easy to generalize it to round to other units.
//round to nearest minute; add 30 seconds for rounding to nearest minute
effectiveDateTime = effectiveDateTime.AddSeconds(30);
TimeSpan timeComponent = effectiveDateTime.TimeOfDay;
effectiveDateTime = effectiveDateTime.Date;
effectiveDateTime = effectiveDateTime.AddHours(timeComponent.Hours).
AddMinutes(timeComponent.Minutes);
Not sure if this approach is effective, but looks quite nice using string format (in this case cutting down to hours):
var date = DateTime.UtcNow;
var cutDownDate = Convert.ToDateTime(date.ToString("yyyy-MM-dd hh"));
Answer Is there a better way in C# to round a DateTime to the nearest 5 seconds? contains an excellent generic DateTime rounding approach.
Edit:
This answer was before the updated question title and is an algorithm for rounding to nearest not rounding down.
Best method for day:
DateTime now = DateTime.Now;
DateTime roundDay = now.Date;

Convert DateTime.Now to Seconds

I am trying to write a function that will convert a DateTime.Now instance to the number of seconds it represents so that I can compare that to another DateTime instance. Here is what I currently have:
public static int convertDateTimeToSeconds(DateTime dateTimeToConvert)
{
int secsInAMin = 60;
int secsInAnHour = 60 * secsInAMin;
int secsInADay = 24 * secsInAnHour;
double secsInAYear = (int)365.25 * secsInADay;
int totalSeconds = (int)(dateTimeToConvert.Year * secsInAYear) +
(dateTimeToConvert.DayOfYear * secsInADay) +
(dateTimeToConvert.Hour * secsInAnHour) +
(dateTimeToConvert.Minute * secsInAMin) +
dateTimeToConvert.Second;
return totalSeconds;
}
I realize that I am truncating the calculation for seconds in a year, but I don't need my calculation to be precise. I'm really looking to know if the method that I am using to calculate seconds is correct.
Does anyone have anything that could better compute seconds given from a DateTime object?
Also, Should the return type be int64 if I am coding in C# if I am going to calculate all the seconds since 0 AD?
The DateTime type supports comparison operators:
if (dateTimeA > dateTimeB)
{
...
This also works for DateTime values returned by DateTime.AddSeconds:
if (dateTimeA.AddSeconds(42) > dateTimeB)
{
...
If you really want the number of seconds that elapsed since 01/01/0001 00:00:00, you can calculate the difference between the two DateTime values. The resulting TimeSpan value has a TotalSeconds property:
double result = DateTime.Now.Subtract(DateTime.MinValue).TotalSeconds;
It really doesn't make sense to convert a DateTime object to seconds. Seconds only make sense if you are dealing with a length of time (TimeSpan). Should you want to compare two dates to get the number of seconds between them:
TimeSpan diff = DateTime.Now - PreviousDateTime;
double seconds = diff.TotalSeconds;
If the purpose is finding the number of seconds between two dates, you'd be much better off using the TimeSpan object.
TimeSpan span = date2 - date1;
double seconds = span.TotalSeconds;
See suggestion from thread below:
How do I convert ticks to minutes?
TimeSpan.FromTicks(DateTime.Now.Ticks).TotalSeconds;
Assuming you really need to get at the seconds for the datetime object, you could directly get the "Ticks" property from it. These aren't in seconds but you can easily divide by the proper factor to convert the Ticks to seconds.
See: http://msdn.microsoft.com/en-us/library/system.datetime.ticks.aspx
So, something like:
DateTime.Now.Ticks/TimeSpan.TicksPerSecond
If you want to compare 2 DateTime object, why just not use the provided operators?
http://msdn.microsoft.com/en-us/library/aa326723%28v=VS.71%29.aspx
DateTime a, b;
if (a > b) //a is after b
I would use the TimeSpan class to get the exact difference between two DateTime instances. Here is an example:
DateTime dt1 = DateTime.Now;
DateTime dt2 = new DateTime(2003,4,15);
TimeSpan ts = dt1.Subtract(dt2);
Once the TimeSpan value (ts, in the code snippet above) is available, you can examine its values to correctly convert the TimeSpan to a given number of seconds.
Using a TimeSpan to get the elapsed time between two DateTimes is probably the best way to go but if you really want to get the number of seconds for a given DateTime you could do something like the following:
DateTime dateTimeToConvert = DateTime.Now;
TimeSpan tsElapsed = dateTimeToConvert - DateTime.MinValue;
return tsElapsed.TotalSeconds;
Note that tsElapsed.TotalSeconds is a Double, not an Int.
Do note that the goal is to get the number of seconds since DateTime.MinVal (the first day of the calendar). I say this, because I see all of these answers for "you do time comparisons like this... add in the object, multiply by that object and do cross-calculus on them, divide by the quotient of the summed result, and Boom! not what you asked."
There's a really simple answer here. Ticks are 100-nanosecond increments. DateTime object.Ticks is the number of ticks that have occurred since 1/1/0001. Ie, year zero. There are 10 million nanoseconds in a second. so...
public static long convertDateTimeToSeconds(DateTime dateTimeToConvert) {
// According to Wikipedia, there are 10,000,000 ticks in a second, and Now.Ticks is the span since 1/1/0001.
long NumSeconds= dateTimeToConvert.Ticks / 10000000;
return NumSeconds;
}

Categories