using "if" on a time literal (formatting help) - c#

I have a time object which if null is for some reason interpreted as 00:00:00. So I need to do a test if it is null, but now I can't do that so I need the equivalent of:
if (TimeObject == 00:00:00) {...
What would the format for this if statement be?

First, C# does not support time literals, so 00:00:00 won't make sense to a standard C# compiler.
Second, in order to handle time, you will need to use DateTime or TimeSpan structures.
Third, because these are structures, they can never be null - they have a default value, but will not allow DateTime dt = null; If you want a nullable struct, use Nullable Types (thus DateTime? and TimeSpan?)

Related

Change format of DateTime without converting to string

I'm new in c# and I have Datetime variable like:
DateTime startingDate
value = 8/8/2018 4:16:18 PM
I want value like 8/8/2018, how can I just drop hours minutes seconds and PMvalue without converting to string? because I'm forced DateTime type for another thing.
In C# (as in many other languages) there is no separate Date and Time, it's just DateTime. Regardless of that though, there are many use cases where you only need a date. In C# it's assumed that if you just need 8/8/2018 then in reality you are working with 8/8/2018 0:00:00.000.
If you need to work with just the Date but still keep it as a DateTime, then the most straightfoward method is to use .Date (i.e. startingDate.Date). This can get a little confusing since the default .ToString() for DateTime represents it (in whatever is the cultural norm for your computer) as Month/Day/Year Hour:Minute:Second AM/PM.
Also, for further clarification, DateTime is an object that has a variety of different properties (Year, Month, Day, Hour, Minute, Second etc), so thinking of it having a "format" is incorrect. It's a collection of things that together make up a Date and/or Time.

Convert Zero Datetime vs Allow Zero Datetime

Convert Zero Datetime=true returns DateTime.MinValue while Allow Zero Datetime return MySqlDateTime.
What else differentiate these 2 settings ?
When to use which one?
Can they be used interchangeable ?
What is pro and cons of them ?
You can refer to this point for a little clarification: http://forums.devart.com/viewtopic.php?t=21367
But it all boils down to how you want to handle zero values on DateTime, When you use Allow Zero DateTime it cannot be converted to a DateTime because it doesn't support zero value. If you use Convert Zero DateTime it will use DateTime but it will return the lower value possible for date which is DateTime.MinValue.

why c# disallows to assign SqlDatetime.MinValue to datetime but allows comparison

The following code compiles fine with comparison operator.
If(dateTimeVariable > SqlDateTime.MinValue) //compiles Ok. dateTimeVariable is of type DateTime
{
}
However, the following code fails to compile.
DateTime dateTimeVariable=SqlDateTime.MinValue;
//Throws exception , cannot convert source type SqlDateTime to DateTime. Which is obvious.
My question is why comparison is allowed between SqlDateTime and Datetime types but not assignment. (Unless comparison operators are doing some implicit conversion.)
I'm guessing I must be missing something really basic.
There's an implicit conversion in SqlDateTime that takes care of converting a DateTime to an SqlDateTime without any additional work:
public static implicit operator SqlDateTime(DateTime value)
{
return new SqlDateTime(value);
}
// SqlDateTime mySqlDate = DateTime.Now
What must be happening is that dateTimeVariable is being implicitly converted from a DateTime to an SqlDateTime for the comparison:
if (dateTimeVariable > SqlDateTime.MinValue)
{
// if dateTimeVariable, after conversion to an SqlDateTime, is greater than the
// SqlDateTime.MinValue, this code executes
}
But in the case of the following code, there's nothing that allows you to simply stuff an SqlDateTime into a DateTime variable, so it doesn't allow it.
DateTime dateTimeVariable = SqlDateTime.MinValue; // fails
Cast your initial value and it will compile okay, but there's a chance you're going to lose some valuable information that is part of an SqlDateTime but not a DateTime.
DateTime dateTimeVariable = (DateTime)SqlDateTime.MinValue;
This is a question of potential loss of precision. Usually this occurs in the context of "narrowing" versus "widening".
Integers are a subset of numbers. All integers are numbers, some numbers are not integers. Thus, the type "number" is wider than the type "integer".
You can always assign a type to a wider type without losing information.
Narrowing is another matter. To assign 1.3 to an integer you must lose information. This is possible but the compiler won't perform a narrowing conversion unless you explicitly state that this is what you want.
As a result, assignments that require a widening conversion are automatically and implicitly converted, but narrowing assignments require explicit casting or conversion (not all conversions are simple casting).
Although arguably SqlDateTime is narrower than DateTime differences in representation mean that conversions in both directions are potentially lossy. As a result, to assign a SqlDateTime to a DateTime requires an explicit conversion. Conversion of DateTime to SqlDateTime strictly speaking ought to require explicit conversion but the implicit conversion implemented in the SqlDateTime type (qv Grant's answer) makes SqlDateTime behave as though it were wider. I made the mistake of assuming SqlDateTime was wider because that's how it's behaving in this case and many kudos to commenters for picking out this important subtlety.
This implicit conversion thing is actually a bit of an issue with VARCHAR columns and ADO.NET implicitly typed parameters, because C# strings are Unicode and become NVARCHAR, so comparing them to an indexed column of type VARCHAR will cause a widening conversion to NVARCHAR (the implicit widening conversions thing also occurs in TSQL), which can prevent the use of the index - which won't stop the query from returning the correct results but will cripple performance.
From MSDN
SqlDateTime Structure
Represents the date and time data ranging in value from January 1, 1753 to December 31, 9999 to an accuracy of 3.33 milliseconds to be stored in or retrieved from a database. The SqlDateTime structure has a different underlying data structure from its corresponding .NET Framework type, DateTime, which can represent any time between 12:00:00 AM 1/1/0001 and 11:59:59 PM 12/31/9999, to the accuracy of 100 nanoseconds. SqlDateTime actually stores the relative difference to 00:00:00 AM 1/1/1900. Therefore, a conversion from "00:00:00 AM 1/1/1900" to an integer will return 0.

How to differentiate between DateTime, Date and Time

There are three styles of Date and Time that can go into a DateTime variable; DateTime, Date or Time. I would like to differentiate between them. How can I do so?
I am creating column filtering on a DataGrid. Depending if it is one of the three the filter will display a DateTime picker or a DatePicker or a Time picker.
This classification is not part of the struct. IOW there's no built-in way to do this, so it's up to you to pick the implementation you'd like.
It has been suggested to check if the TotalSeconds == 0, which may satisfy you, imo it's a wonderful solution, but I think it should be used with caution because it is limited. Because what if you want to have a time+date that points to the date when TotalSeconds that really is == 0. This approach will turn this into just a date automatically.
I suggest that if you do not associate this time with a date, choose TimeSpan and make your life so much easier. However I assume this is not the case.
So, if the time really is associated with a date, I suggest you simply make your own type that wraps a DateTime, plus a boolean flag that will answer your question: is it just a date or date+time?.
This is obvious but I simply must say this anyways: if you do take this approach - encapsulate & hide!
If you expose DateTime as a field, an end-user might change the time of a date, expecting it to become date+time, yet the flag will not follow along. So don't just make a wrapper, make your own type that just uses DateTime internally.
There is no absolute way to differentiate. A DateTime always has a date portion and a time portion. If you create a DateTime from just a date then the time portion will be zeroed to midnight, but there is no difference between that and a value that actually represents the stroke of midnight on that date. If you create a DateTime from just a time then the date portion will be equal to #1/01/0001#, but there's no difference between that and a value that actually represents a time on the first day of the new era.
One option is to assume that a DateTime with a non-zero time and a date of #1/01/0001# represents just a time and a value with a zeroed time portion represents just a date. With that in mind, you could add this extension:
public enum DateTimeType
{
Date,
Time,
DateAndTime
}
public static class DateTimeExtensions
{
private static readonly DateTime ZeroDate = new DateTime(1, 1, 1);
public static DateTimeType GetDateTimeType(this DateTime value)
{
if (value.TimeOfDay == TimeSpan.Zero)
{
return DateTimeType.Date;
}
if (value.Date == ZeroDate)
{
return DateTimeType.Time;
}
return DateTimeType.DateAndTime;
}
}
The only way to check if DateTime has a date value is to make it a nullable type.
So something like this:
DateTime? dt;
if(dt.HasValue) {
//has date
if(dt.Value.TimeOfDay.TotalSeconds == 0) {
// display datepicker
} else {
// display timepicker
}
} else {
// show date time picker
}
Other than that, a regular DateTime will always have a date value (if not time value, or both). That is because it's a struct, hence it is not nullable unless you "make" it so (by wrapping in Nullable, which is done either manually (Nullable<DateTime>) or much simpler - by appending ? to the type (DateTime?) as demonstrated above).
If you have an option to go with different datatype (other than DateTime), then I suggest looking at NodaTime (Microsoft should simply build this into CLR and drop their lame DateTime struct).
You can then have 3 nullable properties
LocalDate? Date;
LocalDateTime? DateTime;
LocalTime? Time;
So based on which prop has value, you show the appropriate control. Of course, you also need to set the appropriate property which I'm not sure if you have any control on.

WCF error when converting datetime to json format

I have a WCF service that returns JSON.
Since this morning, I started to get the following error:
DateTime values that are greater than DateTime.MaxValue or smaller than DateTime.MinValue when converted to UTC cannot be serialized to JSON
Just for the test, I passed today's date to all the DateTime variables that are being returned using JSON, but I stil get the same error.
The code is around 2k rows, so I see no value in posting it here.
Any idea how to solve it??
I suspect you have a DateTime value that is uninitialized - defaults to DateTime.MinValue local time. This can not be converted to UTC if your local timezone is ahead of UTC, because doing so would result in a negative Ticks value.
Either find the uninitialized value and correct it, or move to the USA :)
Another solution might be to use a nullable value (DateTime? in place of DateTime).
This defaults to null rather than DateTime.MinValue, so you should be able to serialize an uninitialized value.

Categories

Resources