Calculate hour difference between given date and current date in C# - c#

I want to check to see how many hours difference there are between a given date and the current date. I'm looking for a date that's less then 24 hours away!
I thought this would work but it's giving me a true statement when the EventDateTime is Sunday which is greater then 24 hours out!
bool lessThen24Hours = (spaceEvent.EventDateTime - DateTime.Now).Hours < 24 ? true : false;

you want the TotalHours property rather than Hours:
bool lessThen24Hours = (spaceEvent.EventDateTime - DateTime.Now).TotalHours < 24;

Try (spaceEvent.EventDateTime - DateTime.Now).TotalHours.
It gives you all the hours distance between two dates

Use .TotalHours
(spaceEvent.EventDateTime - DateTime.Now).TotalHours < 24
put that inside Math.Abs() if you want the proximity of 24 hour regardless which time is first
Use DateTimeOffset instead of DateTime so that time zones don't mess up your math.

Related

Comparing the binary representation of DateTime in C#

I have a DateTime represented as long (8 bytes), that came from DateTime.ToBinary(), let's call it dateTimeBin. Is there an optimal way of dropping the Time information (I only care for the date) so I can compare it to a start of day? Lets say we have this sample value as a start of day.
DateTime startOfDay = new DateTime(2020,3,4,0,0,0);
long startOfDayBin = startOfDay.ToBinary();
I obviously know I can always convert to a DateTime object then get the date component. However, this operation is going to happen billions of times and every little performance tweak helps.
Is there an efficient way of extracting the Date info of dateTimeBin without converting it to DateTime? Or any arithmetic operation on the long that will return the date only?
Is there a way to match startOfDay (or startOfDayBin) and dateTimeBin if they have the same date components?
Is there a way to see if (dateTimeBin >= startOfDayBin), I don't think the long comparison is valid.
N.B. all the dates are UTC
Since you are working only with UTC dates - makes sense to use DateTime.Ticks instead of DateTime.ToBinary, because former has relatively clear meaning - number of ticks since epoch, just like the unix time, the only difference is unix time interval is second and not tick (where tick is 1/10.000.000 of a second), and epoch is midnight January 1st of 0001 year and not year 1970. While ToBinary only promises that you can restore original DateTime value back and that's it.
With ticks it's easy to extract time and date. To extract time, you need to remainder of division of ticks by number of ticks in a full day, so
long binTicks = myDateTime.Ticks;
long ticksInDay = 24L * 60 * 60 * 10_000_000;
long time = binTicks % ticksInDay;
You can then use convert that to TimeSpan:
var ts = TimeSpan.FromTicks(time);
for convenience, or use as is. The same with extracting only date: just substract time
long date = binTicks - (binTicks % ticksInDay);
Regular comparision (dateTimeBin >= startOfDayBin) in also valid for tick values.

How to Convert DateTime.Now in 0 to 1 decimal format in c#

I would like to convert the current time to a decimal representing a fraction of the day. For example, if the day starts at 0, then 12:00 PM should be 0.5.
I need to send that value to an API, and it needs to be in that format. i.e.
"LAST_PRINT_TIME":0.22020833"
Depending on the precision requirements of your result, this may help you:
DateTime now = DateTime.Now;
double dayFraction = (now.Hour + now.Minute / 60d) / 24d;
now.Minute / 60d calculates the fraction of the current hour (so if the time is XX:15 PM this will give 0.25). This is then added to the current hour. This value is then divided by 24 to obtain the final result.
For example, 3:45 PM would go as follows:
(15 + 45 / 60) / 24) => (15 + 0.75) / 24 => 15.75 / 24 => 0.65625
So 3:45 PM, which is 15.75 hours into the day, would be 0.65625 (or 65.625%) of the day.
Or, as #madreflection mentioned in a comment, you could use .ToOADate() as well. In this case, you could do something like:
DateTime now = DateTime.Now;
double dayFraction = now.ToOADate() - now.Date.ToOADate();
This is one of those problems that seems deceptively simple, but the solution is actually much more complex than you would think.
The complexities arise from the nature of local time, whose rules are defined by time zones. Many time zones have transitions that occur either regularly (such as for daylight saving time), or irregularly (such as for changes in standard time).
As such, one needs to consider:
Could the day be shorter or longer than 24 hours?
For example, in most of the US the start of DST is at 2:00 AM, and on that day there are 23 hours in the day because the hour from 2:00 to 2:59 is skipped. At the end of DST, also at 2:00 AM in the US, the hour from 1:00 through 1:59 is repeated, creating 25 hours in that day.
Could the day start or stop at a time other than midnight?
For example, in most of Chile in 2019, the start of DST made the date 2019-09-08 start at 01:00 instead of 00:00.
Learn more in Falsehoods programmers believe about time.
Consider using the following approach to overcome these real-world considerations.
First, define some helper functions to do most of the work. They are not specific to a particular point in time or a particular time zone.
static double GetFractionOfDay(DateTimeOffset dto, TimeZoneInfo tz)
{
// Get the start of the day, and the start of the next day
DateTimeOffset startOfDay = GetStartOfDay(dto, tz);
DateTimeOffset startOfNextDay = GetStartOfDay(startOfDay.AddDays(1), tz);
// Calculate the length of the day. It might not be 24 hours!
TimeSpan lengthOfDay = startOfNextDay - startOfDay;
// Now calculate the position within the day, and the fraction to return
TimeSpan durationSinceStartOfDay = dto - startOfDay;
return durationSinceStartOfDay / lengthOfDay;
}
static DateTimeOffset GetStartOfDay(DateTimeOffset dto, TimeZoneInfo tz)
{
// Make sure we're in the correct time zone
dto = TimeZoneInfo.ConvertTime(dto, tz);
// Start by assuming a local midnight exists
DateTime dt = dto.Date;
// Handle days without a local midnight (these do exist in several time zones)
if (tz.IsInvalidTime(dt))
{
// Advance by the transition gap. This is usually 1 hour, but best not to hard-code that.
TimeSpan[] offsets = { tz.GetUtcOffset(dt.AddDays(-1)), tz.GetUtcOffset(dt.AddDays(1)) };
TimeSpan gap = offsets[1] - offsets[0];
return new DateTimeOffset(dt.Add(gap), offsets[1]);
}
// Handle days with more than one midnight (it's possible, even if unlikely)
if (tz.IsAmbiguousTime(dt))
{
// There's more than one. Prefer the first one, since we want the beginning of the day.
TimeSpan[] offsets = tz.GetAmbiguousTimeOffsets(dt);
TimeSpan offset = offsets[0] > offsets[1] ? offsets[0] : offsets[1];
return new DateTimeOffset(dt, offset);
}
// Clean case, just one local midnight and it does exist
return new DateTimeOffset(dt, tz.GetUtcOffset(dt));
}
With those defined, you can now get an answer to your question with regard to "now" in the local time zone.
double dayFraction = GetFractionOfDay(DateTimeOffset.Now, TimeZoneInfo.Local);
However - Though this is the correct answer of "what fraction of the day is it", keep in mind it may be more important to align with what the receiving API expects, even if not exactly correct. In other words, if 12:00 should always be 0.5, even when it's not exactly at the midpoint of the day, then use elmer007's approach.

Comparing datetimes in eval to hours

I've got a datetime and I want to check if there is 24 hours difference between those two. I just don't know how to do that.
So far I've got this:
<%# (DateTime.Now - Convert.ToDateTime(Eval("new_date"))) < 24 ? "Today" : Eval("new_date") %>
It does not work tho :<
#Edit
And this is how datetime in my database looks like for example:
2016-09-18 12:26:14
The difference between 2 DateTimes is a TimeSpan, which has a TotalDays property you could compare to 1..
The result oft subtracting two DateTime values is a TimeSpan which has properties for hours, minutes, etc.
If you've got two DateTime values you can check whether the difference between them is less than 24 hours like this:
(DateTime.Now - otherDateTime).TotalHours < 24

Get Hours and Minutes from Datetime

Out Time :
2013-03-08 15:00:00.000
In Time :
2013-03-08 11:21:03.290
I need to get Hours and Minutes separately for same date from above, when (Out Time - In Time).
How can I do that ?
I think you probably just want:
TimeSpan difference = outTime - inTime;
int hours = (int) difference.TotalHours;
int minutes = difference.Minutes;
Note that Minutes will give you "just the minutes (never more than 59)" whereas TotalHours (truncated towards zero) will give you "the total number of hours" which might be more than 23 if the times are more than a day apart.
You should also consider what you want to do if the values are negative - either consider it, or explicitly rule it out by validating against it.
The Subtract method on the DateTime class will allow you subtract that date from the other date.
It will give you a TimeSpan which will be the difference.
I'll leave it to you to work out the actual code.
http://msdn.microsoft.com/en-GB/library/8ysw4sby.aspx
You can use Hours property and Minutes
link : http://msdn.microsoft.com/en-us/library/system.datetime.hour.aspx

How to calculate the number of months between two DateTimes?

Requirements:
Calculate the number of months
between two dates: receiveDate and
dueDate.
Both optimistic and pessimistic
calculations are needed
Assumptions:
dueDate will always be the last day of the month.
I've already figured out the pessimistic calculation (meaning a single day overdue counts as a whole month:
if(receiveDate > dueDate)
receiveDate.Month - dueDate.Month + (receiveDate.Year - dueDate.Year) * 12;
Doing a search on the internet turned up several similar examples to confirm this.
Now my instincts tell me the optimistic calculation will just be the same minus one month but for some reason it just doesn't feel right. Am I on the right track or am I missing something?
You're right; if you're looking for the number of complete months between the two dates, subtracting 1 (assuming the receiveDate doesn't fall on the last day of the month, in which case you will have a remainder of 0 days either way) will get you your answer.
If you don't need to keep days of month in your calculus I think it's the way to go.
Your formula calculates the number of months between the first of the receivedDate's month to the first of the dueDate's month. As most time elements in TimeSpan are expressed as TotalXXX, it seems weird that they left out a TotalMonths and a TotalYears.
I think it's because there aren't a fixed number of days from month to month, so it's hard to know what makes most sense in terms of how to express the fractional remainder.
My formula is this...
int nMonthDiff_FirstToFirst = DateTime.Now.Month - testDate.Month + ((DateTime.Now.Year - testDate.Year)* 12);
double dMonthDiff = (double)nMonthDiff_FirstToFirst + (DateTime.Now - testDate.AddMonths(nMonthDiff_FirstToFirst)).TotalDays / (double)DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month);
So what I'm doing is basically getting the month difference like you are (first of the month to first of the month) then I project my testDate into the future by the month difference. Then with that TimeSpan I get the TotalDays and divide that by the number of days in that month. Thus I'm representing the fractional portion in terms of remaining days of the month.
So if you were going May 5st 2012 -> June 3rd 2012, your formula would return 1 for month difference when a full month hasn't passed yet. In my formula the TotalDays of the projected date would yield a negative fractional number of days, and when added to the 'first to first' month difference, it would take it in as needed.
I am doing this extra check to get precise amount of months:
numberOfMonths = receiveDate.Month - dueDate.Month + (receiveDate.Year - dueDate.Year) * 12;
if (receiveDate.Day > dueDate.Day) numberOfMonths--;
int GetMonthsCount(DateTime dtStart, DateTime dtEnd)
{
return (int)Math.Round((dtEnd - dtStart).TotalMonths);
}

Categories