I am trying to get the local datetime with reference to UTC time gap and I am executing this code below.
var dtString =DateTime.UtcNow.ToString(#"yyyy-MM-ddTHH\:mm\:ss.fzzz");
but every time it return me an exception as
Why this exception is there, how to get this fixed?
The z format specifier is used to show the offset between local time and UTC time.
It does not make sense to use it with the UTC time (since it is always 0). That is why you get a warning (thanks to #HansPassant for this remark).
You can either:
Want to print the local time and the offset to the UTC (which is standard):
var dtString = DateTime.Now.ToString(#"yyyy-MM-ddTHH\:mm\:ss.f zzz");
Or want to print the UTC time and the local time zone (which is REALLY not common):
var dtString = DateTime.UtcNow.ToString(#"yyyy-MM-ddTHH\:mm\:ss.f") + " " + DateTime.Now.ToString(#"zzz");
Which is more or less equivalent to your code (as explained in #JeroenMostert link):
var dtString = DateTime.UtcNow.ToString(#"yyyy-MM-ddTHH\:mm\:ss.fzzz");
But the resulting string is not standard at all and lead to misinterpretation.
"2015-02-18T12:08:15.1 +01:00"
Is read as local time and local time zone, not UTC time and local time zone.
Also you can find more information about time zone and good examples here : TimeZone.CurrentTimeZone Property
The full message text will probably answer your question:
This can happen when calling DateTime.ToString using the 'z' format
specifier, which will include a local time zone offset in the output.
In that case, either use the 'Z' format specifier, which designates a
UTC time, or use the 'o' format string, which is the recommended way
to persist a DateTime in text.
Your format string contains the z specifier "yyyy-MM-ddTHH\:mm\:ss.fzzz". Try changing it to "yyyy-MM-ddTHH\:mm\:ss.fZZZ".
Related
In c#, I do this
DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss")
but it gets me the server time. However I also have the offset in this format for example "-04:00". How can I combine the offset to get the local time?
Thanks
If you mean that you want to get the server's system local time including offset, then use the DateTimeOffset.Now property. Then format it as desired.
DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss zzz")
The zzz specifier produces the offset as a string in the ISO 8601 extended format, that you asked for.
If what you mean is you have a UTC offset from elsewhere and you want to apply it to the current UTC time from the server, then do the following instead:
TimeSpan offset = TimeSpan.Parse("-04:00");
DateTimeOffset now = DateTimeOffset.UtcNow.ToOffset(offset);
string result = now.ToString("yyyy-MM-dd HH:mm:ss zzz");
This takes the current server time, and applies the ToOffset function to adjust to the offset you provided.
Do keep in mind though that an offset is not the same as a time zone. The offset you have might be the one for the current date and time, or it might be for some other date and time in that time zone. For example, US Eastern Time is UTC-4 during daylight saving time, but UTC-5 during standard time. See "Time Zone != Offset" in the timezone tag wiki.
This worked.
DateTime.UtcNow.AddHours(DateTimeOffset.Parse("01/01/0001 00:00:00 -04:00").Offset.TotalHours).ToString("yyyy-dd-M--HH-mm-ss")
This should work
DateTime.UtcNow.AddHours(DateTimeOffset.Parse("01/01/0001 00:00:00 -04:00").Offset.TotalHours).ToString("yyyy-dd-M--HH-mm-ss",CultureInfo. InvariantCulture);
Need to add the directive
using System.Globalization;
We are developing a C# application for a web-service client. This will run on Windows XP PC's.
One of the fields returned by the web service is a DateTime field. The server returns a field in GMT format i.e. with a "Z" at the end.
However, we found that .NET seems to do some kind of implicit conversion and the time was always 12 hours out.
The following code sample resolves this to some extent in that the 12 hour difference has gone but it makes no allowance for NZ daylight saving.
CultureInfo ci = new CultureInfo("en-NZ");
string date = "Web service date".ToString("R", ci);
DateTime convertedDate = DateTime.Parse(date);
As per this date site:
UTC/GMT Offset
Standard time zone: UTC/GMT +12 hours
Daylight saving time: +1 hour
Current time zone offset: UTC/GMT +13 hours
How do we adjust for the extra hour? Can this be done programmatically or is this some kind of setting on the PC's?
For strings such as 2012-09-19 01:27:30.000, DateTime.Parse cannot tell what time zone the date and time are from.
DateTime has a Kind property, which can have one of three time zone options:
Unspecified
Local
Utc
NOTE If you are wishing to represent a date/time other than UTC or your local time zone, then you should use DateTimeOffset.
So for the code in your question:
DateTime convertedDate = DateTime.Parse(dateStr);
var kind = convertedDate.Kind; // will equal DateTimeKind.Unspecified
You say you know what kind it is, so tell it.
DateTime convertedDate = DateTime.SpecifyKind(
DateTime.Parse(dateStr),
DateTimeKind.Utc);
var kind = convertedDate.Kind; // will equal DateTimeKind.Utc
Now, once the system knows its in UTC time, you can just call ToLocalTime:
DateTime dt = convertedDate.ToLocalTime();
This will give you the result you require.
I'd look into using the System.TimeZoneInfo class if you are in .NET 3.5. See http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx. This should take into account the daylight savings changes correctly.
// Coordinated Universal Time string from
// DateTime.Now.ToUniversalTime().ToString("u");
string date = "2009-02-25 16:13:00Z";
// Local .NET timeZone.
DateTime localDateTime = DateTime.Parse(date);
DateTime utcDateTime = localDateTime.ToUniversalTime();
// ID from:
// "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Time Zone"
// See http://msdn.microsoft.com/en-us/library/system.timezoneinfo.id.aspx
string nzTimeZoneKey = "New Zealand Standard Time";
TimeZoneInfo nzTimeZone = TimeZoneInfo.FindSystemTimeZoneById(nzTimeZoneKey);
DateTime nzDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, nzTimeZone);
TimeZone.CurrentTimeZone.ToLocalTime(date);
DateTime objects have the Kind of Unspecified by default, which for the purposes of ToLocalTime is assumed to be UTC.
To get the local time of an Unspecified DateTime object, you therefore just need to do this:
convertedDate.ToLocalTime();
The step of changing the Kind of the DateTime from Unspecified to UTC is unnecessary. Unspecified is assumed to be UTC for the purposes of ToLocalTime: http://msdn.microsoft.com/en-us/library/system.datetime.tolocaltime.aspx
I know this is an older question, but I ran into a similar situation, and I wanted to share what I had found for future searchers, possibly including myself :).
DateTime.Parse() can be tricky -- see here for example.
If the DateTime is coming from a Web service or some other source with a known format, you might want to consider something like
DateTime.ParseExact(dateString,
"MM/dd/yyyy HH:mm:ss",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal)
or, even better,
DateTime.TryParseExact(...)
The AssumeUniversal flag tells the parser that the date/time is already UTC; the combination of AssumeUniversal and AdjustToUniversal tells it not to convert the result to "local" time, which it will try to do by default. (I personally try to deal exclusively with UTC in the business / application / service layer(s) anyway. But bypassing the conversion to local time also speeds things up -- by 50% or more in my tests, see below.)
Here's what we were doing before:
DateTime.Parse(dateString, new CultureInfo("en-US"))
We had profiled the app and found that the DateTime.Parse represented a significant percentage of CPU usage. (Incidentally, the CultureInfo constructor was not a significant contributor to CPU usage.)
So I set up a console app to parse a date/time string 10000 times in a variety of ways. Bottom line:
Parse() 10 sec
ParseExact() (converting to local) 20-45 ms
ParseExact() (not converting to local) 10-15 ms
... and yes, the results for Parse() are in seconds, whereas the others are in milliseconds.
I'd just like to add a general note of caution.
If all you are doing is getting the current time from the computer's internal clock to put a date/time on the display or a report, then all is well. But if you are saving the date/time information for later reference or are computing date/times, beware!
Let's say you determine that a cruise ship arrived in Honolulu on 20 Dec 2007 at 15:00 UTC. And you want to know what local time that was.
1. There are probably at least three 'locals' involved. Local may mean Honolulu, or it may mean where your computer is located, or it may mean the location where your customer is located.
2. If you use the built-in functions to do the conversion, it will probably be wrong. This is because daylight savings time is (probably) currently in effect on your computer, but was NOT in effect in December. But Windows does not know this... all it has is one flag to determine if daylight savings time is currently in effect. And if it is currently in effect, then it will happily add an hour even to a date in December.
3. Daylight savings time is implemented differently (or not at all) in various political subdivisions. Don't think that just because your country changes on a specific date, that other countries will too.
#TimeZoneInfo.ConvertTimeFromUtc(timeUtc, TimeZoneInfo.Local)
Don't forget if you already have a DateTime object and are not sure if it's UTC or Local, it's easy enough to use the methods on the object directly:
DateTime convertedDate = DateTime.Parse(date);
DateTime localDate = convertedDate.ToLocalTime();
How do we adjust for the extra hour?
Unless specified .net will use the local pc settings. I'd have a read of: http://msdn.microsoft.com/en-us/library/system.globalization.daylighttime.aspx
By the looks the code might look something like:
DaylightTime daylight = TimeZone.CurrentTimeZone.GetDaylightChanges( year );
And as mentioned above double check what timezone setting your server is on. There are articles on the net for how to safely affect the changes in IIS.
In answer to Dana's suggestion:
The code sample now looks like:
string date = "Web service date"..ToString("R", ci);
DateTime convertedDate = DateTime.Parse(date);
DateTime dt = TimeZone.CurrentTimeZone.ToLocalTime(convertedDate);
The original date was 20/08/08; the kind was UTC.
Both "convertedDate" and "dt" are the same:
21/08/08 10:00:26; the kind was local
I had the problem with it being in a data set being pushed across the wire (webservice to client) that it would automatically change because the DataColumn's DateType field was set to local. Make sure you check what the DateType is if your pushing DataSets across.
If you don't want it to change, set it to Unspecified
I came across this question as I was having a problem with the UTC dates you get back through the twitter API (created_at field on a status); I need to convert them to DateTime. None of the answers/ code samples in the answers on this page were sufficient to stop me getting a "String was not recognized as a valid DateTime" error (but it's the closest I have got to finding the correct answer on SO)
Posting this link here in case this helps someone else - the answer I needed was found on this blog post: http://www.wduffy.co.uk/blog/parsing-dates-when-aspnets-datetimeparse-doesnt-work/ - basically use DateTime.ParseExact with a format string instead of DateTime.Parse
This code block uses universal time to convert current DateTime object then converts it back to local DateTime. Works perfect for me I hope it helps!
CreatedDate.ToUniversalTime().ToLocalTime();
When writing DateTime values to a text file, I have to make sure the used timezone is always UTC +01:00. The format is then yyyy-MM-ddTHH:mm:sszzz, with the zzz part always equaling +01:00. This means that, in case the DateTime value is not in UTC +01:00, a conversion needs to happen before writing the output.
What would be the best way to go about this?
From the documentation:
With DateTime values, the "zzz" custom format specifier represents the signed offset of the local operating system's time zone from UTC, measured in hours and minutes. It does not reflect the value of an instance's System.DateTime.Kind property. For this reason, the "zzz" format specifier is not recommended for use with DateTime values.
Instead, either use DateTimeOffset values (in which "zzz" does what you think it should), or if you continue to use DateTime values then use the "K" specifier.
For example, on my computer (which is in the US Pacific time zone):
DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:sszzz") // "2017-06-21T14:57:17-07:00"
DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssK") // "2017-06-21T14:57:17Z"
DateTimeOffset.UtcNow.ToString("yyyy-MM-ddTHH:mm:sszzz") // "2017-06-21T14:57:17+00:00"
On line 1, even though the time is the UTC time, the offset is incorrectly showing local time.
On line 2, the K specifier picks up on the UTC kind and properly gives a Z in the result.
On line 3, the zero offset is properly conveyed by the zzz specifier.
Related: https://stackoverflow.com/a/31223893/634824
Using:
DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:sszzz")
Will result in an error.
Please try this instead:
DateTime.**Now**.ToString("yyyy-MM-ddTHH:mm:sszzz")
I have two DateTime variables. Each has a timezone stored in the variable so that when I ToString with format including zzz I get a string including +01:00.
At design time I do not know what the timezones will be and I am expecting the variables to have different timezones from each other.
I want to compare the two DateTime values so that I know which is more recent.
For example, if variable A is 2015-07-04T02:00:00+03:00 and variable B is 2015-07-03T18:00:00-07:00 then B > A.
What do I write in C# to tell me this? (I would prefer not to use a third party library.)
(To the SO question-closing zealots: I have spent several hours investigating this using Google, MSDN and SO and am confused. I cannot find a very similar question to this on SO. I am confident that answers to this question will help others.)
You said:
I have two DateTime variables. Each has a timezone stored in the variable so that when I ToString with format including zzz I get a string including +01:00.
This is a common misunderstanding. DateTime doesn't have a time zone stored in the variable. It only has a Kind property, which is of type DateTimeKind, and can be either Utc, Local, or Unspecified.
When calling ToString, the zzz format specifier uses the Kind property to determine which offset to display.
When the Kind is DateTimeKind.Utc, the offset is always +00:00.
When the Kind is DateTimeKind.Local, the offset is determined from the local time zone on the computer where the code is executing. For example, my computer is set to US Pacific time, so the offset will be either -08:00 or -07:00 depending on whether daylight saving time is in effect or not.
When the Kind is DateTimeKind.Unspecified, the behavior is the same as if it were Local. Keep in mind that other methods treat Unspecified in different ways - this is just the particular behavior of the zzz specifier.
MSDN actually says:
For this reason, the "zzz" format specifier is not recommended for use with DateTime values.
Going back to your question:
At design time I do not know what the timezones will be and I am expecting the variables to have different timezones from each other.
Then you cannot use DateTime. You should instead use DateTimeOffset, as it retains a specific time zone offset instead of using a DateTimeKind.
For example, if variable A is 2015-07-04T02:00:00+03:00 and variable B is 2015-07-03T18:00:00-07:00 then B > A. What do I write in C# to tell me this?
DateTimeOffset a = DateTimeOffset.Parse("2015-07-04T02:00:00+03:00");
DateTimeOffset b = DateTimeOffset.Parse("2015-07-03T18:00:00-07:00");
bool result = b > a; // true
See also: DateTime vs DatetimeOffset
Furthermore
As Gustav pointed out, you can use just DateTime, as long as you convert back to universal time before comparing. This works due to DateTime's hidden fourth state (more here). The state is set properly during parsing, and is taken into account when ToUniversalTime is called. Then comparison has valid UTC times to operate from.
DateTime A = DateTime.Parse("2015-11-01T01:00:00-07:00");
DateTime B = DateTime.Parse("2015-11-01T01:00:00-08:00");
Console.WriteLine(A.ToUniversalTime().ToString("'A: 'yyyy'-'MM'-'dd hh:mm:ss"));
Console.WriteLine(B.ToUniversalTime().ToString("'B: 'yyyy'-'MM'-'dd hh:mm:ss"));
Console.WriteLine( B.ToUniversalTime() > A.ToUniversalTime() );
Console.WriteLine( B > A );
And the result:
A: 2015-11-01 08:00:00
B: 2015-11-01 09:00:00
True
False
If your local time zone is set to Pacific Time, you'll get the above results. However, if it's set to something else - it's possible you will get True for the last result, because the values may have been parsed to different local times in your time zone, even though they'd be the same local time in the Pacific time zone.
Using DateTimeOffset is still simpler, going through less conversions, and not being affected by the local time zone.
Did you try this?
var A = DateTime.Parse("2015-07-04T02:00:00+03:00");
var B = DateTime.Parse("2015-07-03T18:00:00-07:00");
Console.WriteLine( B > A );
I've string (variable is fileDate) with Date values in the following format:
2/12/2011 11:58 AM
Now I want to convert this to a date and then to UTC time based as I've problems in comparing dates in different machines, so *I always want to convert all strings (which are getting compared) to Utc_date values.*
I tried this code below but it did not work as I'm not able to convert the above string to Datetime based (as it does not have seconds).
DateTime date = Convert.ToDateTime(fileDate);
date = DateTime.SpecifyKind(date, DateTimeKind.Utc);
fileDate = date.ToString("MM/dd/yyyy hh:mm tt");
Above did not work showing FormatException.
Can you pl help?
To start with, I'd suggest using DateTime.ParseExact or TryParseExact - it's not clear to me whether your sample is meant to be December 2nd or February 12th. Specifying the format may well remove your FormatException.
The next problem is working out which time zone you want to convert it with - are you saying that 11:58 is a local time in some time zone, or it's already a UTC time?
If it's a local time in the time zone of the code which is running this, you can use DateTimeStyles.AssumeLocal | DateTimeStyles.AdjustToUniversal to do it as part of parsing.
If it's already a universal time, use DateTimeStyles.AssumeUniversal
If it's a local time in a different time zone, you'll need to use TimeZoneInfo to perform the conversion.
Also, if it's a local time you'll need to consider two corner cases (assuming you're using a time zone which observes daylight saving time):
A local time may be skipped due to DST transitions, when the clocks go forward. So if the clocks skip from 1am to 2am, then 1:30am doesn't exist at all.
A local time may be ambiguous due to DST transitions, when the clocks go back. So if the clocks go back from 2am to 1am, then 1:30am occurs twice at different UTC times - which occurrence are you interested in?
You should decide how you want to handle these cases, and make sure they're covered in your unit tests.
Another option is to use my date and time library, Noda Time, which separates the concepts of "local date/time" and "date/time in a particular time zone" (and others) more explicitly.
you should be using DateTime.ParseExact to get the value into a proper DateTime instance, and then you can use .ToUniversalTime() to get the UTC time (this would be with respect to the difference of time as in your server machine)
you can use :
DateTime.Now.ToUniversalTime();
i don't mean to say to you should use "DateTime.Now" but you get the point that as a part of the DateTime object you have a method to transform it to Universal time
http://msdn.microsoft.com/en-us/library/system.datetime.touniversaltime.aspx