DateTime parsing error: The supplied DateTime represents an invalid time - c#

I have one situation where date is "3/13/2016 2:41:00 AM". When I convert date by time-zone, I get an error.
DateTime dt = DateTime.Parse("3/13/2016 2:41:00 AM");
DateTime Date_Time = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(dt, "Eastern Standard Time",
"GMT Standard Time");
Response.Write(dt);
after execution, I get this error:
The supplied DateTime represents an invalid time. For example, when
the clock is adjusted forward, any time in the period that is skipped
is invalid. Parameter name: dateTime

Try to check if the time is ambiguous or a valid time. Due to the daylight change the time you mentioned i.e, 2:41:00 AM doesn not exist since the clock was moved 1 hour ahead and hence the date is invalid or ambiguous.
2016 Sun, 13 Mar, 02:00 CST → CDT +1 hour (DST start) UTC-5h
Sun, 6 Nov, 02:00 CDT → CST -1 hour (DST end) UTC-6h
You can also refer to this blog: System.TimeZoneInfo: Working with Ambiguous and Invalid Points in Time
System.TimeZoneInfo (currently available as part of .NET Framework 3.5
Beta 1) contains methods for checking if a DateTime instance
represents an ambiguous or invalid time in a specific time zone. These
methods are particularly useful for validating user-supplied points in
time.
Background Information
Time zones that adjust their time for Daylight Saving Time (in most
cases by moving the clock time back or forward by 1 hour) have gaps
and repeats in the timeline — wherever the clock time was moved
forward or back by the adjustment. Let’s use Pacific Standard Time as
an example. In 2007 Pacific Standard Time (PST) changes to Pacific
Daylight Time (PDT) at 02:00AM (“spring forward”) on the second Sunday
in March and then returns at 02:00AM (“fall back”) on the first Sunday
in November
To check if the time is valid you can use:
TimeZoneInfo.IsInvalidTime

In my case, I was trying to convert a UTC date (thus, it was valid, as UTC dates don't skip any periods of time with DST).
The problem was that I was loading the date from Entity Framework and the DateKind was set to Unspecified. In that case, ConvertTimeBySystemTimeZoneId assumes it is a local time and may find it invalid.
The solution is to properly set the DateKind to UTC before converting:
var date = DateTime.ParseExact("2019-03-31T03:06:55.7856471", "O", CultureInfo.InvariantCulture);
// Here date.Kind == DateTimeKind.Unspecified
date = DateTime.SpecifyKind(date, DateTimeKind.Utc);
// Now date.Kind == DateTimeKind.Utc
// Now the conversion should work
TimeZoneInfo.ConvertTimeBySystemTimeZoneId(date, "Central Standard Time");

Related

Timezone StartOfDay

Hi i receice some random datetimeoffset utc my point is
1 - turn it into chicago time
2- Define the chicago startOfDay
3-finaly convert chicago startOfDay back to an utc datetimeOffset.
(this process is needed to query an utc api)
i writed this that seem do what i want but realy not sure it will always do the job with day saving light etc..
someone can tell or improve the code?
var UTCDate = DateTimeOffset.UtcNow; //<----------Some random utc dateTimeOffset
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
DateTimeOffset CSTDate = GetZoneDatetimeOffset(UTCDate, zone);
Console.WriteLine("Utc : {0} Chicago: {1} local : {2}", UTCDate, CSTDate, UTCDate.ToLocalTime());
Console.WriteLine(" Chicago StartOfDay: {0} Chicago StartOfDay To UTC : {1}", CSTDate.Date, CSTDate.Date.ToUniversalTime());
public DateTimeOffset GetZoneDatetimeOffset(DateTimeOffset someUTCDate , TimeZoneInfo destZone)
{
DateTimeOffset ZoneDateTimeOffset = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(someUTCDate.DateTime , TimeZoneInfo.Utc.Id, destZone.Id);
return ZoneDateTimeOffset;
}
You have a few bugs in your code:
You call TimeZoneInfo.ConvertTimeBySystemTimeZoneId and pass a DateTime value. The result will thus also be a DateTime. The Kind of that result will be Unspecified. Assigning it to a DateTimeOffset thus will perform an implicit cast operation from DateTime to DateTimeOffset, which will use the computer's local time zone - not the time zone you are working with.
Both DateTimeOffset.Date and DateTimeOffset.DateTime also return a DateTime whose Kind is Unspecified. Thus when you call ToLocalTime or ToUniversalTime, you are again using your the computer's local time zone.
Determining the start of the day in a specific time zone can be tricky. Though it doesn't happen in Chicago (or anywhere in the USA), some time zones of the world have DST transitions that occur immediately at the start of the day. Thus 00:00 might not be the first moment of the day, or it might occur twice. Your code doesn't account for that.
A good example is Cuba, where DST next starts on 2022-03-13 at midnight, and thus the start of that day in Cuba is 2022-03-13T01:00.
You can use the GetStartOfDay method I already provided in this answer to handle these edge cases.
Putting it all together:
// Input values
DateTimeOffset utc = DateTimeOffset.UtcNow;
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
// Convert with full fidelity using only DateTimeOffset values
DateTimeOffset converted = TimeZoneInfo.ConvertTime(utc, zone);
// Get the start of day using the method from https://stackoverflow.com/a/49988688
DateTimeOffset startOfDay = GetStartOfDay(converted.DateTime, zone);
// Output the results
Console.WriteLine("Original values:");
Console.WriteLine("Chicago: {0:o} UTC: {1:o} Local: {2:o}", converted, utc, utc.ToLocalTime());
Console.WriteLine();
Console.WriteLine("At start of day in Chicago:");
Console.WriteLine("Chicago: {0:o} UTC: {1:o} Local: {2:o}", startOfDay, startOfDay.ToUniversalTime(), startOfDay.ToLocalTime());
Example output (local time zone is US Pacific Time in this example):
Original values:
Chicago: 2022-03-10T10:58:47.8164830-06:00 UTC: 2022-03-10T16:58:47.8164830+00:00 Local: 2022-03-10T08:58:47.8164830-08:00
At start of day in Chicago:
Chicago: 2022-03-10T00:00:00.0000000-06:00 UTC: 2022-03-10T06:00:00.0000000+00:00 Local: 2022-03-09T22:00:00.0000000-08:00
See also the working .NET Fiddle here.

Date time convertion with daylight saving

I am using following code to convert date time between time zones
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById(site.TimeZone);
returnTime = TimeZoneInfo.ConvertTime(DateTimeOffset.Parse(time.ToString()), timeZone);
The daylight saving adjustment for the CST timezone happened on 12th March. On that day it gave an error as
The supplied DateTime represents an invalid time. For example, when the clock is adjusted forward, any time in the period that is skipped is invalid
How can I change my date time conversion which support day light saving
I had similar problems and fixed all of them using this easy to use alternative:
Noda Time "A better date and time API for .NET"
Alternative approach would be to convert to UTC first and then to target timezone. While converting to UTC also check if time passed in is ambiguous, you may need to adjust for that, check the following How to: Resolve Ambiguous times
You need to know the TimeZone of the source time value - that can be used to determine if the time is ambiguous. If not ambiguous convert to UTC via the source TimeZone by checking if it is standard time (apply the base UTC offset of the TimeZone) or daylight time (apply the non-base UTC offset) - the UTC offsets, ambiguous check and daylight check can be done via the TimeZoneInfo. If ambiguous you can either assume that the time is standard time or have an alternative means to specify if it is daylight time - once determined use the offset values as previously. Then use the target TimeZone to convert from UTC.

TimeZoneInfo BaseUtcOffset always zero on Windows Embedded 7

I'm trying to get the difference between an application running on Windows Embedded 7 and UTC time. To do that I have the following piece of code:
TimeZoneInfo utcTimeZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
DateTime localTime = DateTime.Now;
DateTime utcTime = TimeZoneInfo.ConvertTime(localTime, TimeZoneInfo.Local, utcTimeZone);
TimeSpan utcOffset = localTime - utcTime;
This runs fine on my own development PC, running Windows 7. However, when I install my application on a device running Windows Embedded 7, no matter what timezone I set it to, when I run my application,
The value for TimeZoneInfo.Local.BaseUtcOffset is always 00:00.
The BaseUtcOffset value in the object returned by TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time") is also 00:00 (though this is to be expected).
The ConvertTime() function above always returns the current time less one hour. (Kind of not surprised since the TimeZoneInfo.Local.SupportsDaylightSavingsTime value is always false.)
Should I be using another way that TimeZoneInfo.Local to get the offset between UTC and the current time zone? I need to include Daylight Savings in this.
A few things:
The time zone with the ID "GMT Standard Time" is not UTC - it's UK Time. Its display name matches "Dublin, Edinburgh, Lisbon, London". It uses UTC+0 in the winter, and UTC+1 in the summer for daylight saving time.
The UTC time zone ID is simply "UTC" - though you'll rarely need that.
If TimeZoneInfo.Local.BaseUtcOffset is zero, then that means the computer's time zone setting is one that has UTC+0 as its standard offset. There are four of those currently defined in Windows. This property does not reflect daylight saving time.
Recognize that offsets will change depending on what time of the year that you are running the code. A time zone is not the same as a time zone offset.
Since you said you got zero in your above code, I'd guess that your local time zone is either the previously mentioned UK Time, or Casablanca, Morocco. This is because you are subtracting a UTC+1 local time with the time from another time zone that is also UTC+1 presently. 1 - 1 = 0
The correct way to do this does not involve subtraction at all. Simply use the GetUtcOffset method:
TimeSpan offset = TimeZoneInfo.Local.GetUtcOffset(DateTime.Now);
Again, note that this returns the current offset. Running it at different times of the year, or by passing a different value instead of DateTime.Now could return a different result.

C# doing a convert timezone on thousands of rows. Randomly got "The supplied DateTime represents an invalid time."

Just a quick question as I am baffled. I have some code that loops through datarows in a ssis package to convert timezones and it is failing on a row and I have no idea why.
The full error message is:
The supplied DateTime represents an invalid time. For example, when the clock is adjusted forward, any time in the period that is skipped is invalid.
The code that I run to do the convert time is:
DateTime easternstandardtime = Row.UniversalTime;
TimeZoneInfo timeZoneGMT = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
TimeZoneInfo timeZoneEST = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
easternstandardtime = TimeZoneInfo.ConvertTime(Row.UniversalTime, timeZoneGMT, timeZoneEST);
Row.StandardEasternTime = easternstandardtime;
The code fails on the 2nd to last line (The convert time). The value for Row.UniversalTime is 3/27/2016 1:10:03 AM. How is this not ok? The full stats of the variable are below. What's strange to me is that the whole rest of the file processed fine and the datetimes are all similar. Not sure why it is randomly blowing up with a value like this. Any ideas?
Full var stats:
?Row.UniversalTime
{3/27/2016 1:10:03 AM}
Date: {3/27/2016 12:00:00 AM}
Day: 27
DayOfWeek: Sunday
DayOfYear: 87
Hour: 1
Kind: Unspecified
Millisecond: 0
Minute: 10
Month: 3
Second: 3
Ticks: 635946378030000000
TimeOfDay: {01:10:03}
Year: 2016
As the error message somewhat implies, you're attempting to do a conversion on a time that does not actually exist.
http://www.timeanddate.com/news/time/europe-starts-dst-2016.html
Most countries in Europe will spring forward 1 hour at 01:00 UTC
So, if most European countries spring forward at 01:00 (GMT), and you're trying to convert a GMT time that's at 01:10, that time does not actually exist as per the DST adjustment. Seems that's your issue.

Converting EST to IST gives error in C#

I am trying to convert EST( Eastern Standard Time) to IST (Indian Standard Time) but the conversion is showing incorrect results.
Can anyone help me on that??
I searched on net and found that using Noda time we can solve that.
But I want to solve it using conventional DateTime class.
Here is my code and its output:
DateTime time= new DateTime(1899,12,30, 23, 30 ,0); //some random date and 11:30 PM in EST
TimeZoneInfo estZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); // Eastern Time Zone
TimeZoneInfo istZone = TimeZoneInfo.FindSystemTimeZoneById("India Standard Time"); // Indian Time Zone
DateTime localTime = TimeZoneInfo.ConvertTime(time, estZone, istZone); // result is 10:00 am while it should be 09:00 am.
A few things:
The TimeZoneInfo identifier "Eastern Standard Time" refers to the North American Eastern Time zone, covering both Eastern Standard Time and Eastern Daylight Time. EST is UTC-5, while EDT is UTC-4. In general, you should not infer too much from the names of these identifiers. See more examples in the timezone tag wiki.
The TimeZoneInfo.ConvertTime method will use whichever offset is appropriate for the supplied date and time, correctly taking the daylight saving time rules into account.
The underlying time zone data from Windows does not go back to 1899. There are actually no sources of data that guarantee historical dates from that time period. Even the IANA time zone database used with Noda Time makes an educated guess. See History of DST in the United States.
Windows will just use the earliest data it has, which for this zone uses the daylight saving time rules that were in effect from 1986 to 2007. These are not the current rules, so it would make better sense to use a modern year, such as DateTime.Today.Year.
Even if you supplied a modern year, the correct converted time would indeed be 10:00 for a date in December. If you want 9:00, try a date in the summer.

Categories

Resources