I have a windows service that runs every night between 3am and 5am. When the job runs the following happens:
var endDate = DateTime.Today.ToUniversalTime(); // Set to midnight
var startDate = endDate.AddDays(-1);
The query that runs at night says something like (All dates are currently stored as UTC):
SELECT * FROM Table WHERE CreatedAt BETWEEN startDate AND endDate
This works just fine, it basically grabs all the data from the previous day when the job runs. I am now developing a UI part to this where a user clicks a button to see the data count that will be processed at night.
The problem I am running into is when a user is at work during normal business hours and clicks that button the counts will be off by 1 day. The count will only display correctly if the local time is after 8pm EST (server is located on the east coast) since that will be after midnight in UTC time.
I tried to solve this with something like:
var now = DateTime.Now;
var midnight = DateTime.Today.ToUniversalTime();
var endDate = (now.Day == midnight.Day) ? midnight.AddDays(1) : midnight;
var startDate = endDate.AddDays(-1);
But this is incorrect as it will only work during some parts of the day. If the button is clicked after midnight local time it would be off by one day again.
Is there any clever way to use the DateTime object to solve this problem?
You can translate the local time to UTC in your UI; or just use DateTime.UtcNow. You have to be careful with ToUniversalTime as it only works if the DateTime you call it on has Kind==DateTimeKind.Local:
var localTimeUtc = TimeZoneInfo.ConvertTimeToUtc(
DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local));
//or (much easier)
var localTimeUtc = DateTime.UtcNow;
And then:
var utcMidnight = localTimeUtc.Date;
var yesterdayUtcMidnight = midnight.AddDays(-1);
now utcMidnight and yesterdayUtcMidnight will cover all of 'yesterday' in UTC time.
On a second note - is your windows service meant to process data from yesterday UTC or yesterday local? If the times in the database are UTC, then your service code should work - but if they've gone in as local time (perhaps with a default GetDate()?) then your code for processing won't work.
Related
I want to add posted date of product to database. I am using DateTime.UtcNow but it shows wrong date if date is wrong on computer. How can I solve this problem?
I have "prodpostDate" column in the "product" table and its type is nvarchar.
DateTime aDate = DateTime.UtcNow;
item.prodpostDate= aDate.ToString("dddd, dd MMMM yyyy");
_context.Products.Add(item);
The date is not wrong. The date is exactly what it should be. When you call Now functions, it pulls the date and time from the computer that executes the code. If the date is wrong on the computer, you need to update it/change the timezone.
Expanding on the comment below:
If you want the date and time regardless of a users local settings, you cannot get the date time from their local machine which is what happens if you call a Now function from code ran on the client. You need to make a call to a different source to get it. If you are using an API, you could make a call to it from your client to get the current date and time. Even better than that, if you end up sending a request to the server for an update, just don't send a date time and let the server get it and populate it. Or if you are doing a database update, let the database get the date time on update/insert.
I am having an issue with creating a contract from a custom workflow activity. The contract takes it's activeon date from a field in a related entity. The time portion of the date is removed before being set as the activeon date for the contract. This seems to work as expected but the code is creating wonky dates for the contract. Does anyone have any experience with this?
DateTime startDate;
DateTime endDate;
Anh_home home = <<Get record from service>>;
startDate = home.Anh_ActualPossessionDate.GetValueOrDefault().Date;
endDate = startDate.AddYears(contractDuration).Date.AddSeconds(-1);
newContract = new Contract()
{
Title = contractName,
anhwp_Home = home.ToEntityReference(),
CustomerId = home.Anh_CompanyId,
ActiveOn = startDate,
ExpiresOn = endDate,
BillingCustomerId = home.Anh_CompanyId,
BillingStartOn = startDate,
BillingEndOn = endDate,
ContractTemplateId = dataContext.ContractTemplateSet.FirstOrDefault(x => x.Abbreviation == "HWC").ToEntityReference()
};
newContract.Id = service.Create(newContract);
Below is the results of a query on the filtered views. It seems like the activeon date is setting the activeonutc field but my understanding is that CRM handles the conversion to UTC based on the users settings.
Thanks.
So I have stumbled upon the answer to my question on this great blog post https://community.dynamics.com/crm/b/develop1/archive/2011/12/06/dynamics-crm-datetimes-the-last-word.
It seems that when you retrieve data from CRM via the SDK the date is always sent as UTC but you can send data either as local time or UTC. The issue I was having is that I was treating the date retrieved from the other entity as local time when it was really UTC. So when I saved my new contract CRM was correctly taking the UTC time I provided and converting it to local time.
To fix this issue I simply made a call to the .ToLocalTime() method of the DateTime object of the retrieved record.
I need a time from different location. My server resides in the US but I need time from Australia.
when I save records in database, I use DateTime.Now() C# function. Is there a way I can get and save Australian time even though the server where my website is hosted is in US?
If there is any database solution then that will be ok too. I am using sql server
This is how you get your local time now:
DateTime yourLocalTime = DateTime.Now;
You can get current UTC time with DateTime.UtcNow or by converting local time to UTC time:
DateTime utcTime = DateTime.UtcNow;
DateTime utcTime = yourLocalTime.ToUniversalTime();
Save this time to database instead of saving some local time. How to get your local time from UTC time:
DateTime yourLocalTime = utcTime.ToLocalTime();
How to get time in other time zone:
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
DateTime tokyoLocalTime = TimeZoneInfo.ConvertTimeFromUtc(utcTime, timeZone);
I'm battling with my model for storing dates in a web application used in different time zones. At the moment, all dates are stored in UTC dates. So, lets say I am allowing the user to save a Transaction date, and a field on the screen is "Transaction Date". I default it to DateTime.UTCNow. SQL Server is in the United States, and I am in Australia.
So, what I have done now, is when I present the default transaction date, I add the GMT Offset to the UTC Now date:
var usersCurrentDate = DateTime.UtcNow.AddSeconds(GmtOffset.Value);
Where GmtOffset is a value in seconds, difference from GMT.
This code works - the user get's presented with the current date/time in their zone.
My issue is - how I should store this. Going to the UI, I do the above conversion. Should I then have a converted on the way to the database that converts the date entered by the user, back into UTC date/time?
In that case, I am always sure that all dates in the database are UTC dates. And then when ever I get the data from the database, I need to remember to translate into Local time? So, have a function that takes a Local time (As entered by the user) and converts it to the UTC?
Something like:
public DateTime UserDateToUTC(DateTime userDate)
{
return DateTime.UtcNow.AddSeconds(GmtOffset.Value * -1);
}
Is this an acceptable pattern?
How can i change the UTC time to local time.
I have this code,
DateTime dt = booking.CreateDateTime.Value;
where CreationDateTime is in the form of UTC.
When ever i change the time to local time on client side, it is 7 hours faster then the local time.
Any body has Idea on this.
This is how i am changing it to local time.
var localTime = TimeZone.CurrentTimeZone.ToLocalTime(dt);
When booking is made, sever side code for datetime is
booking.CreateDateTime = DateTime.UtcNow;
There are really only two things that could be wrong:
The UTC date is not really UTC.
The machine on which this is running is not set to the right time zone.
It looks like .net is assuming the date is in local time. In the following code, dt1 and dt3 are both the same as dt. One solution would be to to use TimeZone.CurrentTimeZone.GetUtcOffset and do the calculation yourself.
dt = Now
dt1 = TimeZone.CurrentTimeZone.ToLocalTime(dt)
dt2 = TimeZone.CurrentTimeZone.ToUniversalTime(dt)
dt3 = dt.ToLocalTime
dt4 = dt.ToUniversalTime