I'm trying to compare a time stamp from an incoming request to a database stored value. SQL Server of course keeps some precision of milliseconds on the time, and when read into a .NET DateTime, it includes those milliseconds. The incoming request to the system, however, does not offer that precision, so I need to simply drop the milliseconds.
I feel like I'm missing something obvious, but I haven't found an elegant way to do it (C#).
The following will work for a DateTime that has fractional milliseconds, and also preserves the Kind property (Local, Utc or Undefined).
DateTime dateTime = ... anything ...
dateTime = new DateTime(
dateTime.Ticks - (dateTime.Ticks % TimeSpan.TicksPerSecond),
dateTime.Kind
);
or the equivalent and shorter:
dateTime = dateTime.AddTicks( - (dateTime.Ticks % TimeSpan.TicksPerSecond));
This could be generalized into an extension method:
public static DateTime Truncate(this DateTime dateTime, TimeSpan timeSpan)
{
if (timeSpan == TimeSpan.Zero) return dateTime; // Or could throw an ArgumentException
if (dateTime == DateTime.MinValue || dateTime == DateTime.MaxValue) return dateTime; // do not modify "guard" values
return dateTime.AddTicks(-(dateTime.Ticks % timeSpan.Ticks));
}
which is used as follows:
dateTime = dateTime.Truncate(TimeSpan.FromMilliseconds(1)); // Truncate to whole ms
dateTime = dateTime.Truncate(TimeSpan.FromSeconds(1)); // Truncate to whole second
dateTime = dateTime.Truncate(TimeSpan.FromMinutes(1)); // Truncate to whole minute
...
var date = DateTime.Now;
date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Kind);
Here is an extension method based on a previous answer that will let you truncate to any resolution...
Usage:
DateTime myDateSansMilliseconds = myDate.Truncate(TimeSpan.TicksPerSecond);
DateTime myDateSansSeconds = myDate.Truncate(TimeSpan.TicksPerMinute)
Class:
public static class DateTimeUtils
{
/// <summary>
/// <para>Truncates a DateTime to a specified resolution.</para>
/// <para>A convenient source for resolution is TimeSpan.TicksPerXXXX constants.</para>
/// </summary>
/// <param name="date">The DateTime object to truncate</param>
/// <param name="resolution">e.g. to round to nearest second, TimeSpan.TicksPerSecond</param>
/// <returns>Truncated DateTime</returns>
public static DateTime Truncate(this DateTime date, long resolution)
{
return new DateTime(date.Ticks - (date.Ticks % resolution), date.Kind);
}
}
DateTime d = DateTime.Now;
d = d.AddMilliseconds(-d.Millisecond);
Sometimes you want to truncate to something calendar-based, like year or month. Here's an extension method that lets you choose any resolution.
public enum DateTimeResolution
{
Year, Month, Day, Hour, Minute, Second, Millisecond, Tick
}
public static DateTime Truncate(this DateTime self, DateTimeResolution resolution = DateTimeResolution.Second)
{
switch (resolution)
{
case DateTimeResolution.Year:
return new DateTime(self.Year, 1, 1, 0, 0, 0, 0, self.Kind);
case DateTimeResolution.Month:
return new DateTime(self.Year, self.Month, 1, 0, 0, 0, self.Kind);
case DateTimeResolution.Day:
return new DateTime(self.Year, self.Month, self.Day, 0, 0, 0, self.Kind);
case DateTimeResolution.Hour:
return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerHour));
case DateTimeResolution.Minute:
return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerMinute));
case DateTimeResolution.Second:
return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerSecond));
case DateTimeResolution.Millisecond:
return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerMillisecond));
case DateTimeResolution.Tick:
return self.AddTicks(0);
default:
throw new ArgumentException("unrecognized resolution", "resolution");
}
}
Instead of dropping the milliseconds then comparing, why not compare the difference?
DateTime x; DateTime y;
bool areEqual = (x-y).TotalSeconds == 0;
or
TimeSpan precision = TimeSpan.FromSeconds(1);
bool areEqual = (x-y).Duration() < precision;
To round down to the second:
dateTime.AddTicks(-dateTime.Ticks % TimeSpan.TicksPerSecond)
Replace with TicksPerMinute to round down to the minute.
If your code is performance sensitive, be cautious about
new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second)
My app was spending 12% of CPU time in System.DateTime.GetDatePart.
Less obvious but more than 2 times faster :
// 10000000 runs
DateTime d = DateTime.Now;
// 484,375ms
d = new DateTime((d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);
// 1296,875ms
d = d.AddMilliseconds(-d.Millisecond);
Not the fastest solution but simple and easy to understand:
DateTime d = DateTime.Now;
d = d.Date.AddHours(d.Hour).AddMinutes(d.Minute).AddSeconds(d.Second)
A way for easy reading is...
//Remove milliseconds
DateTime date = DateTime.Now;
date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss", null);
And more...
//Remove seconds
DateTime date = DateTime.Now;
date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH:mm"), "yyyy-MM-dd HH:mm", null);
//Remove minutes
DateTime date = DateTime.Now;
date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH"), "yyyy-MM-dd HH", null);
//and go on...
I understand that it is easy to understand, but it lacks performance.
Regarding Diadistis response. This worked for me, except I had to use Floor to remove the fractional part of the division before the multiplication. So,
d = new DateTime((d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);
becomes
d = new DateTime(Math.Floor(d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);
I would have expected the division of two Long values to result in a Long, thus removing the decimal part, but it resolves it as a Double leaving the exact same value after the multiplication.
Eppsy
2 Extension methods for the solutions mentioned above
public static bool LiesAfterIgnoringMilliseconds(this DateTime theDate, DateTime compareDate, DateTimeKind kind)
{
DateTime thisDate = new DateTime(theDate.Year, theDate.Month, theDate.Day, theDate.Hour, theDate.Minute, theDate.Second, kind);
compareDate = new DateTime(compareDate.Year, compareDate.Month, compareDate.Day, compareDate.Hour, compareDate.Minute, compareDate.Second, kind);
return thisDate > compareDate;
}
public static bool LiesAfterOrEqualsIgnoringMilliseconds(this DateTime theDate, DateTime compareDate, DateTimeKind kind)
{
DateTime thisDate = new DateTime(theDate.Year, theDate.Month, theDate.Day, theDate.Hour, theDate.Minute, theDate.Second, kind);
compareDate = new DateTime(compareDate.Year, compareDate.Month, compareDate.Day, compareDate.Hour, compareDate.Minute, compareDate.Second, kind);
return thisDate >= compareDate;
}
usage:
bool liesAfter = myObject.DateProperty.LiesAfterOrEqualsIgnoringMilliseconds(startDateTime, DateTimeKind.Utc);
This is my version of the extension methods posted here and in similar questions. This validates the ticks value in an easy to read way and preserves the DateTimeKind of the original DateTime instance. (This has subtle but relevant side effects when storing to a database like MongoDB.)
If the true goal is to truncate a DateTime to a specified value (i.e. Hours/Minutes/Seconds/MS) I recommend implementing this extension method in your code instead. It ensures that you can only truncate to a valid precision and it preserves the important DateTimeKind metadata of your original instance:
public static DateTime Truncate(this DateTime dateTime, long ticks)
{
bool isValid = ticks == TimeSpan.TicksPerDay
|| ticks == TimeSpan.TicksPerHour
|| ticks == TimeSpan.TicksPerMinute
|| ticks == TimeSpan.TicksPerSecond
|| ticks == TimeSpan.TicksPerMillisecond;
// https://stackoverflow.com/questions/21704604/have-datetime-now-return-to-the-nearest-second
return isValid
? DateTime.SpecifyKind(
new DateTime(
dateTime.Ticks - (dateTime.Ticks % ticks)
),
dateTime.Kind
)
: throw new ArgumentException("Invalid ticks value given. Only TimeSpan tick values are allowed.");
}
Then you can use the method like this:
DateTime dateTime = DateTime.UtcNow.Truncate(TimeSpan.TicksPerMillisecond);
dateTime.Kind => DateTimeKind.Utc
DateID.Text = DateTime.Today.ToShortDateString();
Use ToShortDateString() //Date 2-02-2016
Use ToShortDateString() // Time
And By Use Of
ToLongDateString() // its show 19 February 2016.
:P
New Method
String Date = DateTime.Today.ToString("dd-MMM-yyyy");
// define String pass parameter dd-mmm-yyyy return 24-feb-2016
Or shown on textbox
txtDate.Text = DateTime.Today.ToString("dd-MMM-yyyy");
// put on PageonLoad
In my case, I was aiming to save TimeSpan from datetimePicker tool without saving the seconds and the milliseconds, and here is the solution.
First convert the datetimePicker.value to your desired format, which mine is "HH:mm" then convert it back to TimeSpan.
var datetime = datetimepicker1.Value.ToString("HH:mm");
TimeSpan timeSpan = Convert.ToDateTime(datetime).TimeOfDay;
You can simply use Split
new TimeSpan(new DateTime(1970, 1, 1).Ticks).TotalSeconds.ToString().Split('.')[0]
I know the answer is quite late, but the best way to get rid of milliseconds is
var currentDateTime = DateTime.Now.ToString("s");
Try printing the value of the variable, it will show the date time, without milliseconds.
Related
I'm trying to compare a time stamp from an incoming request to a database stored value. SQL Server of course keeps some precision of milliseconds on the time, and when read into a .NET DateTime, it includes those milliseconds. The incoming request to the system, however, does not offer that precision, so I need to simply drop the milliseconds.
I feel like I'm missing something obvious, but I haven't found an elegant way to do it (C#).
The following will work for a DateTime that has fractional milliseconds, and also preserves the Kind property (Local, Utc or Undefined).
DateTime dateTime = ... anything ...
dateTime = new DateTime(
dateTime.Ticks - (dateTime.Ticks % TimeSpan.TicksPerSecond),
dateTime.Kind
);
or the equivalent and shorter:
dateTime = dateTime.AddTicks( - (dateTime.Ticks % TimeSpan.TicksPerSecond));
This could be generalized into an extension method:
public static DateTime Truncate(this DateTime dateTime, TimeSpan timeSpan)
{
if (timeSpan == TimeSpan.Zero) return dateTime; // Or could throw an ArgumentException
if (dateTime == DateTime.MinValue || dateTime == DateTime.MaxValue) return dateTime; // do not modify "guard" values
return dateTime.AddTicks(-(dateTime.Ticks % timeSpan.Ticks));
}
which is used as follows:
dateTime = dateTime.Truncate(TimeSpan.FromMilliseconds(1)); // Truncate to whole ms
dateTime = dateTime.Truncate(TimeSpan.FromSeconds(1)); // Truncate to whole second
dateTime = dateTime.Truncate(TimeSpan.FromMinutes(1)); // Truncate to whole minute
...
var date = DateTime.Now;
date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Kind);
Here is an extension method based on a previous answer that will let you truncate to any resolution...
Usage:
DateTime myDateSansMilliseconds = myDate.Truncate(TimeSpan.TicksPerSecond);
DateTime myDateSansSeconds = myDate.Truncate(TimeSpan.TicksPerMinute)
Class:
public static class DateTimeUtils
{
/// <summary>
/// <para>Truncates a DateTime to a specified resolution.</para>
/// <para>A convenient source for resolution is TimeSpan.TicksPerXXXX constants.</para>
/// </summary>
/// <param name="date">The DateTime object to truncate</param>
/// <param name="resolution">e.g. to round to nearest second, TimeSpan.TicksPerSecond</param>
/// <returns>Truncated DateTime</returns>
public static DateTime Truncate(this DateTime date, long resolution)
{
return new DateTime(date.Ticks - (date.Ticks % resolution), date.Kind);
}
}
DateTime d = DateTime.Now;
d = d.AddMilliseconds(-d.Millisecond);
Sometimes you want to truncate to something calendar-based, like year or month. Here's an extension method that lets you choose any resolution.
public enum DateTimeResolution
{
Year, Month, Day, Hour, Minute, Second, Millisecond, Tick
}
public static DateTime Truncate(this DateTime self, DateTimeResolution resolution = DateTimeResolution.Second)
{
switch (resolution)
{
case DateTimeResolution.Year:
return new DateTime(self.Year, 1, 1, 0, 0, 0, 0, self.Kind);
case DateTimeResolution.Month:
return new DateTime(self.Year, self.Month, 1, 0, 0, 0, self.Kind);
case DateTimeResolution.Day:
return new DateTime(self.Year, self.Month, self.Day, 0, 0, 0, self.Kind);
case DateTimeResolution.Hour:
return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerHour));
case DateTimeResolution.Minute:
return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerMinute));
case DateTimeResolution.Second:
return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerSecond));
case DateTimeResolution.Millisecond:
return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerMillisecond));
case DateTimeResolution.Tick:
return self.AddTicks(0);
default:
throw new ArgumentException("unrecognized resolution", "resolution");
}
}
Instead of dropping the milliseconds then comparing, why not compare the difference?
DateTime x; DateTime y;
bool areEqual = (x-y).TotalSeconds == 0;
or
TimeSpan precision = TimeSpan.FromSeconds(1);
bool areEqual = (x-y).Duration() < precision;
To round down to the second:
dateTime.AddTicks(-dateTime.Ticks % TimeSpan.TicksPerSecond)
Replace with TicksPerMinute to round down to the minute.
If your code is performance sensitive, be cautious about
new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second)
My app was spending 12% of CPU time in System.DateTime.GetDatePart.
Less obvious but more than 2 times faster :
// 10000000 runs
DateTime d = DateTime.Now;
// 484,375ms
d = new DateTime((d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);
// 1296,875ms
d = d.AddMilliseconds(-d.Millisecond);
Not the fastest solution but simple and easy to understand:
DateTime d = DateTime.Now;
d = d.Date.AddHours(d.Hour).AddMinutes(d.Minute).AddSeconds(d.Second)
A way for easy reading is...
//Remove milliseconds
DateTime date = DateTime.Now;
date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss", null);
And more...
//Remove seconds
DateTime date = DateTime.Now;
date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH:mm"), "yyyy-MM-dd HH:mm", null);
//Remove minutes
DateTime date = DateTime.Now;
date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH"), "yyyy-MM-dd HH", null);
//and go on...
I understand that it is easy to understand, but it lacks performance.
Regarding Diadistis response. This worked for me, except I had to use Floor to remove the fractional part of the division before the multiplication. So,
d = new DateTime((d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);
becomes
d = new DateTime(Math.Floor(d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);
I would have expected the division of two Long values to result in a Long, thus removing the decimal part, but it resolves it as a Double leaving the exact same value after the multiplication.
Eppsy
2 Extension methods for the solutions mentioned above
public static bool LiesAfterIgnoringMilliseconds(this DateTime theDate, DateTime compareDate, DateTimeKind kind)
{
DateTime thisDate = new DateTime(theDate.Year, theDate.Month, theDate.Day, theDate.Hour, theDate.Minute, theDate.Second, kind);
compareDate = new DateTime(compareDate.Year, compareDate.Month, compareDate.Day, compareDate.Hour, compareDate.Minute, compareDate.Second, kind);
return thisDate > compareDate;
}
public static bool LiesAfterOrEqualsIgnoringMilliseconds(this DateTime theDate, DateTime compareDate, DateTimeKind kind)
{
DateTime thisDate = new DateTime(theDate.Year, theDate.Month, theDate.Day, theDate.Hour, theDate.Minute, theDate.Second, kind);
compareDate = new DateTime(compareDate.Year, compareDate.Month, compareDate.Day, compareDate.Hour, compareDate.Minute, compareDate.Second, kind);
return thisDate >= compareDate;
}
usage:
bool liesAfter = myObject.DateProperty.LiesAfterOrEqualsIgnoringMilliseconds(startDateTime, DateTimeKind.Utc);
This is my version of the extension methods posted here and in similar questions. This validates the ticks value in an easy to read way and preserves the DateTimeKind of the original DateTime instance. (This has subtle but relevant side effects when storing to a database like MongoDB.)
If the true goal is to truncate a DateTime to a specified value (i.e. Hours/Minutes/Seconds/MS) I recommend implementing this extension method in your code instead. It ensures that you can only truncate to a valid precision and it preserves the important DateTimeKind metadata of your original instance:
public static DateTime Truncate(this DateTime dateTime, long ticks)
{
bool isValid = ticks == TimeSpan.TicksPerDay
|| ticks == TimeSpan.TicksPerHour
|| ticks == TimeSpan.TicksPerMinute
|| ticks == TimeSpan.TicksPerSecond
|| ticks == TimeSpan.TicksPerMillisecond;
// https://stackoverflow.com/questions/21704604/have-datetime-now-return-to-the-nearest-second
return isValid
? DateTime.SpecifyKind(
new DateTime(
dateTime.Ticks - (dateTime.Ticks % ticks)
),
dateTime.Kind
)
: throw new ArgumentException("Invalid ticks value given. Only TimeSpan tick values are allowed.");
}
Then you can use the method like this:
DateTime dateTime = DateTime.UtcNow.Truncate(TimeSpan.TicksPerMillisecond);
dateTime.Kind => DateTimeKind.Utc
DateID.Text = DateTime.Today.ToShortDateString();
Use ToShortDateString() //Date 2-02-2016
Use ToShortDateString() // Time
And By Use Of
ToLongDateString() // its show 19 February 2016.
:P
New Method
String Date = DateTime.Today.ToString("dd-MMM-yyyy");
// define String pass parameter dd-mmm-yyyy return 24-feb-2016
Or shown on textbox
txtDate.Text = DateTime.Today.ToString("dd-MMM-yyyy");
// put on PageonLoad
In my case, I was aiming to save TimeSpan from datetimePicker tool without saving the seconds and the milliseconds, and here is the solution.
First convert the datetimePicker.value to your desired format, which mine is "HH:mm" then convert it back to TimeSpan.
var datetime = datetimepicker1.Value.ToString("HH:mm");
TimeSpan timeSpan = Convert.ToDateTime(datetime).TimeOfDay;
You can simply use Split
new TimeSpan(new DateTime(1970, 1, 1).Ticks).TotalSeconds.ToString().Split('.')[0]
I know the answer is quite late, but the best way to get rid of milliseconds is
var currentDateTime = DateTime.Now.ToString("s");
Try printing the value of the variable, it will show the date time, without milliseconds.
I have a "requirement" to give a timestamp to the nearest second... but NOT more accurate than that. Rounding or truncating the time is fine.
I have come up with this abomination
dateTime = DateTime.Parse(DateTime.UtcNow.ToString("U"));
(U is the Long format date and time. "03 January 2007 17:25:30")
Is there some less horrific way of achieving this?
Edit: So from the linked truncate milliseconds answer (thanks John Odom) I am going to do this
private static DateTime GetCurrentDateTimeNoMilliseconds()
{
var currentTime = DateTime.UtcNow;
return new DateTime(currentTime.Ticks - (currentTime.Ticks % TimeSpan.TicksPerSecond), currentTime.Kind);
}
barely less horrific.. but it does preserve the 'kind' of datetime which I do care about. My solution did not.
You could implement this as an extension method that allows you to trim a given DateTime to a specified accuracy using the underlying Ticks:
public static DateTime Trim(this DateTime date, long ticks) {
return new DateTime(date.Ticks - (date.Ticks % ticks), date.Kind);
}
Then it is easy to trim your date to all kinds of accuracies like so:
DateTime now = DateTime.Now;
DateTime nowTrimmedToSeconds = now.Trim(TimeSpan.TicksPerSecond);
DateTime nowTrimmedToMinutes = now.Trim(TimeSpan.TicksPerMinute);
You can use this constructor:
public DateTime(
int year,
int month,
int day,
int hour,
int minute,
int second
)
so it would be:
DateTime dt = DateTime.Now;
DateTime secondsDt = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
If you really want to round the time to the nearest second, you can use:
DateTime.MinValue
.AddSeconds(Math.Round((DateTime.Now - DateTime.MinValue).TotalSeconds));
However unless that extra half a second really makes a difference, you can just remove the millisecond portion:
DateTime.Now.AddTicks( -1 * (DateTime.Now.Ticks % TimeSpan.TicksPerSecond));
Try this
TimeSpan span= dateTime.Subtract(new DateTime(1970,1,1,0,0,0, DateTimeKind.Utc));
return span.TotalSeconds;
After working with the selected solution I am satisfied that it works well. However the implementations of the extension methods posted here do not offer any validation to ensure the ticks value you pass in is a valid ticks value. They also do not preserve the DateTimeKind of the DateTime object being truncated. (This has subtle but relevant side effects when storing to a database like MongoDB.)
If the true goal is to truncate a DateTime to a specified value (i.e. Hours/Minutes/Seconds/MS) I recommend implementing this extension method in your code instead. It ensures that you can only truncate to a valid precision and it preserves the important DateTimeKind metadata of your original instance:
public static DateTime Truncate(this DateTime dateTime, long ticks)
{
bool isValid = ticks == TimeSpan.TicksPerDay
|| ticks == TimeSpan.TicksPerHour
|| ticks == TimeSpan.TicksPerMinute
|| ticks == TimeSpan.TicksPerSecond
|| ticks == TimeSpan.TicksPerMillisecond;
// https://stackoverflow.com/questions/21704604/have-datetime-now-return-to-the-nearest-second
return isValid
? DateTime.SpecifyKind(
new DateTime(
dateTime.Ticks - (dateTime.Ticks % ticks)
),
dateTime.Kind
)
: throw new ArgumentException("Invalid ticks value given. Only TimeSpan tick values are allowed.");
}
Then you can use the method like this:
DateTime dateTime = DateTime.UtcNow.Truncate(TimeSpan.TicksPerMillisecond);
dateTime.Kind => DateTimeKind.Utc
Here is a rounding method that rounds up or down to the nearest second instead of just trimming:
public static DateTime Round(this DateTime date, long ticks = TimeSpan.TicksPerSecond) {
if (ticks>1)
{
var frac = date.Ticks % ticks;
if (frac != 0)
{
// Rounding is needed..
if (frac*2 >= ticks)
{
// round up
return new DateTime(date.Ticks + ticks - frac);
}
else
{
// round down
return new DateTime(date.Ticks - frac);
}
}
}
return date;
}
It can be used like this:
DateTime now = DateTime.Now;
DateTime nowTrimmedToSeconds = now.Round(TimeSpan.TicksPerSecond);
DateTime nowTrimmedToMinutes = now.Round(TimeSpan.TicksPerMinute);
I need to find the difference in days between two dates.
For example:
Input: **startDate** = 12-31-2012 23hr:59mn:00sec, **endDate** = 01-01-2013 00hr:15mn:00sec
Expected output: 1
I tried the following:
(dt1-dt2).TotalDays and convert to integer but didn't give me appropriate answer as double has to be converted to int - tried Math.Ceiling, Convert.To...
dt1.day - dt2.day does not work across months
dt.Substract() has the same output as option 1 mentioned above.
None of the above worked, so I ended up writing the following code. The code works well, but I feel that there must be a solution with only a couple of lines of code.
public static int GetDifferenceInDaysX(this DateTime startDate, DateTime endDate)
{
//Initializing with 0 as default return value
int difference = 0;
//If either of the dates are not set then return 0 instead of throwing an exception
if (startDate == default(DateTime) | endDate == default(DateTime))
return difference;
//If the dates are same then return 0
if (startDate.ToShortDateString() == endDate.ToShortDateString())
return difference;
//startDate moving towards endDate either with increment or decrement
while (startDate.AddDays(difference).ToShortDateString() != endDate.ToShortDateString())
{
difference = (startDate < endDate) ? ++difference : --difference;
}
return difference;
}
Note: I do not have any performance issue in the while-loop iteration as the max difference will not be more than 30 to 45 days.
Well, it sounds like you want the difference in the number of days, ignoring the time component. A DateTime with the time component reset to 00:00:00 is what the Date property gives you:
(startDate.Date - endDate.Date).TotalDays
If you use the DateTime.Date property this will eliminate the time
date1.Date.Subtract(date2.Date).Days
Use TimeStamp. Just subtract two dates (using DateTime.Date property), get the difference in time span and return TotalDays
TimeSpan ts = endDate.Date - startDate.Date;
double TotalDays = ts.TotalDays;
So your extension method can be as simple as:
public static int GetDifferenceInDaysX(this DateTime startDate, DateTime endDate)
{
return (int) (endDate.Date - startDate.Date).TotalDays;
// to return just a int part of the Total days, you may round it according to your requirement
}
EDIT: Since the question has been edited, you may check the following example.
Consider the following two dates.
DateTime startDate = new DateTime(2012, 12, 31, 23, 59, 00);
DateTime endDate = new DateTime(2013, 01, 01, 00, 15, 00);
You can write the extension method as:
public static int GetDifferenceInDaysX(this DateTime startDate, DateTime endDate)
{
TimeSpan ts = endDate - startDate;
int totalDays = (int) Math.Ceiling(ts.TotalDays);
if (ts.TotalDays < 1 && ts.TotalDays > 0)
totalDays = 1;
else
totalDays = (int) (ts.TotalDays);
return totalDays;
}
For the above dates it will give you 1
The following code crashes and burns and I don't understand why:
DateTime dt = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);
double d = double.Parse("1332958778172");
Console.Write(dt.AddSeconds(d));
Can someone tell me what's going on? I just can't seem to be able to figure out why...
EDIT
This value comes back from the Salesforce REST API and from what I understand it's a Unix epoch time stamp. "The time of token issue, represented as the number of seconds since the Unix epoch (00:00:00 UTC on 1 January 1970)."
SOLUTION
Salesforce REST API is in fact sending milliseconds back for the issued_at field when performing the OAuth request when they say they're sending seconds...
As others have said, the problem is that the value is too large.
Having looked over it, I believe it represents milliseconds since the Unix epoch, not seconds so you want:
DateTime dt = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);
double d = double.Parse("1332958778172"); // Or avoid parsing if possible :)
Console.Write(dt.AddMilliseconds(d));
Either that, or divide by 1000 before calling AddSeconds - but obviously that will lose data.
The value you are adding results in a date outside of the valid range of dates that a DateTime supports.
DateTime supports 01/01/0001 00:00:00 to 31/12/9999 23:59:59.
A simple calculation of 1332958778172/3600/24/365 gives 42267 years.
I think the double value is genuinely too large. It represents just over 42,267 years (if my maths is correct), and DateTime.MaxValue is 23:59:59.9999999, December 31, 9999
DateTime dt = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);
Console.Write(dt.AddSeconds(1332958778172D));
Except that...
1332958778172/60/60/24/365 = 42,267 years... which DateTime can only go up to 23:59:59.9999999, December 31, 9999
I had a similar issue where I was required to add a configurable timespan to a datetime.
If the configuration is not correct I have to assume the 'worst scenario' : MaxValue.
I solved it by implementing an extension to DateTime (still in test phase) :
/// <summary>
/// Removes a timespan from a date, returning MinValue or MaxValue instead of throwing exception when if the resulting date
/// is behind the Min/Max values
/// </summary>
/// <returns></returns>
public static DateTime SafeAdd(this DateTime source, TimeSpan value)
{
// Add or remove ?
if (value.Ticks > 0)
{
// add
var maxTicksToAdd = DateTime.MaxValue - source;
if (value.Ticks > maxTicksToAdd.Ticks)
return DateTime.MaxValue;
}
else
{
var maxTicksToRemove = source - DateTime.MinValue;
// get the value to remove in unsigned representation.
// negating MinValues is impossible because it would result in a value bigger than MaxValue : (-32768 .. 0 .. 32767)
var absValue = value == TimeSpan.MinValue ? TimeSpan.MaxValue : -value;
if (absValue.Ticks > maxTicksToRemove.Ticks)
return DateTime.MinValue;
}
return source + value;
}
Looks like this timestamp is in milliseconds, try below code it should work fine.
DateTime nDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
double epoch = 1585008000000;
DateTime rDate = nDateTime.AddMilliseconds(epoch);
In my case I had to consume an api object as a double and convert the unix time to a DateTime:
DateTime Date = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(Double.Parse("1596225600000"));
I have an instance of DateTime that I get from my database, I want to subtract it from DateTime.Now and find out if 4 hours were passed. How do I do that?
Also when should i use DateTime.UTCNow or DateTimeOffset
You can use the subtraction operator to get a TimeSpan:
private static readonly TimeSpan MinimumTime = TimeSpan.FromHours(4);
...
if ((dateFromDatabase - DateTime.Now) > MinimumTime)
{
...
}
As for whether you need UTCNow or Now... it will depend on what happens to time zones when you fetch the data from the database. DateTime is not terribly clear on this front :(
If you can fetch the value as a DateTimeOffset to start with, then you can use DateTimeOffset.Now instead and it should be simpler to work out any time zone issues.
DateTime.Subtract
First Google hit..
Try this:
bool fourHoursPassed = date.AddHours(4) < DateTime.Now;
or this to actually perform a subtraction:
bool fourHoursPassed = (DateTime.Now - date).TotalHours > 4;
DateTime.Subtract
or
DateTime myDateTime = someValue;
TimeSpan ts = DateTime.Now -myDateTime;
if(ts.Hours>=4)
{
doSomething();
}
Hope it helps.
DateTime dt = new DateTime(2011, 07, 10);
DateTime dob = new DateTime(1987, 07, 10);
You can simply subtract as:
TimeSpan age = dt - dob;