Parse Date Time from US Time zone to Datetime. - c#

How to parse below date time string?
2014-01-17T09:59:24.000Z
I tried below code but its, not working.
DateTime.ParseExact("2014-01-17T09:59:24.000Z", "ddd MMM dd HH:mm:ss %zzzz yyyy", CultureInfo.InvariantCulture);

With a string like "2014-01-17T09:59:24.000Z"
You can just use DateTime.Parse("2014-01-17T09:59:24.000Z")
From The Documentation:
The string to be parsed can take any of the following forms:
A string that includes time zone information and conforms to ISO 8601. In the following examples, the first string designates Coordinated Universal Time (UTC), and the second string designates the time in a time zone that's seven hours earlier than UTC:
2008-11-01T19:35:00.0000000Z
2008-11-01T19:35:00.0000000-07:00

From DateTime.ParseExact
Converts the specified string representation of a date and time to its
DateTime equivalent using the specified format and culture-specific
format information. The format of the string representation must match
the specified format exactly.
Clearly your string representation and format is not the same.
You can use it like;
var date = DateTime.ParseExact("2014-01-17T09:59:24.000Z",
"yyyy-MM-dd'T'HH:mm:ss.fff'Z'",
CultureInfo.InvariantCulture);
Console.WriteLine(date);
Output will be;
1/17/2014 9:59:24 AM
Here a demonstration.
For more information, take a look at;
Custom Date and Time Format Strings

The value you have, 2014-01-17T09:59:24.000Z is an ISO8601/RFC3339 formatted timestamp. The Z at the end is significant, which means that it represents UTC.
You have two options to correctly parse it:
You could parse it to a DateTime that has DateTimeKind.Utc for it's .Kind property:
DateTime dt = DateTime.ParseExact("2014-01-17T09:59:24.000Z",
"yyyy-MM-dd'T'HH:mm:ss.fffK",
CultureInfo.InvariantCulture,
DateTimeStyles.RoundtripKind);
Or, you could parse it to a DateTimeOffset, where UTC will correspond to an offset of zero:
DateTimeOffset dt = DateTimeOffset.ParseExact("2014-01-17T09:59:24.000Z",
"yyyy-MM-dd'T'HH:mm:ss.fffK",
CultureInfo.InvariantCulture);
Some of the other answers here are close, but are forgetting to actually consider the Z in your string, using the K specifier and the DateTimeStyles.RoundtripKind parameter. These are important, for without them you will likely end up with a resulting DateTime that has DateTimeKind.Unspecified, which could get treated as local time in certain time zone conversion functions. If you use either of the options I gave you, then the meaning of the Z is preserved.

Related

Error while Converting specific date time to Sydney date using c# code

Using below code I am trying to convert specific date time to Sydney date time.
string datetime = "20200424-04:09:42.145";
datetime = datetime.Replace("-", " ").Insert(4, "-").Insert(7, "-");
TimeZoneInfo dest = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");
TimeZoneInfo src = TimeZoneInfo.FindSystemTimeZoneById("Greenwich Standard Time");
DateTime convertTime = TimeZoneInfo.ConvertTimeToUtc(Convert.ToDateTime(datetime), src);
DateTime transactTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(convertTime, dest.Id);
Getting output invalid format - 4/24/2020 2:09:42 PM.145
System format date format dd/mm/yyyy and time in 24 hours
A few things:
That input format is non-standard and a bit strange. If you can change wherever it is constructed, that would be a better approach. In the meantime, I suggest you parse it with DateTime.ParseExact instead of replacing characters to get Convert.ToDateTime to recognize it.
Greenwich Standard Time is the local time zone identifier for Monrovia (Liberia) and Reykjavik (Iceland) (and a few others). I suspect you are actually trying to convert from GMT/UTC to Sydney time. If so, you only need one conversion function - ConvertTimeFromUtc.
You say you're getting invalid output format, but you don't show how you create that. I assume you are doing something like Console.WriteLine(transactTime), or just putting transactTime in some other place that converts it to a string. When doing so, it will use the general format controlled by the current culture. (See the Remarks section in the DateTime.ToString documentation.)
It sounds like instead you would like a specific format, which you can get by specifying the desired output in the ToString method. You can either specify a standard format token (usually used with the current culture), or your own custom formatting tokens (usually used with the InvariantCulture).
A complete example illustrating the above points:
// Parse the input string to a DateTime, from a given format
DateTime dt = DateTime.ParseExact("20200424-04:09:42.145", "yyyyMMdd-HH:mm:ss.fff", CultureInfo.InvariantCulture);
// Convert the datetime from UTC to Sydney time
TimeZoneInfo dest = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");
DateTime transactTime = TimeZoneInfo.ConvertTimeFromUtc(dt, dest);
// Create and output the string you want to output, in a specific format
string output = transactTime.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture);
Console.WriteLine(output);
// Output: "2020-04-24 14:09:42.145"
(Working .NET Fiddle here.)

Convert Time Zone formatted datetime to local date time

Can someone point out this "20130913095509+1000" datetime represent which format in .NET.
I am able to parse this with following code
string test= "20130913095509+1000";
DateTime parseDt = DateTime.ParseExact(test,
"yyyyMMddhhmmsszzzz",
CultureInfo.InvariantCulture);
//For comparison
string output= parseDt.ToString("yyyyMMddhhmmsszzzz");
//output= 20130913095509+10:00
What is difference between "20130913095509+10:00" and "20130913095509+1000" in terms of Format in .NET.
A few things:
You'd be better to parse this as a DateTimeOffset rather than a DateTime. That way, the local time zone of the machine you are working on does not affect parsing behavior, and you don't need to worry about the madness that is DateTimeStyles or DateTimeKind. Since DateTimeOffset retains the offset you give it, it will survive the round trip from string to object back to string without changing.
zzzz is not a valid format specifier according to the documentation. It may appear to be honored by some implementations, but what's probably happening is that zzz and z are being interpreted separately, with the latter being ignored.
Unfortunately, there is not a format specifier that represents an offset with sign, hours, and minutes without a colon. zzz is the closest, which includes a colon when formatting with ToString, but treats it as optional when parsing with ParseExact. Thus you can use zzz in your format string, but you'll have to remove the : manually after a ToString call.
Putting this together:
string test = "20130913095509+0530";
DateTimeOffset dto = DateTimeOffset.ParseExact(test, "yyyyMMddHHmmsszzz", CultureInfo.InvariantCulture);
string output = dto.ToString("yyyyMMddHHmmsszzz").Remove(17,1);
Console.WriteLine(output); //=> 20130913095509+0530
Note that the format you are using is close to the ISO 8601 "basic" format, however that would include the T separator between the date and time components. If possible, you should consider inserting the T such that your data is ISO 8601 compliant.
string test = "20130913T095509+0530";
DateTimeOffset dto = DateTimeOffset.ParseExact(test, "yyyyMMdd'T'HHmmsszzz", CultureInfo.InvariantCulture);
string output = dto.ToString("yyyyMMdd'T'HHmmsszzz").Remove(18,1);
Console.WriteLine(output); //=> 20130913T095509+0530

DateTime.ToString() not converting time

Looks like time is automatically getting changed during conversion.
My input is 17:15:25. However, it gets converted to 13:15:25
What could be the reason?
string testDate = Convert.ToDateTime("2016-03-24T17:15:25.879Z")
.ToString("dd-MMM-yyyy HH:mm:ss", CultureInfo.InvariantCulture);
The result I get for testDate is : 24-Mar-2016 13:15:25
The Z in your input indicates a UTC time, but the default behaviour of Convert.ToDateTime is to convert the result to your local time. If you look at the result of Convert.ToDateTime("2016-03-30T17:15:25.879Z").Kind you'll see it's Local.
I would suggest using DateTime.ParseExact, where you can specify the exact behaviour you want, e.g. preserving the UTC time:
var dateTime = DateTime.ParseExact(
"2016-03-30T17:15:25.879Z",
"yyyy-MM-dd'T'HH:mm:ss.FFF'Z'",
CultureInfo.InvariantCulture,
DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal);
Console.WriteLine(dateTime); // March 30 2016 17:15 (...)
Console.WriteLine(dateTime.Kind); // Utc
You can then convert that value to a string however you want to.
Of course I'd really suggest using my Noda Time project instead, where you'd parse to either an Instant or a ZonedDateTime which would know it's in UTC... IMO, DateTime is simply broken, precisely due to the kind of problems you've been seeing.
When you use Convert.ToDateTime (which uses DateTime.Parse internally) with Z (which means Zulu time), this method adds your current time zone offset to that DateTime value.
Looks like your current time zone is UTC -04:00 right now and that's why method returns 4 hours back as a result.
I would suggest to use DateTime.ParseExact with AdjustToUniversal and AssumeUniversal styles for prevent Kind conversion as Jon answered.
From AdjustToUniversal
Date and time are returned as a Coordinated Universal Time (UTC). If
the input string denotes a local time, through a time zone specifier
or AssumeLocal, the date and time are converted from the local time to
UTC. If the input string denotes a UTC time, through a time zone
specifier or AssumeUniversal, no conversion occurs. If the input
string does not denote a local or UTC time, no conversion occurs and
the resulting Kind property is Unspecified.
Because of the CultureInfo.InvariantCulture.
You are converting a date in your GMT
Convert.ToDateTime("2016-03-24T17:15:25.879Z")
And then you are converting it to string in an invariant culture
ToString("dd-MMM-yyyy HH:mm:ss",CultureInfo.InvariantCulture);
You should use DateTime.ParseExact, and then use the invariant culture in the conversion.

Date conversion

I need help to convert current date to "Tue Nov 4 00:00:00 UTC+0530 2014" date format
using C#.
Say I have date like : DateTime dt = DateTime.Now;
Now, how can I convert it in mentioned format.
DateTime.ToString(string) allows you to specify a format for your date. You can construct a custom format using Custom Date and Time Format Strings.
I feel like taking risk to answer your question but anyway..
A DateTime doesn't have any implicit format. It just have date and time values etc.. That's why it is not possible to have any format. But string representations of them can have a format. Formatting a DateTime is easy, just need to use DateTime.ToString() method with a specific culture. (In your case looks like InvariantCulture is a good candidate)
DateTime dt = DateTime.Now;
dt.ToString("ddd MMM d HH:mm:ss 'UTC+0530' yyyy", CultureInfo.InvariantCulture);
returns
Tue Nov 4 14:20:36 UTC+0530 2014
AFAIK, time zone abbreviations are not standardized and that's why there is way to parse them besides literal string delimiter. Also since a DateTime doesn't keep offset value, you need also parse it as a literal string delimiter
If you would want to +05:30 instead +0530 as a result, "zzz" custom format specifier would be a nice choice since it gets + or - sign, hours and minutes part offset of local operating system's time zone from UTC.
Based upon your suggestions, I build this code
DateTimeOffset localTime = DateTimeOffset.Now;
string.Format("{0:ddd MMM d HH:mm:ss} UTC+{1} {0:yyyy}", localTime, localTime.Offset.ToString("hhmm"));
and its generating correct format:
"Tue Nov 4 18:25:48 UTC+0530 2014"

Converting the string "20111027" to a DateTime with a timezone of GMT

I have a string in this format: "20111027", i.e. of the general format: "yyyyMMdd".
How do I convert this to a DateTime having the timezone GMT?
This code does some conversion, but it's unclear what timezone would be used:
DateTime date = DateTime.ParseExact(dateString, "yyyyMMdd",
CultureInfo.InvariantCulture);
Use a DateTimeStyles of AssumeUniversal:
DateTime date = DateTime.ParseExact(dateString, "yyyyMMdd",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal);
From the docs of DateTimeStyles.AssumeUniversal:
If no time zone is specified in the parsed string, the string is assumed to denote a UTC.
Sounds like exactly what you want :)
(Alternatively you could use Noda Time and parse it to a LocalDate. It only represents a date, after all, so why use a type which cares about times and time zones? :)
From the documentation:
If s does not represent a time in a particular time zone and the parse operation succeeds, the Kind property of the returned DateTime value is DateTimeKind.Unspecified.
You can change the Kind using DateTime.SpecifyKind:
date = DateTime.SpecifyKind(date, DateTimeKind.Utc);

Categories