DateTime comparison, minus certain timeframe? c# - c#

Say I have these two DateTime objects:
var dt1 = new DateTime(1900,12,1,1,1,1);
var dt2 = new DateTime(1900, 12, 1, 1, 59, 1);
Obviously if I do DateTime.Compare(dt1,dt2) the method will return a value indicating they do not equal the same (because of the 59/minute component).
If I only want comparison with precision restricted to a certain value (i.e. same day - dont care about hours/minutes etc) is the best way to do this just to rebuild each datetime object?
I.e.
DateTime.Compare(new DateTime(dt1.Year,dt1.Month,dt1.Day,1,1,1),new DateTime(dt2.Year,dt2.Month,dt2.Day,1,1,1))
or is there a smarter way to do this?

There is already a built in function to get the Date from a DateTime, namely the Date property:
DateTime.Compare(dt1.Date,dt2.Date)
In theory you could compare year, month and day in that order instead of building a new DateTime, but since DateTime is a small struct building it is rather cheap, causes no heap allocations etc. And the code is much more readable.

If you just want the same date, just compare the Date properties:
dt1.Date == dt2.Date
If you need down to the same hour, or up to the same month, you need to use the constructors as you've shown.

The same day is easy - just use the Date property:
dt1.Date.CompareTo(dt2.Date)
For other granularities you would probably need to manually build different values though.

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.

Validation of DateTime against another DateTime

I need to ensure that a DateTime variable named start falls approximately a month after the current date. The only means that I am aware of to do this is to create another DateTime variable that is hard-coded to be precisely one month (or four weeks, preferably) after the current date, and compare the two.
Is there a more efficient way to do this, without creating another object that I will do nothing with?
DateTime start = new DateTime(2015, 12, 25);
if (start > DateTime.UtcNow.AddDays(28))
{
// Do something
}
if 4 weeks is a must, then;
if((start-DateTime.Now).Days>=28)
{
}

why datetime change to 1st Jan in 16 year ago does not show year part properly?

i want to set the date to 1st of Jan 16 years ago from today's date. I used the code
DateTime dtm = new DateTime(DateTime.Today.Year, 1, 1);
dtm.AddYears(-16);
dtpDOB.Value = dtm;// assign value to date time picker
but it shows the date value as 1/1/2014, why this does not set the year part back in 16 years?
thanks
dtm = dtm.AddYears(-16);
Just assign the value
According to the MSDN documentation, .AddYears will return a new DateTime object rather than modifying the existing instance. So change your line to
dtm = dtm.AddYears(-16);
The DateTime type is a struct. Because of that, its properties are immutable (they can't be changed post-constructor). structs are passed by value in C#.
Because of that, as a few other people have said, you need to reassign the value.
dtm = dtm.AddYears(-16);
It's just like a typical string operation in C#. When you call string.Replace(string, string), you need to capture the return value of the operation. The same is true for LINQ-y IEnumerable<T> operations.
Although that said, it seems like you'd be better off to just call the constructor appropriately.
dtpDOB.Value = new DateTime(DateTime.Today.Year - 16, 1, 1);

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.

DateTime.AddDays vs Calendar.AddDays

What is the difference between DateTime.AddDays and Calendar.AddDays?
Is DateTime type calendar independent?
DateTime.AddDays just converts days to ticks and adds this number of ticks to the date time. The default implementation of Calendar.AddDays does exactly the same. However, since it is a virtual method it can be implemented in specific calendar in a more complicated way, e.g. something like here: http://codeblog.jonskeet.uk/2010/12/01/the-joys-of-date-time-arithmetic/
I believe that DateTime is hard-coded to use the Gregorian calendar, effectively.
For example, if you look at DateTime.DaysInMonth it assumes there are 12 months, whereas the HebrewCalendar supports 13.
EDIT: There are some aspects of DateTime which do accommodate other calendars, such as this constructor. However, I believe it just converts it to a Gregorian calendar:
Calendar calendar = new HebrewCalendar();
DateTime dt = new DateTime(5901, 13, 1, 0, 0, 0, calendar); // Uses month 13!
Console.WriteLine(dt.Year); // 2141
Console.WriteLine(dt.Month); // 9
As far as I know the Calendar.AddDays method returns a DateTime object and calls it's function.
The answer to this question is extremely easy to answer. There is no difference between the two functions.
Calendar.AddDays is also a DateTime
DateTime does not extend that particular functionality the only thing it uses is UTC and Local time. One should also suggest that a Calendar is NOT a DateTime object, it might not behave the same, and does not appear to provide a method to get the current system time.
Edit - I originally thought you were talking about the Web Control, this appears to be a globalization, to allow you to display the current date and time for a given user base do their declared operating system's settings.

Categories

Resources