I want to compare the two dateTimePickers in the winforms using C#.
My comparing code is as below;
if (dtpFromDate.Value > dtpToDate.Value)
{
MessageBox.Show("From Date is greater than To Date");
return;
}
Below are the values of the two dateTimePickers
dtpFromDate.Value = 10/29/2016 5:10:27 PM
dtpToDate.Value = 10/29/2016 5:10:27 PM
But if the two dateTimePickers are set to be at their initial values (i.e. today's date) as above, the if statement got also true, but what I need is to check only if the dates are greater (FromDate>ToDate). Am I doing something wrong?
If you do not care the time, do that:
if (dtpFromDate.Value.Date > dtpToDate.Value.Date)
{
MessageBox.Show("From Date is greater than To Date");
return;
}
To be explicit here, the data type of dtpFromDate.Value is of DateTime. I always prefer to use DateTime.Tick property for DateTime comparisons, since it is an integral type, so the comparison is obvious to the reader and also fast.
I believe when the two different DateTimePicker controls are created, they differ in their values by less than a second, causing the issue. If your intention is to simply compare the DateTime with a least count of second, then you can do this
if ((dtpFromDate.Value.Ticks / TimeSpan.TicksPerSecond) >
(dtpToDate.Value.Ticks / TimeSpan.TicksPerSecond))
{
MessageBox.Show("From Date is greater than To Date");
return;
}
The DateTime object has a least count of a Tick. You can read up on DateTime.Ticks and TimeSpan on MSDN
A single tick represents one hundred nanoseconds or one ten-millionth
of a second. There are 10,000 ticks in a millisecond, or 10 million
ticks in a second.
I had two date time pickers on the same windows form. Even though I was making a comparison of dtpStartDate.Value.Date and dtpEndDate.Value.Date, the check for the end date being earlier than the start date was still coming up wrong when it appeared that the two date time picker values were the same. It wasn't until I compared the values down to the millisecond like dtpEndDate.Value.ToString("MM/dd/yyyy HH:mm:ss.fff") and dtpStartDate.Value.ToString("MM/dd/yyyy HH:mm:ss.fff") that I saw the difference.
In my case I wanted to only compare month, day and year. What I had to do to make a proper comparison was use
if (dtpStartDate.Value.Date.Date > dtpEndDate.Value.Date.Date)
{
// Start Date cannot be later than the End Date
}
Related
I receive a date like 1.01.2022 h:00, m:00, s:00, ms: 00
What is the best approach to get the date at the end of the day, something like: 01.01.2022 h:23, m:59, s:59, ms: 999?
I tried those 2 ways:
var endOfDay = new TimeSpan(0, 23, 59, 59, 999);
time = time.Add(endOfDay);
and
time = time.AddDays(1).AddMilliseconds(-1);
This removes all doubt down to the resolution of a single tick. In the code below, assume that dateAndTime could include a non-zero time component.
dateAndTime.Date.AddDays(1).AddTicks(-1);
This
ensures we are only working with a date that has no time component as our reference point/date
moves us to the next date at midnight
subtracts a single tick, bringing us back to our reference date with a full-resolution time component (you could do milliseconds if you prefer, just know it's less resolution).
While this works, it's generally better to consider an alternate design that doesn't rely on a time component at all (e.g. use a given date at midnight on the next day to act as a virtual end-of-day for the given reference date).
If you want just to print out the range, the action format is opinion based. If you, however, want to check if some time is within or without the day, please do it as (note >= and <)
if (timeOfQuestion >= day.Date && timeOfQuestion < day.Date.AddDays(1)) {
...
}
Using onstructions like endOfDays = time.AddDays(1).AddMilliseconds(-1) is dangerous:
please, note that day.Date.AddMilliseconds(999.5) - double value - should be within the day.
When I search about maximum time. people always answering that from VS debugger. which is 23:59:59.9999999
As I need 12 AM in 24 formats. I guess it will be 00:00:00 but...
C# .NET assume the following:
var xx = DateTime.MaxValue.ToString("HH:mm:ss.fffffff");
When debugging previous it will print 23:59:59.9999999
What should I use? does it matter? what's the difference?
Should use 00:00:00 ? or 23:59:59.9999999 Specially when
saving Time in SQL-Server.
The big problem or I mean un-good behavior for end-user when you convert 24 formats to 12 Hour format via hh:mm:ss it will show 11:59:59 PM it will be ugly isn't it? it should be 12:00:00 AM.
After All, Obsidian Age answered this well depending on the use case.
It depends on perspective:
var xx = DateTime.MaxValue.ToString("HH:mm:ss.fffffff");
var xy = DateTime.MinValue.ToString("HH:mm:ss.fffffff");
Gives
23:59:59.9999999
00:00:00.0000000
So, one is the end of the day and the other is the beginning of the day.
There's an interesting novel called 'The time between midnight'
DateTime.MaxValue is exactly that - the maximum value that DateTime can represent; that is to say, the 'last' point in a day. Conversely, the .Date property makes use of 00:00:00 by default, as it has no notion of time (unless specified).
If you have an event that occurs at exactly midnight, I would recommend storing it as 00:00:00, as the event occurs at midnight, and you want to accurately represent that.
Ultimately, it really depends on your desired use case as to which one you want to use. Do you want to state that the event occurs on day 1's evening, or day 2's beginning? That is what it boils down to, although in the vast majority of cases such a delineation makes no difference. In this case you would want to opt for both the accuracy and 'ease' of 00:00:00.
programmatically speaking, you can do both. the only difference between them (in code) is this :
// using 00:00:00 will require you to add 1 day to the end date in order to count as full day
if(time >= "2019-12-03 00:00:00" && time < "2019-12-04 00:00:00")
//using 23:59:59 will not require you to add 1 day to the end date.
if(time >= "2019-12-03 00:00:00" && time <= "2019-12-03 23:59:59")
so, basically, if you use 23:59:59 there is a one second off the grid, if any record has been stored in this second, it'll not be included in the results. while the second one will include it.
Which one to use ? surely the 00:00:00 if you want to be more precise, however, I've not seen any difference in the results in my projects as I've used both of them in different projects. But I'm sure there are some projects needs to include every micro second as this microsecond could change the result's curve (such as analytics or deep learning ..etc).
In SQL Server, don't save the time as string, save it with the correct datatype (DateTime, TimeSpan ..etc). SQL Server will reads the time perfectly fine when you pass a correspond time datatype from your application.
A few things:
The maximum value that a DateTime in C# can represent is 9999-12-31 23:59:59.9999999. In SQL Server, this corresponds to a datetime2, which has the same maximum value.
The time type in SQL Server also has a maximum value of 23:59:59.9999999 (though note that a C# TimeSpan can be much larger because it primarily represents duration instead of time of day).
If you are storing just a time range using the time type, you'll need that 23:59:59.9999999 value for the end of the day. You can get this quickly in C# with DateTime.MaxValue.TimeOfDay. Indeed it will be one tick less than a true 24:00.
There are 7 decimals of nines because that is the precision offered by the data type. If you choose a lower precision, there is some small (but not impossible) chance that a given value could fall after it. Thus when you use this technique, always align the nines with the full precision of the data type. (Don't just subtract one second or one millisecond.)
When calculating the difference of a datetime range such as 2020-01-01 00:00 to 2020-01-01 01:00, one can simply subtract the two values to get the result (1 hour in this case). However, when using 23:59:59.99999999, one has to account for the missing tick. This can get messy, and such there is a significant advantage to using 00:00 instead.
As you pointed out, when displaying 23:59:59.9999999 to an end user, you may have to write your own logic to format it as 24:00 or as "end of day", etc.
When comparing datetime ranges, you'll want to use a different operator for the end comparison:
If you use 23:59:59.9999999, use a fully-inclusive range comparison: a <= now && b >= now
If you use 00:00, use a half-open range comparison - inclusive at the start, exclusive at the end: a <= now && b > now
When comparing time-only ranges (i.e. timspan types), the same logic applies, but one also has to consider time ranges that span over midnight:
If you use 23:59:59.9999999:
if (a < b)
result = a <= now && b >= now;
else
result = a <= now || b >= now;
If you use 00:00:
if (a < b)
result = a <= now && b > now;
else
result = a <= now || b > now;
In summary, it is generally simpler to work with 00:00 values instead of 23:59:59.9999999 values, and thus you should prefer 00:00. If you find the need to use 23:59:59.9999999, you should be aware of the coding changes required.
I am setting up a system to gather data from a database based on a user inputted start date and end date. The system will gather data averaged over an interval(1 hour, 6 hours, or one day for example). If the user does not input a start or end date I would like the program to set the start date to the current time minus the interval.
I currently have the user inputting the interval in the following format.
1m = 1 minute
1h = 1 hour
12h = 12 hours
3d = 3 days
So these values are not formatted like datetime. I could take the current datetime and subtract it by either minutes, hours, or days depending on the value appended (splitting on the number), but this would mean many if statements. What I would really like is a method to subtract a datetime by an arbitrary value Does anyone have a better solution?
Instead of providing predefined time intervals (that are implemented e. g. via a separate type/enum), it is much easier to let the user freely specify a TimeSpan.
This has two advantages:
The user is not restricted to predefined intervals
You can subtract the TimeSpan directly from your DateTime.Now
If restriction to limited intervals is a requirement, you can implement this in the view/window. But still this should be a TimeSpan.
What i am doing is that, i need to select a row that i have just recently added through DateTime to get the PK since i need it.
I store the DateTime through:
DateTime nw = DateTime.now and i use nw to search through my table.
My question is that, what if let's say i put 2 rows within a span of 1 minute?
My sql table stores them like this:
Since milliseconds isn't visible, will both of them be selected?(assuming everything happened within 1 minute)
Edit: this is from my asp mvc project. So the DateTime is new everytime my action is run.
The problem is precision. The GetDate() function in TSQL is not at the precision as c# DateTime, as GetDate() returns an TSQL DateTime.
TSQL DateTime:
Defines a date that is combined with a time of day with fractional seconds that is based on a 24-hour clock.
Rounded to increments of .000, .003, or .007 seconds
C# DateTime:
The Ticks property expresses date and time values in units of one ten-millionth of a second, and the Millisecond property returns the thousandths of a second in a date and time value. However, if you are using repeated calls to the DateTime.Now property to measure elapsed time, and you are concerned with small time intervals less than 100 milliseconds, you should note that values returned by the DateTime.Now property are dependent on the system clock, which on Windows 7 and Windows 8 systems has a resolution of approximately 15 milliseconds.
However you could use the newer (avail as of SQL Server 2008) SysDateTime() which returns a datetime2(7) value that should match the precision of C# Datetime.
datetime2(7):
Defines a date that is combined with a time of day that is based on 24-hour clock. datetime2 can be considered as an extension of the existing datetime type that has a larger date range, a larger default fractional precision, and optional user-specified precision.
This only academically interesting because you should never use a datetime as a PK.
Let's say it's Nov 6, 2016 at 1:15AM. You create a record:
MyPk
------
2016-11-06 01:15:00
One hour later you create another record...
MyPk
------
2016-11-06 01:15:00
2016-11-06 01:15:00
Duplicate PKs due to daylight savings. Don't have daylight savings? There are a multitude of reasons to not use DateTime for a PK (simply google search for datetime as primary key).
Just to name a few:
Exact select can be very difficult (milliseconds matter!)
Foreign Keys become a Nightmare
Replication is very difficult unless all systems are in the same timezone
If you really want to use the DateTime.Now with second precision as a way to find the PK of your data, you should not declared it once and use it everywhere. Rather, you should use it like this:
insertDataToDataBase(data, DateTime.Now);
and then 10-20 seconds later
insertDataToDataBase(data, DateTime.Now); //still use DateTime.Now
This way your DateTime.Now will always be updated
I use System.DateTime.Now , but it return like 5/28/2011 1:45:58 AM .(no Milli second precision)
I would like to save current time (or Date time ) with Milli second precision in database .
Update : Sorry , I meant Milli Second
System.DateTime manages precision to the millisecond, 5/28/2011 1:45:58 AM is just how it was formatted to a String.
To format with millisecond included use format string: "d/M/yyyy hh:mm:ss.fff tt"
If you want to store it in a SQL Server database, ADO.Net automatically converts the CLR System.DateTime datatype to a SQL Server datetime datatype (and vice-versa).
The CLR System.DateTime has 100-nanosecond precision (e.g., each tick is 100 nanoseconds; 10,000 ticks per millisecond, 10 million ticks per second.
The SQL Server datetime datatype is precise to (approximately) 3ms.
You shouldn't need to worry about it: ADO.Net will take care of it for you.
OTOH, if you really want to throw away extra nanoseconds, something like this ought to do the trick:
public static DateTime ToExactMillisecondPrecision( DateTime dt )
{
const long TICKS_PER_MILLISECOND = 10000 ;
long totalMilliseconds = dt.Ticks / TICKS_PER_MILLISECOND ;
return new DateTime( totalMilliseconds * TICKS_PER_MILLISECOND ) ;
}
Can't really see the need myself.
Look under the properties list in this link. All the different options are there.
http://msdn.microsoft.com/en-us/library/system.datetime.aspx
Including seconds, milliseconds, and ticks
The string you posted contains seconds, so I suppose you're not asking for second precision, but for more precise timing.
The value of DateTime.Now is returned with more than millisecond precision. it's just that with default formatting, the milliseconds aren't displayed. To display the value with milliseconds, you can either use the o standard format string, or write your own custom format string, that includes the millisecond format specifier fff.
Note that just because the returned value is precise, it doesn't mean it's as much accurate. The actual accuracy is not defined exactly, but tends to be in tens of milliseconds.
It should not be necessary to convert the date to string. Perhaps the real problem is that you using dynamic SQL.