Increment DateTime Variable - c#

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.

Related

Is this AddMonths(number) a valid way of adding month in C#?

I know you can add months using AddMonths(number), but I was debugging code that doesn't assign the AddMonths(number) to a DateTime variable directly.
var dat = new DateTime(2015, 12, 31);
//I am sure this will add 6 months
dat = dat.AddMonths(6);
//I am not sure what this code does
dat.AddMonths(6);
Is the last sentence incorrect? I think it does nothing, but I am not sure.
If so, I want to understand why it does nothing and why is not marked as incorrect code in Visual Studio.
In .NET fiddle, it does nothing.
If you check the definition of the AddMonths methods, you will find the following:
public DateTime AddMonths (int months);
which means that the method is returning a new DateTime with added months.
The second call is just calling the AddMonths on the returned DateTime and you don't use the new returned value that's why it seems like nothing happened, so there is nothing invalid.
Try to run the below code, I think it will make everything more clear
using System;
public class Program
{
public static void Main()
{
var dat = new DateTime(2015, 12, 31);
//I am sure this will add 6 months
dat = dat.AddMonths(6);
Console.WriteLine(dat);
Console.WriteLine(dat.AddMonths(6));
Console.WriteLine(dat);
}
}
As a conclusion I will add that it doesn't make sense to call the DateTime.AddMonths(x) method without working with the returned value as it is not changing the DateTime that you are passing to it.
There are two line of code in the question: one with an assignment and one without. This line:
dat.AddMonths(6);
with no assignment, still creates a brand new DateTime value for six months after the existing dat value, just like the other line with the assignment. But then it throws the new DateTime value away. The value is returned from the method, but there's nothing waiting to receive it.

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;

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);

DateTime.Now within a statement

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

Checking if Var from LINQ query is Null and returning values older than x

Hello everyone I'm currently having 2 issues with the code below:
Upon return of result1 I'm trying to complete a check to see if it is != null and if it is't it will begin to delete the records selected. The issue is that even when result1 returns nothing and defaults the if statement doesn't pick this up so I guess I'm missing something but what?
I'm wishing to return only values which are over 10 mintues old (this will later be scaled to 12 hours) to do this I'm checking against a.DateTime which is a DateTime value stored in a database. However if i use the <= or >= operators it doesn't work so again what am I missing?
DateTime dateTime = DateTime.Now.Subtract(new TimeSpan(0, 0, 10, 0));
var result1 = (from a in cpuInfo
where a.DateTime <= dateTime
select a).DefaultIfEmpty(null);
if (result1 != null)
{
foreach (TblCPUInfo record1 in result1)
{
localDB.TblCPUInfo.DeleteOnSubmit(record1);
localDB.SubmitChanges();
}
}
Philippe has talked about the sequence side of things - although you don't even need the call to Any(). After all, if there are no changes the loop just won't do anything.
Do you really want to submit the changes on each iteration? It would probably make more sense to do this once at the end. Additionally, you can use DateTime.AddMinutes to make the initial "10 minutes ago" simpler, and if you're only filtering by a Where clause I'd use dot notation.
After all these changes (and making the variable names more useful), the code would look like this:
DateTime tenMinutesAgo = DateTime.Now.AddMinutes(-10);
var entriesToDelete = cpuInfo.Where(entry => entry.DateTime <= tenMinutesAgo);
foreach (var entry in entriesToDelete)
{
localDB.TblCPUInfo.DeleteOnSubmit(entry);
}
localDB.SubmitChanges();
Now, as for why <= isn't working for you... is it possible that you need the UTC time instead of the local time? For example:
DateTime tenMinutesAgo = DateTime.UtcNow.AddMinutes(-10);
If that still isn't working, I suggest you have a look at the generated query and play with it in a SQL tool (e.g. Enterprise Manager or SQL Server Management Studio) to work out why it's not returning any results.
DefaultIfEmpty will return a single item with the content you provided, so in your case a collection with a single value "null".
You should check for elements in the collection using the Any() extension method. In your case:
DateTime dateTime = DateTime.Now.Subtract(new TimeSpan(0, 0, 10, 0));
var result1 = from a in cpuInfo
where a.DateTime <= dateTime
select a;
if (result1.Any())
{
foreach (TblCPUInfo record1 in result1)
{
localDB.TblCPUInfo.DeleteOnSubmit(record1);
localDB.SubmitChanges();
}
}
But if this is really your code, you can skip the Any() check completely, because the foreach loop will not run if there are no elements in result1.

Categories

Resources