Date time convertion with daylight saving - c#

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.

Related

Check a date (datetime) if it is Daylight Saving Time with unknown region - c#

With what I understood from other questions I've used below code for checking a date if it is Daylight saving time and altering as required. I do not know which region would the application be used hence I am using Utc. However it is not working as expected.
DateTime dateValWithOffset = dateVal;
TimeZoneInfo timeZoneInfo = TimeZoneInfo.Utc;
if(timeZoneInfo.IsDaylightSavingTime(dateValWithOffset))
{
dateValWithOffset = dateValWithOffset.AddMinutes(60);
}
Example: for sample date (06-JUL-21 06.16.34.547000000 AM) above code should be showing dateValWithOffset as 07/06/2021 02:16:34.547 AM but it returns 07/06/2021 01:16:34.547 AM . If someone can point out where am I going wrong please.
Datetime values should always be in UTC. To format a datetime in the machine or user's local timezone, you should convert to a DateTimeOffset. Knowing the local time and knowing if that time is in daylight saving time are two different things.
// machine local
var timeZoneInfo = TimeZoneInfo.Local;
// or by name
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(name);
var localTime = new DateTimeOffset(dateVal, timeZoneInfo.GetUtcOffset(dateVal));
var isDst = timeZoneInfo.IsDaylightSavingTime(localTime)
IMHO DateTime is a terrible type, designed before the age of cloud computing. All DateTimeKind values other than Utc encourage programmers to continue to handle dates incorrectly and should be deprecated.
As jason.kaisersmith said in comments, "UTC is universal, so there is no daylight saving."
To elaborate, UTC does not have any daylight saving time. Instead, daylight saving time is observed differently at each time zone across the world. Some time zones don't use it at all. Some time zones start and stop DST at different dates or times than other time zones. There's even one time zone that shifts for DST by 30 minutes instead of the usual 1 hour. Without a time zone reference, the concept of DST is meaningless.
For clarity and reference, here's an overview of anticipated DST dates for 2022 by country, and a detailed list of dates and times for the first half and second half of 2022.

How to get datetime based on timezone offset in c#?

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;

Issue on converting time from local to UTC at DST end date while using TimeZoneInfo.ConvertTimeToUtc(DateTime, TimeZoneInfo) method

I have an application that converts local time to UTC and stores it in the database. I encountered this problem while I was testing the conversion during a particular date - 1st November, 2015(the date on which the Daylight savings time ends(the clock goes back to 1.00AM on reaching 2.00AM)).
My local system timezone is (UTC-08:00) Pacific Time (US & Canada)
I converted the time 2015-10-31 01:49:00.000 to UTC, the output was 2015-10-31 08:49:00.000.
but
when I tried to convert 2015-11-01 01:49:00.000 to UTC, the output was 2015-10-31 09:49:00.000.
Isn't this wrong? why did the converted time increase by an hour on 1st November?
This is my method,
DateTime universalFormatDateTime = localDateTime.Value.GetUniversalFormatDateTime();
utcDateTime = TimeZoneInfo.ConvertTimeToUtc(universalFormatDateTime, _timeZoneInfo);
Isn't this wrong? why did the converted time increase by an hour on 1st November?
Because that's when the clocks change, as you say.
The problem is that "2015-11-01 01:49:00.000" is ambiguous in Pacific Time - it occurs twice, once at 2015-11-01T08:49:00Z and once at 2015-11-01T09:49:00Z.
A DateTime can remember which of those you mean, but it depends on how you came up with the value. If you've just parsed this from text somewhere, you basically don't have enough information - it doesn't specify a single instant in time.
If you were to use my Noda Time library instead, then when converting from LocalDateTime to ZonedDateTime you'd be able to specify how you wanted ambiguity to be handled - so that may be an option for you... but it depends on where the value came from, and whether you know that it was always the second occurrence or always the first.
If you still want to use TimeZoneInfo, you can use TimeZoneInfo.IsAmbiguousTime and TimeZoneInfo.IsInvalidTime to detect local times which occur twice or zero times due to time zone shifts, and then handle those appropriately in your app.

How to convert Datetimes into UTC based timing values to compare timings- C#

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

Wunderground and UTC Offset

I am consuming the international weather forecasts via Wunderground's XML API:
http://wiki.wunderground.com/index.php/API_-_XML
Looking at an output for Kabul, Afghanistan for instance:
http://api.wunderground.com/auto/wui/geo/ForecastXML/index.xml?query=OAKB
I notice that there is no UTC offset. The closest that I can see is this:
<tz_short>AFT</tz_short>
Which identifies the current TimeZone is AFT. The problem I see is that there is no universally accepted time zone abbreviations, so I cannot take these abbreviations and look up and offset from C#'s TimeZoneInfo objects.
Is there a listing of Wunderground's Time Zones abbreviations/names/offsets so I can map their Time Zones to the TimeZoneInfo objects, or is there a better way to get this information? I will need to use the TimeZoneInfo so I can calculate daylight savings time for different locations internationally.
Here is an idea of what you can do to acquire a UTC offset.
Use the epoch field from the XML output, which will be in UNIX time (number of seconds since 1970-01-01 00:00). This time will be in UTC/GMT. Then, either by converting the contents of the pretty field, or by using the day/month/year/hour/minute/second fields, determine the difference between the published local time and the epoch time. This will give you your UTC offset. There is also a isdst field to tell you whether or not the zone is honoring DST at the moment.
Unfortunately I don't know of a comprehensive list of time zone abbreviations, so using the method above to determine the offset and DST is probably your best option. Good luck!

Categories

Resources