Unable to convert DateTime string to DateTime in C# using DateTime.ParseExact() - c#

So I want to convert a certain UTC DateTime string that is in the following format 2020-04-18T20:05:00.000-04:00.
I am trying to use the following function :
DateTime.ParseExact(segment.DepartureDate,"yyyy-MM-ddTHH:mm:ss.fffzzz", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AdjustToUniversal);
for converting the above Date string that i received from an API, to a C# DateTime type variable.
But the Actual Result is {19-04-2020 00:05:00}. Somehow the date gets rounded up or converted which is not what i am expecting.
Have also tried Date.Parse but that filters out the UTC Offset whose value i really need.
Can anyone suggest a legit way to achieve this conversion accurately.Thanks in Advance.

If you are working with different time zones (where the offset is not equal to your current locale's offset) and the offset is important, it is usually better to use DateTimeOffset instead of DateTime. DateTime only has a property identifying it as UTC or (system-)local, but DateTimeOffset stores the full offset value instead.

Related

DateTime format usage in C#

I have following date time format
TimeZoneDetails.TimeZoneInstance ="Australia/Perth"
DateTime Today = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow,TimeZoneDetails.TimeZoneInstance);
Does today variable store the date based on timezone?
string date = "2020-03-19";
DateTime startdate = DateTime.Parse(date);
What is the timezone of startdate variable?
DateTime enddate = TimeZoneInfo.ConvertTimeToUtc(startdate, TimeZoneDetails.TimeZoneInstance);
Will enddate variable converted to UTC time?
A few things:
"Australia/Perth" is an IANA time zone identifier. It will work with .NET on Linux or Mac OSX, but on Windows you'd have to use "W. Australia Standard Time" instead. Alternatively, you could use my TimeZoneConverter library to work with either form of identifier on any platform.
In your code:
TimeZoneDetails.TimeZoneInstance ="Australia/Perth"
This isn't generally valid. Given the usage in the rest of your code, your TimeZoneInstance would have to be a TimeZoneInfo object. You can't assign a string in that way. You'd have to use a function like TimeZoneInfo.FindSystemTimeZoneById, or TZConvert.GetTimeZoneInfo from TimeZoneConverter, or a similar function in your own code. (Also you're missing a semicolon.)
In your code:
string date = "2020-03-19";
DateTime startdate = DateTime.Parse(date);
You asked what the time zone is in the startdate variable. That's a DateTime, which does not store time zone or offset information. It only has a .Kind property, which is of type DateTimeKind. In your example, it will be DateTimeKind.Unspecified. Also note the time will be set to 00:00:00.0000000.
You can read more about this in the documentation, here and here.
In your code:
DateTime enddate = TimeZoneInfo.ConvertTimeToUtc(startdate, TimeZoneDetails.TimeZoneInstance);
Yes, that will correctly convert the DateTime from the time zone given to UTC. Because startdate.Kind == DateTimeKind.Unspecified, the value is treated as belonging to the time zone specified. The resulting value will have enddate.Kind == DateTimeKind.Utc.
You can read more in the documentation, here.
In comments you asked:
which one is default for DateTimeKind?
That depends on which method you call to create the DateTime, and what values you pass in. In your case, because you call DateTime.Parse and pass a string that contains no time zone offset information, the resulting value has .Kind == DateTimeKind.Unspecified. You can read more about the behavior of DateTime.Parse in the remarks section here. Other methods and constructors behave similarly, but you should check the documentation for each, or validate the results yourself. You may find conversion errors if you, for example, think a DateTime has Unspecified kind, but it actually has Local kind due to how you obtain it.

How to Convert Date Time using Offset values

I Need to convert a DateTime accordign to the given offset value.
I have values like:
-08:00
-07:00
+08:00
+07:00
+02:00
+05:30
How I can convert a date time according to these given offset values.
I tried:
string t = "Pacific Standard Time";
var tInfo = TimeZoneInfo.FindSystemTimeZoneById(t);
var data = TimeZoneInfo.ConvertTime(DateTime.Now, tInfo);
this is fine to but I need to convert based on offset value.
Plz suggest here how to convert it.
Thanks
The type that stores timezone offsets is DateTimeOffset. If you care about offsets use that type instead of DateTime. Otherwise you won't be able to compare dates with different offsets unless you also store the offset along with the datetime.
Properties like DateTimeOffset.Now and DateTimeOffset.UtcNow will return the current time in the machine's timezone or UTC respectively.
Creating a DateTimeOffset from a DateTime in a specific offset is as simple as calling the appropriate constructor, eg :
var pstTime=new DateTimeOffset(2019,1,14,1,0,0,new TimeSpan(-8,0,0));
You can convert a DateTimeOffset value to different offsets with ToOffset, eg :
var eastEuropeTime=pstTime.ToOffset(new TimeSpan(2,0,0));
This will return 11am.
ToUniversalTime will return the time in UTC, ie +00:00:
var utcTime=pstTime.ToUniversalTime();
Which returns 9 am.
Conversion from/to DateTime
You can also construct a DateTimeOffset from an existing DateTime value. The constructor check the input DateTime's Kind property and refuses to use invalid offsets if DateTime.Kind.
For Utc the only valid value is 00:00.
var now=DateTime.UtcNow;
var utcOffset=new DateTimeOffset(now, TimeSpan.Zero);
utcOffset.Dump();
For a local time, the only valid value is the machine's offset. To convert a local time to DateTimeOffset, you can retrieve its offset from TimeZoneInfo.Local :
var now=DateTime.Now;
var localOffset=new DateTimeOffset(now, TimeZoneInfo.Local.GetUtcOffset(now));
Arbitrary Offsets
In some cases we may want to use a DateTime as is with a specific offset. Many web sites (especially forums) for example allow users to specify their timezone and thus avoid problems with timezone detection on the browser.
In other cases, the offset may be stored separately or come from an IANA timezone name.
To use an arbitrary offset, the DateTime's Kind must have the Unspecified:
var date=new DateTime(2019,01,15,18.17.00, DateTimeKind.Unspecified);
var pst=new DateTimeOffset(date,new TimeSpan(-8,0,0));
This is useful eg when loading datetime values from a database. DateTime values loaded from a database are Unspecified.
Values that come from code or input controls may already be Local or UTC. In this case we need to use DateTime.SpecifyKind to create a new Unspecified DateTime value :
var date=DateTime.SpecifyKind(domeDate,DateTimeKind.Unspecified);
var pst=new DateTimeOffset(date,new TimeSpan(-8,0,0));
What you can use is DateTimeOffset.Parse
For example:
var offsetValue = "+08:00";
var now = DateTime.Now;
var nowString = now.ToString("dd/MM/yyyy HH:mm:ss");
var offsetDateTime = DateTimeOffset.Parse($"{nowString} {offsetValue}");
Please note the above is just an example, this is ignoring any sort of culture specific issues etc.

TimeZoneInfo.ConvertTime method not converting the DateTime correctly

I have the following date string: 2015-11-10T23:52:18.5245011Z
And when I parse it using DateTime.Parse method it returns 11/11/2015 10:52:18 AM which is incorrect.
I also tried the follwing conversion:
TimeZoneInfo est = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");
DateTime targetTimeUtcconverted = TimeZoneInfo.ConvertTime(UtcDate, est);
and it still gives out: 11/11/2015 10:52:18 AM
Can't figure out what I am missing here.
Use:
DateTime.Parse(s, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind)
Or:
DateTime.Parse(s, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal)
Or (best option):
DateTimeOffset.Parse(s)
By default, DateTime.Parse will adjust to local time if there is any offset information present in the string. Since Z is the same as +00:00, it assumes the input is +00:00, then adjusts from UTC to the local time zone.
If there is no offset information present, it returns a DateTime with Unspecified kind.
Passing DateTimeStyles.RoundtripKind tells it to treat any value with an offset as local time (as before), but any value containing Z, UTC, GMT, etc. to have DateTimeKind.Utc.
Passing DateTimeStyles.AdjustToUniversal tells it that the output should always have DateTimeKind.Utc, and the value should be adjusted if necessary.
Parsing using DateTimeOffset.Parse bypasses all of that convoluted behavior and just returns a value with an offset matching what was provided. This is the best approach when an offset (or Z) is present in the input string. If you need a DateTime, you can use the UtcDateTime, LocalDateTime, or DateTime properties from the resulting DateTimeOffset.
The time zone conversion code you gave is correct, as long as the Kind is UTC. It would be more explicit to use ConvertTimeFromUtc, but that wouldn't really matter in this case. The best approach is to use the overload of ConvertTime that works with DateTimeOffset values. The resulting value will be a DateTimeOffset whose DateTime property matches the time in that time zone, and whose Offset property is the correct offset for that time in that time zone.

Is it possible to set DateTimeOffset to a SAME offset for all the Silverlight clients?

I use DateTimeOffset for the date/time values.
And what I want to achieve is, for all the clients who load their page to run a SilverLight app., I want them to see the Dates according to a specific zone, for example Tokyo time.
So no conversion to their LocalTime will occur.
Is it possible to configure that for all the Silverlight clients they will see the DateTimeOffsets as for example, UTC + Offset of Tokyo ? Not as their local time?
This always returns Tokyo time
DateTimeOffset tokyoTime = DateTimeOffset.UtcNow.ToOffset(TimeSpan.FromHours(9));
For DateTime you can use this:
DateTime tokyoTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time"));
I ran into a simliar problem, the solution I found was not to mark the date or DateTimeOffset property/fields as datamembers, but rather to create an additional string property that is the datamember and perform a string conversion in the getter/setter functions

Difference between System.DateTime and System.DateTimeOffset

Can anyone explain the difference between System.DateTime and System.DateTimeOffset in C#.NET? Which is best suited for building web apps with users from different time zones?
A DateTime value defines a particular date and time, it includes a Kind property that provides limited information about the time zone to which that date and time belongs.
The DateTimeOffset structure represents a date and time value, together with an offset that indicates how much that value differs from UTC. Thus, the value always unambiguously identifies a single point in time.
DateTimeOffset should be considered the default date and time type for application development as the uses for DateTimeOffset values are much more common than those for DateTime values.
See more info, code examples at:
http://msdn.microsoft.com/en-us/library/bb384267.aspx
There are a couple of point here:
DateTime information should be stored in UTC format in your database:
https://web.archive.org/web/20201202215446/http://www.4guysfromrolla.com/articles/081507-1.aspx
When you use DateTime information in your Web Application you will need to convert it to LocalTime:
DateTime.UtcNow.ToLocalTime();
will convert it to the local time from the Web Server's perspective.
If you have a WebServer in one location, serving clients in multiple countries, then you will need to perform this operation in javascript on the Client itself:
myUTCDate.toLocaleTimeString();
http://www.java2s.com/Code/JavaScript/Date-Time/ConvertDatetoLocaleString.htm
DateTimeOffset represents the datetime as UTC datetime.
So
DateTimeOffset dtoNow = DateTimeOffset.Now;
is same as
DateTimeOffset dtoUTCNow = DateTimeOffset.UTCNow;
Here dtoNow will be equal to dtoUTCNow even though one was initialized to DateTimeOffset.Now and the other was initialize to DateTimeOffset.UTCNow;
So DatetimeOffset is good for storing the difference or Offset w.r.t UTC.
For more details refer to MSDN.

Categories