DateTime.Now within a statement - c#

In the below thisIsAlwaysTrue should always be true.
DateTime d = DateTime.Now;
bool thisIsAlwaysTrue = d == d;
But does DateTime.Now work in such a way that isThisAlwaysTrue is guaranteed to be true? Or can the clock change between references to the Now property?
bool isThisAlwaysTrue = DateTime.Now == DateTime.Now;

The clock can definitely change between two back-to-back calls to DateTime.Now;

The DateTime.Now property is volatile, meaning it definitely can change between uses. But the variable you assign it to is not volatile.
So this should always set result to true:
DateTime d = DateTime.Now;
bool result = d == d;
It assigns the value returned by DateTime.Now to the d variable, not the property itself. Thus d will always equal d in that code.
But this will not always set result to true:
bool result = DateTime.Now == DateTime.Now;

I would have to recommend you try this for yourself. This code takes a fraction of second in the Release build:
using System;
class Program {
static void Main(string[] args) {
while (DateTime.UtcNow == DateTime.UtcNow) ;
Console.WriteLine("oops");
Console.ReadLine();
}
}
I trust it will repro well.

DateTime is immutable, so it will never ever change once assigned. Your call to DateTime.Now doesn't "link" them - it just assigns whatever value DateTime.Now is at the time of calling to the variable d - it will not assign some sort of reference.
So if you have a delay like this:
DateTime d = DateTime.Now; // Let's assume it's 9:05:10
Thread.Sleep(100);
Console.WriteLine(d); // will still be 9:05:10, even though it's much later now

Related

DateTime substracting days doesn't work

I am using the following code in order to substract a day of the DateTime until I am getting Monday:
DateTime currentWeek = new DateTime(beginDate.Year, beginDate.Month, beginDate.Day);
while (currentWeek.DayOfWeek.ToString() != "Monday")
{
currentWeek.AddDays(-1);
MessageBox.Show(currentWeek.Day.ToString());
MessageBox.Show(currentWeek.DayOfWeek.ToString());
}
beginDate is in the first run set to the current Date of DateTime.Now.
For me this loops forever, and the day of currentWeek always stays the same (29) even though I am substracting 1 everytime I am looping through.
I am already using another function that takes a DateTime and a bool Parameter, which does pretty much the same and works:
private void ErstenTagDerWocheAuswaehlen(DateTime date, bool anfangDerWoche = true)
{
string wochentagName;
int incrementor;
if(anfangDerWoche == true)
{
wochentagName = "Monday";
incrementor = -1;
}
else
{
wochentagName = "Friday";
incrementor = 1;
}
while(date.DayOfWeek.ToString() != wochentagName)
{
date = date.AddDays(incrementor);
}
}
Can someone explain to me why the upper code doesn't work whilst the lower one does?
You have to assign the resulting value, DateTime is immutable.
currentWeek = currentWeek.AddDays(-1);
About your 2nd question:
Use the enum for day of the week, do not try to convert a day of the week to a string for a comparison. The type is DayOfWeek.
Again, a DateTime is not mutable so you have to return a DateTime instance as you can't mutate the one that was passed in (without passing it as ref)
Code change
private DateTime ErstenTagDerWocheAuswaehlen(DateTime date, bool anfangDerWoche = true)
{
System.DayOfWeek wochentagName;
int incrementor;
if(anfangDerWoche == true)
{
wochentagName = System.DayOfWeek.Monday;
incrementor = -1;
}
else
{
wochentagName = System.DayOfWeek.Friday;
incrementor = 1;
}
while(date.DayOfWeek != wochentagName)
{
date = date.AddDays(incrementor);
}
return date;
}
DateTime is an immutable struct, so you need to store the value returned from AddDays():
var t2 = currentWeek.AddDays(-1);
Then use t2. The call to AddDays() doesn't actually change currentWeek.
As DateTime is immutable, when using the AddDays it returns a new DateTime structure with the new information and does not change the given one.
Method documentation states:
Returns a new System.DateTime that adds the specified number of days to the value of this instance.
You must assign it to a variable:
currentWeek = currentWeek.AddDays(-1);

Increment DateTime Variable

I'm trying to create a loop where my date increments by 1 month while it's in the for loop. Currently It's only displaying today's date. And is not incrementing. I want to change the display date to selected display date instead of today/default
for (int i = 1; i <= 15; i++)
{
DateTime initialdate = InitialDate.DisplayDate;
InitialDate.DisplayDate.AddMonths(1);
initialdate = InitialDate.DisplayDate;
}
I didn't show any of the initialdate being used because I don't think it's necessary.
InitialDate is a DateTimePicker
Initialization of the Datepicker
<DatePicker x:Name="InitialDate"></DatePicker>
Problem : You need to assign the return value of the InitialDate.DisplayDate.AddMonths(1).
From MSDN: DateTime.AddMonths()
Returns a new DateTime that adds the specified number of months to the
value of this instance.
Replace This:
InitialDate.DisplayDate.AddMonths(1);
With This:
InitialDate.DisplayDate = InitialDate.DisplayDate.AddMonths(1);
DateTime.AddMonths doesn't change the value you call it on - it returns a new value. This is true of all the DateTime methods. There's nothing which changes the value in place, which is a good job as it's a value type and changes would be lost anyway if they were made to a copy of the variable (e.g. due to being called on the value returned by a property).
You want:
InitialDate.DisplayDate = InitialDate.DisplayDate.AddMonths(1);
Assuming you use initialdate in the rest of the body of the loop, it would be clearer if you just declared it after the increment:
for (int i = 1; i <= 15; i++)
{
InitialDate.DisplayDate = InitialDate.DisplayDate.AddMonths(1);
DateTime initialDate = InitialDate.DisplayDate;
// Use initialDate here
}
(I've renamed the variable to have a capital D for the sake of convention.)
do this:
DateTime initialdate = InitialDate.DisplayDate.AddMonth(1);
You problem stems from the fact that InitialDate.DisplayDate.AddMonths(1); returns a new DateTime rather than modifying the instance it's being called on. You do nothing with the return value emitted by that call. Instead you want;
InitialDate.DisplayDate = InitialDate.DisplayDate.AddMonths(1);
Just FYI you will see this a lot in C#. I would say more often than not, methods that would change the values of an object return a new instance rather than mutating the instance they're called on.

Property or indexer 'System.DateTime.TimeOfDay' cannot be assigned to — it is read only

I saw lots of duplicate post of this But for me it's something different.
I have a Datetime object and get time portion & assign another time to that.When i'm going to assign it it raise those error.
in here newStartDateGroup is a DateTime Object
in here OpenTime is a TimeSpan
Property or indexer cannot be assigned to — it is read only
else if(newStartDateGroup.TimeOfDay < i.OpenTime && newEndDateGroup.TimeOfDay > i.CloseTime) // < >
{
newStartDateGroup.TimeOfDay = i.OpenTime;
DateTime struct in .NET is immutable, so instead of changing it's values you have to create new one:
newStartDateGroup = newStartDateGroup.Date.Add(i.OpenTime);
You can only create new DateTime instances.
According to your shown code, you want to set only the day time.
This should do it:
newStartDateGroup = DateTime.Today.Add(i.OpenTime);
DateTime.Today is today at 00:00.
Just assign the hours, minutes and seconds manually.
DateTime temp = DateTime(newStartDateGroup.Year, newStartDateGroup.Month, newStartDateGroup.Day, i.OpenTime.Hours, i.OpenTime.Minutes, i.OpenTime.Seconds);
newStartDateGroup = temp;

Compare datetime get different result

I need to compare two dates including the seconds. I searched the web and got two methods. One is import Microsoft.VisualBasic dll. The result is not same when it runs the same data. I think C# should do the same thing without import VisualBasic. Can someone point the way to me to made it work in C#?
Thanks in advance.
There is one using Microsoft.VisualBasic
if (Math.Abs(DateAndTime.DateDiff(DateInterval.Second,
Conversions.ToDate(colFilesFound[RuntimeHelpers.GetObjectValue(rw["file_path"])]),
Conversions.ToDate(rw["last_modified_timestamp"]),
FirstDayOfWeek.Sunday, FirstWeekOfYear.Jan1)) == 0L)
{
unchangedFileNum++;
Console.WriteLine("unchange");
}
else
{
modifiedFileNum++;
Console.WriteLine("change");
}
There is another method not using Visual.dll:
DateTime fileLastModifiedDate = Conversions.ToDate(colFilesFound[rw["file_path"]]);
DateTime dataLastModifiedDate = Conversions.ToDate(rw["last_modified_timestamp"]);
if (Math.Abs((fileLastModifiedDate - dataLastModifiedDate).TotalSeconds) == 0L)
{
Console.WriteLine("File Date: " + colFilesFound[rw["file_path"]] +
" <> Database Date: " + Conversions.ToString(rw["last_modified_timestamp"]));
unchangedFileNum++;
Console.WriteLine("unchange");
}
else
{
modifiedFileNum++;
Console.WriteLine("change");
}
The correct way to compare DateTimes in .NET is using the == operator or calling the DateTime.Compare() method:
DateTime fileLastModifiedDate = ...;
DateTime dataLastModifiedDate = ...;
if (fileLastModifiedDate == dataLastModifiedDate)
{
...
}
You need to take into account the precission. Sometimes, you cannot have enough precission to consider milliseconds. In this case you need to compare the dates without having into account the milliseconds:
public static bool IsSameDateWithoutMilliseconds(DateTime d1, DateTime d2)
{
return d1.Subtract(d2).TotalSeconds == 0;
}
Your problem is probably the milliseconds since those are probably not equal the way you check the DateTimes.
DateTime fileLastModifiedDate = Conversions.ToDate(colFilesFound[rw["file_path"]]);
DateTime dataLastModifiedDate = Conversions.ToDate(rw["last_modified_timestamp"]);
fileLastModifiedDate = fileLastModifiedDate.AddMilliseconds(-fileLastModifiedDate.Millisecond);
dataLastModifiedDate = dataLastModifiedDate.AddMilliseconds(-dataLastModifiedDate.Millisecond);
if (DateTime.Compare(fileLastModifiedDate, dataLastModifiedDate) == 0)
{
// dates are equal
}
else
{
// dates are not equal
}

C# Correct way to change DateTime value?

Is is possible to change the value returned by DateTime? Or at least assign it to a variable then change that variable?
internal int hour;
internal int minute;
DateTime time = DateTime.Now;
public int incrementHour(int step)
{
if (step > 0 && hour < 24)
{
//step = step % hour;
hour = (hour + step) % 24;
time.AddHours(hour);
return hour;
}//end of if
else
{
MessageBox.Show("Please enter a positive number.");
return 0;
}//end of else
}//end of incrementHour
Addhours doesn't really do anything from the looks of it.
Instances of DateTime are immutable - AddHours() returns a new instance of DateTime that reflects the changed value - so you have to re-assign the changed value to your time variable:
time = time.AddHours(hour);
MSDN for AddHours method (applies to all other methods of DateTime as well):
This method does not change the value
of this DateTime. Instead, it returns
a new DateTime whose value is the
result of this operation. The Kind
property of the returned DateTime
object is the same as that of value.
all you need to do is
time = time.AddHours(hour)
and that will be it
See documentation of DateTime.AddHours, it does not change the parameter value but returns a new DateTime instance. Try:
time = time.AddHours(hour);

Categories

Resources