TimeZoneInfo.ConvertTimeFromUtc is returning the wrong value - c#

I'm taking a set date/time value and converting from UTC, but timezone. I'm expecting to get the original time - 5 to be the correct time in the EST time zone, but it is off by 1 hour and only offset it by 4 hours.
string dateString = "3/15/2021 6:59 AM";
DateTime TimeDataDue = DateTime.Parse(dateString, System.Globalization.CultureInfo.InvariantCulture);
TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var TimeDataDueEastern = TimeZoneInfo.ConvertTimeFromUtc(TimeDataDue, easternZone).Dump();
The output I get is "3/15/2021 2:59:00 AM", but I expect to get "3/15/2021 1:59:00 AM"
Any suggestions?
Thanks!

As Yarik said in the question comments, the result you obtained is correct.
You can review the 2021 DST schedule for the US Eastern Time zone here:
https://www.timeanddate.com/time/zone/usa/new-york?year=2021
Additionally, you'll note that easternZone.DisplayName in your code will be "(UTC-05:00) Eastern Time (US & Canada)" (assuming English). In other words, despite the time zone having the word "Standard" in its Id, it applies for the entire year including both EST and EDT periods.
Since EDT is in effect on March 15th 2021, you get a result that is four hours behind UTC.

Related

TimeZoneInfo.ConvertTimeFromUTC produce different output then TimeZone.BaseUTCOffset

I have a UTC date-time, I need to convert it to EST time zone. It should be as simple as this
var easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var dt = DateTime.SpecifyKind(value, DateTimeKind.Utc);
return TimeZoneInfo.ConvertTimeFromUtc(dt, easternZone);
So my input date is
02-08-2019 22:53:32
and the result value is
02-08-2019 18:53:32
It deduct 4 hours from given time.
But if I check the Offset between Eastern Standard Time Zone and UTC time zone then the value it return is
easternZone.BaseUtcOffset {-05:00:00} System.TimeSpan
If this is true then above result value should be
02-08-2019 17:53:32
I am not sure what I am missing here.
I am not sure what I am missing here.
BaseUtcOffset does not take into account daylight saving time (it can't, since it doesn't know what specific date you are interested in). You likely want to use GetUtcOffset:
The returned time span includes any differences due to the application
of adjustment rules to the current time zone. It differs from the
BaseUtcOffset property, which returns the difference between
Coordinated Universal Time (UTC) and the time zone's standard time
and, therefore, does not take adjustment rules into account.
Adjustment Rule is discussed here (emphasis mine):
Provides information about a time zone adjustment, such as the
transition to and from daylight saving time.
As a general rule, if dates are ever <= 1 hour out from what you expect, look into daylight savings issues.
To illustrate the impact of daylight saving time:
var timeUtc = Convert.ToDateTime("01-01-2019 22:53:32");
var easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var dt = DateTime.SpecifyKind(timeUtc, DateTimeKind.Utc);
Console.WriteLine(TimeZoneInfo.ConvertTimeFromUtc(dt, easternZone));
Console.WriteLine(easternZone.GetUtcOffset(dt));
timeUtc = Convert.ToDateTime("07-07-2019 22:53:32");
easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
dt = DateTime.SpecifyKind(timeUtc, DateTimeKind.Utc);
Console.WriteLine(TimeZoneInfo.ConvertTimeFromUtc(dt, easternZone));
Console.WriteLine(easternZone.GetUtcOffset(dt));
The above code will output:
1/1/2019 5:53:32 PM
-05:00:00
7/7/2019 6:53:32 PM
-04:00:00
Try This :
var timeUtc = Convert.ToDateTime("02-08-2019 22:53:32");
TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime easternTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, easternZone);
Console.WriteLine(easternTime);

C# How to convert UTC date time to Mexico date time

see my code which i used to convert Mexico date and time to UTC date and time.
string strDateTime = "25/01/2017 07:31:00 AM";
DateTime localDateTime = DateTime.Parse(strDateTime);
DateTime univDateTime = localDateTime.ToUniversalTime();
ToUniversalTime return UTC 25-01-2017 02:01:00
when again i try to convert the same UTC date and time UTC 25-01-2017 02:01:00 to Mexico local time then i got 24-01-2017 06:01:00
so see 07:31:00 AM becomes 06:01:00 which is not right. so tell me what is missing in my code for which i am getting wrong local time when i convert from utc to Mexico time using timezone info.
see my code which converting from utc to Mexico local time using timezone info.
string strDateTime = "25-01-2017 02:01:00";
DateTime utcDateTime = DateTime.Parse(strDateTime);
string nzTimeZoneKey = "Pacific Standard Time (Mexico)";
TimeZoneInfo nzTimeZone = TimeZoneInfo.FindSystemTimeZoneById(nzTimeZoneKey);
DateTime nzDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, nzTimeZone);
You current time zone (UTC+05:30) is different from the time zone you are converting into (UTC-8:00). So you get the difference. There is about 13 hours and 30 minutes difference from your original time zone to the targeted one. 5:30 - (-8) = 13:30.
Subtract 13 hours and 30 minutes from your original date, and then you get 18:01:00, which in 12-hour format is 6PM on the previous day.
Edit:
Instead of hard-coding Mexico time zone, you will need to have a method by which you can determine user's time zone no matter where they are coming from. This is best done using JavaScript as outlined in this answer.
Okay, I didn't know that you were located in India - which changes things a little bit:
You're going to want to utilize the TimeZoneInfo.ConvertTime() API for this one.. Maybe something like :
var dt = new DateTime(2017, 01, 25, 7, 31, 0).ToUniversalTime();
var nzTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time (Mexico)");
//var ist = TimeZoneInfo.FindSystemTimeZoneById("India Standard Time");
DateTime nzDateTime = TimeZoneInfo.ConvertTime(dt, TimeZoneInfo.Utc, nzTimeZone);
Your problem is that the Parse is done without specifying the timezone it comes from - therefore the system will use whatever the default is of your computer. It appears that Your computer is NOT in PST. Rather somewhere in India.
Therefore after turning it into a DateTime object you need to convert it to UTC by specifying the PST timezone. There are a few ways to do this:
Specify the timezone offset as part of the string.
Call one of the TimeZoneInfo.ConvertTimeToUtc and specify the timezoneid
Maybe all you want to do is convert between two timezones by calling ConvertTime or ConvertTimeByTimeZoneId.
https://msdn.microsoft.com/en-us/library/bb382770(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/bb382058(v=vs.110).aspx
string pst = "Pacific Standard Time";
TimeZoneInfo.ConvertTimeBySystemTimeZoneId(currentTime, TimeZoneInfo.Local.Id, pst));
For example: 7:30AM PST should be 1:30 UTC - not 2:30. So that suggests a problem in the initial conversion. 2 AM UTC to PST is indeed 6 PM. Also I noticed your input was 7:31 and you claim it output 2:01 -- does Mexico do 30 minute timezones? I know India does.
I use Google to test conversions by literally searching for "2:01 UTC to PST" and it returns the answer for comparison.
See this other post which shows declaring the input timezone for Parsing. And as stated one does NOT need to convert for DST. Does ConvertTimeFromUtc() and ToUniversalTime() handle DST?
More info on MSDN for TimeZoneInfo: https://msdn.microsoft.com/en-us/library/bb495915(v=vs.110).aspx

TimeZone.GetUtcOffset() Requires DateTime, but DateTime's Timezone is Ignored, why?

My goal is to get the difference between UTC and another time zone. Take for example the difference between UTC and EST (UTC-5:00). Also for sake of example assume my system is currently in Pacific Standard Time so DateTime.Kind, "LOCAL", is PST. In order to find the difference between UTC and EST I'm forced to provide a DateTime which I'm providing in PST. Here's a simplified snippet of my code:
public static void Run_Timezone_Test()
{
var myDate = DateTime.Now;
Console.WriteLine(myDate.Kind);
//OUTPUT: Local (note this is currently PST)
var easternTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var offset = easternTimeZone.GetUtcOffset(myDate);
Console.WriteLine(offset);
//OUTPUT: -05:00:00 (correct offset for EST)
Console.ReadLine();
}
Why am I forced to provide "myDate" if it and its time zone are not used?
Here's an example of why it matters:
var AUSEast = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");
var offset = AUSEast.GetUtcOffset(DateTime.Now);
Console.WriteLine(offset);
offset = AUSEast.GetUtcOffset(DateTime.Now.AddMonths(6));
Console.WriteLine(offset);
At the time of writing, this will output (assuming you have AEST installed as a system time - you can check via TimeZoneInfo.GetSystemTimeZones()):
11:00:00
10:00:00
Note that a time zone does not indicate an offset from UTC by itself. Time anomalies (most commonly daylight savings) will change the UTC offset while still remaining in the same time zone

How to use Standard Time Only in TimezoneInfo.ConvertTime C#

I am having a Issue with the C# function of TimeZoneInfo.ConvertTime().
What i need to get is the Standard Time not the DST but i'm only getting DST is there a way to Tell the Function to only get the Result in Standard Time.
My local Timezone is UTC -6:00 Central America Standard Time, so if my time is 12:00 PM the Conversion i'm getting is throwing it at 2 PM Eastern Time but i need it to tell me it's 1:00 PM.
public static DateTime TimetoEst( DateTime timenow)
{
var currentTimeZone = TimeZone.CurrentTimeZone.GetUtcOffset(timenow).ToString();
var estzone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var conver = TimeZoneInfo.ConvertTime(timenow, estzone);
return conver;
}
Thanks
A couple of things:
The ID "Eastern Standard Time" represents both EST and EDT, with the appropriate transitions in place. It would more appropriately be called "Eastern Time", but alas this is the identifier and the convention used by Windows time zones.
The Eastern Time zone really does transition in and out of daylight saving time. If you were to always adjust to just Eastern Standard Time (UTC-5), you would be ignoring the reality of timekeeping in that region - that it is in Eastern Daylight Time (UTC-4) for dates in the summer months.
Your code will indeed return EST, but only for date values that are outside of the DST period.
Now, if you still think this is what you want to do - then you can do it without the TimeZoneInfo object at all. Simply adjust the result from the offset that applies to your source value, to the UTC-5 offset that applies to EST.
public static DateTime TimetoEst(DateTime timenow)
{
var dto = new DateTimeOffset(timenow); // will use .Kind to decide the offset
var converted = dto.ToOffset(TimeSpan.FromHours(-5));
return converted.DateTime;
}
This is what you asked, but for the record - I don't think this is the best plan. Besides the issues above - assuming that the input value should be interpreted based on the local time zone is not necessarily a good idea - and unless the input time has a .Kind of DateTimeKind.Utc, it will indeed use the computer's local time zone.
You did label the variable as timenow. If you are just after a DateTime which represents the current time in a fixed offset, then it's much safer just to get it like so:
DateTime dt = DateTimeOffset.UtcNow.ToOffset(TimeSpan.FromHours(-5)).DateTime;
And if you really want the current time in the Eastern Time zone, taking DST into account when appropriate, then:
DateTime dt = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.UtcNow,
"Eastern Standard Time");

Convert same time to different time zone

I am trying to convert times to different time zones, but not the way you're thinking. I need to convert a DateTime that is 9am EST to 9am CST on the UTC for example. The timezones are variable so just adding/subtracting hours doesn't seem correct way to do it with NodaTime
Fri, 21 Feb 2014 21:00:00 EST = 1393034400 Epoch Timestamp
convert to
Fri, 21 Feb 2014 21:00:00 CST = 1393030800 Epoch Timestamp
If I understand the question correctly, it sounds like you're trying to convert a date/time in one time zone to another one that has the same local time and a different time zone; that is, a different point in time.
You can do this with Noda Time by combining the LocalDateTime with the new zone. For example, given something like the following:
Instant now = SystemClock.Instance.Now;
DateTimeZone eastern = DateTimeZoneProviders.Tzdb["America/New_York"];
ZonedDateTime nowEastern = now.InZone(eastern);
nowEastern is the time now in the America/New_York time zone. If we print nowEastern directly to the console, we'll see something like 2014-02-22T05:18:50 America/New_York (-05).
As an aside, "EST" and "CST" aren't time zones: they're non-unique abbreviations for a particular offset within a time zone; America/New_York and America/Chicago are probably representative of what we think of as "Eastern" and "Central", though (or you could use something like UTC-05:00 if you really wanted EST even when daylight savings time was in effect).
Given a ZonedDateTime in any time zone, we can convert it to a ZonedDateTime with the same local time and a specified time zone as follows:
DateTimeZone central = DateTimeZoneProviders.Tzdb["America/Chicago"];
ZonedDateTime sameLocalTimeCentral = nowEastern.LocalDateTime.InZoneStrictly(central);
This gives us a ZonedDateTime with the same local time, but a different time zone. With the input above, the result would be 2014-02-22T05:18:50 America/Chicago (-06).
Note that I'm using InZoneStrictly. This will throw an exception if the local time is ambiguous or invalid (for example, during daylight savings transitions). If that's unacceptable, you could use InZoneLeniently, which picks the earliest valid ZonedDateTime on or after the given local time, or InZone, which allows you to specify your own rules in those cases.
On Msdn website you can find all you need.
Small example:
DateTime dateNow = DateTime.Now;
Console.WriteLine("The date and time are {0} UTC.",
TimeZoneInfo.ConvertTimeToUtc(dateNow));
Go to the link for more details on what you want, I can't give you more with that small description

Categories