Convert same time to different time zone - c#

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

Related

Get time zone with UTC conversion

I have the system date in BST . I want to convert it to UTC. So did the below:
string utcDate= TimeZoneInfo.ConvertTimeToUtc(dt).ToString("dd/MM/yyyy HH:mm:ss");
What I want is to get the zone along with the Date in UTC. Pls consider the daylight savings.
Example: 2019-07-08T23:59:00+01:00.
A few things:
The string format you gave the example of, 2019-07-08T23:59:00+01:00 is part of the ISO 8601 specification. To be precise, it is the "complete date and time of day representation" of the "ISO 8601 Extended Format". It also the format defined by RFC 3339.
In this format, the date and time portion represent the local time, as denoted by the time zone offset portion. In other words, the values are not in UTC, but already adjusted. In your example, 2019-07-08T23:59:00 is the local time and UTC+01:00 is in effect at that time. The corresponding UTC time would thus be an hour earlier, 2019-07-08T22:59:00Z.
You seem to be asking for the date in UTC but with an offset that includes daylight saving time. That is impossible, as UTC does not observe daylight saving time. The offset from UTC is always zero. You can read more about UTC here.
The offset of UTC itself is denoted with Z, but can also be represented with +00:00, which can be thought of as "zero offset from UTC". In other words, if you are referring to UTC time use the Z, and if you are referring to a local time that is aligned to UTC (such as GMT in London in the winter, or Iceland, etc.) use +00:00.
In your question, you say you want the system time in UTC with the offset. I will assume by "system time" you mean the current time of the clock on the system. That is provided by DateTime.UtcNow or DateTimeOffset.UtcNow. These return either a DateTime or DateTimeOffset structure - not a string. Since you wanted a string in a specific format, then you should first ask for the current time, and then format it as a string with ToString:
using System.Globalization;
...
string a = DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture);
// output example: "2019-07-08T22:59:00Z"
string b = DateTimeOffset.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:sszzz", CultureInfo.InvariantCulture);
// output example: "2019-07-08T22:59:00+00:00"
If what you actually wanted was the local time, such that the offset would be +00:00 in the winter and +01:00 in the summer (in the UK), then use Now instead of UtcNow. This gives the local time in the time zone of the computer where the code is running.
string c = DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture);
// output example: "2019-07-08T23:59:00+01:00"
string d = DateTimeOffset.Now.ToString("yyyy-MM-dd'T'HH:mm:sszzz", CultureInfo.InvariantCulture);
// output example: "2019-07-08T23:59:00+01:00"
If you actually wanted the time in the UK regardless of what the time zone of the local computer was on, then you'd have to first get the UTC time and then convert it to UK time before creating the string.
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
string e = TimeZoneInfo.ConvertTime(DateTime.UtcNow, tzi).ToString("yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture);
// output example: "2019-07-08T23:59:00"
string f = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, tzi).ToString("yyyy-MM-dd'T'HH:mm:sszzz", CultureInfo.InvariantCulture);
// output example: "2019-07-08T23:59:00+01:00"
In example e, note that a DateTime can't store an arbitrary offset as the result of time zone conversion, and thus you get DateTimeKind.Unspecified assigned to the Kind property, which results in no offset being in the string representation. Thus most of the time you should use a DateTimeOffset (example f) instead.
Also, note the time zone ID of "GMT Standard Time" is the correct ID to use for the UK on Windows platforms. It correctly switches between GMT and BST when appropriate. If you are running .NET Core on non-Windows platforms (Linux, OSX, etc.), then you should use "Europe/London" instead. Or if you are wanting to write code that is platform-neutral then you can use my TimeZoneConverter library, which allows you to provide either form and run on any platform.
In your code example, you didn't call any of the "now" functions, but gave a dt variable. Assuming this is a DateTime, the result of calling TimeZoneInfo.ConvertTimeToUtc will depend on the Kind property of that variable. If it's DateTimeKind.Utc, then no conversion is performed. If it's DateTimeKind.Local or DateTimeKind.Unspecified, then the value is converted from the computer's local time zone to UTC.
Lastly, keep in mind that when talking to an international audience, time zone abbreviations can be ambiguous. I could deduce by "BST" that you meant British Summer Time, but only because you showed a +01:00 offset in your question. "BST" can also stand for "Bangladesh Standard Time" (+06:00), or "Bougainville Standard Time" (+11:00).
I guess you can do something like this:
var dt = DateTime.Now;
string utcDate = dt.ToUniversalTime().ToString("dd/MM/yyyy HH:mm:ss") +
dt.ToString(" zzz");
Output: (I'm in EET)
14/07/2019 20:02:17 +02:00
But be aware that this could be confusing to people. The standard way is that the timezone follows the local date, not the universal date.

C# TimeZoneInfo to convert GMT timezone name to system timezone

In windows, we get timezone list like this:
ID Time zone name Display string
-- -------------- --------------
0 Dateline Standard Time (UTC-12:00) International Date Line West
110 UTC-11 (UTC-11:00) Coordinated Universal Time -11
200 Hawaiian Standard Time (UTC-10:00) Hawaii
300 Alaskan Standard Time (UTC-09:00) Alaska
more here.
I use this list to convert from one timezone to another using TimeZoneInfo class which accepts time zone name shown in above list.
Ex.
// Local time zone to UTC
var utcOffset = new DateTimeOffset(DateTime.UtcNow, TimeSpan.Zero);
var localTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timezoneName); // here tz name can be any name from above table
var localOffset = new DateTimeOffset(date.Value, localTimeZone.GetUtcOffset(utcOffset));
DateTime utcDate = localOffset.UtcDateTime;
Now I came across SalesForce timezone representation like:
Time Zone Code Time Zone Name
-------------- --------------
GMT+14:00 Line Is. Time (Pacific/Kiritimati)
GMT+13:00 Phoenix Is.Time (Pacific/Enderbury)
GMT+13:00 Tonga Time (Pacific/Tongatapu)
GMT+12:45 Chatham Standard Time (Pacific/Chatham)
more here.
I couldn't find built in functionality to use either time zone code or time zone name given in above table for the conversion.
If you're happy to stick with TimeZoneInfo and DateTime/DateTimeOffset, you can use Matt Johnson's TimeZoneConverter library to convert the IANA ID (the part in brackets, e.g. Pacific/Kiritimati) to a Windows system time zone ID.
Examples from the project page docs:
string tz = TZConvert.IanaToWindows("America/New_York");
// Result: "Eastern Standard Time"
Or:
TimeZoneInfo tzi = TZConvert.GetTimeZoneInfo("America/New_York");
However, things to be aware of:
There won't always be a complete mapping from IANA IDs to Windows IDs. Some aren't mapped, although the situation is better than it used to be.
The Windows time zone data can be different to the IANA data sometimes. (Again, this is getting better.)
Time zone data changes over time. If you're storing future date/time values, you might want to store the time zone and local time rather than the UTC instant. (That instant may not map to the same local time in the future.)
Some local times can be ambiguous - e.g. if the clocks go back from 2am to 1am on a particular date in a particular time zone, then 1:15am on that day will occur twice in that time zone. Think about how you want to handle that, and test it.
I'd personally recommend using my Noda Time library anyway, as a cleaner way of handling date/time, but I acknowledge that if you've got a lot of code dealing with DateTime already, that may not be feasible.

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

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");

Using TimeZoneInfo to convert between UTC/Specified TimeZone not working

All of our date/time data in our database is stored in UTC time. I'm trying to write a function to convert that UTC time into the user's preferred time zone (they can select their timezone in their profile so it has NOTHING to do with local settings on their computer and everything to do with which timezone they have selected from a dropdown of available choices.
This function is in the context of a DevExpress AspxGridView event (the third party control is not relevant to the question but I thought I'd mention it):
DateTimeOffset utcTime = (DateTimeOffset)e.Value;
TimeZoneInfo destTimeZone = Helper.GetTimeZoneInfo();
DateTime modifiedDate = TimeZoneInfo
.ConvertTimeFromUtc(utcTime.DateTime, destTimeZone);
e.DisplayText = String.Format("{0} {1}",
modifiedDate.ToString("g"),
destTimeZone.Abbreviation());
Helper.GetTimeZoneInfo() simply returns a TimeZoneInfo class that corresponds to the one the user selected, or defaults to "Pacific Standard Time" if they have not chosen one.
This generally works fine until I switch my system clock (which this server is running on) from today (which is Oct. 14, a DST date) to something like January 11, which is NOT DST.
The time seems to always be displayed in DST (i.e. always a 7 hour offset). No matter what I do with my system clock, I can't get the time to adjust for the extra hour.
For example, when I have my timezone set to Pacific Standard Time, for UTC time 10-10-2011 20:00:00, it is always displaying this time:
10-10-2011 13:00:00 (the DST time, offset of -7).
During non-Daylight Savings dates (standard), the time should be:
10-10-2011 12:00:00 (offset of -8).
What am I missing?
The converted local time of a UTC time is always based on the time zone info for that UTC time... not for whatever the current time happens to be.
That is, the PST offset on Oct 10, 2011 UTC is always -7. It doesn't matter what date you are doing the conversion on.
...Or am I misunderstanding what you are asking?
You might have a look at the e.Value.
Is the DateTimeKind for it set to DateTimeKind.Utc or is it DateTimeKind.Unspecified
If it is Unspecified, the conversion will not work correctly.
One cannot set the Kind directly. The best I have come up with is something along the lines of
// the value off the DB, but Kind is unspecified
var fromDb = new DateTime(1999,31,12)
// convert it to a Utc version of the same date
var fromDbInUtc = new DateTime(fromDb.Ticks, DateTimeKind.Utc)
var destTimeZone = Helper.GetTimeZoneInfo();
var local = TimeZoneInfo.ConvertFromUtc(fromDbInUtc, destTimeZone);
Hope this helps,
Alan.

Categories