Get date/time for specific region? - c#

How do I get DateTime.Now for specific region?
I'm trying to get the current date in a foreign country, I'm looking for an easy way to achieve this.
Note: I don't mind getting the value from an online server, I just don't want to spend too much dev-time for it.

If you know the timezone you want, you can use the TimeZoneInfo class. First get the TimeZoneInfo object for your desired timezone, then convert current time to that timezone:
var timezone = TimeZoneInfo.FindSystemTimeZoneById("Central America Standard Time");
var dateTime = TimeZoneInfo.ConvertTime(DateTime.Now, timezone);

Related

Converting a "Kind-less" DateTime to universal time while specifying culture and source timezone

I am tripping over myself here with figuring out how to standardize times coming into our system. We are in an unfortunate situation where our API is being fed a stringified time like this
2/3/20,08:47:28
I know for a fact that the times being fed are in user's local times. I am also getting a timezone along with the api call such as "Eastern Standard Time"
From my understanding on reading the following article I cannot convert to UTC unless the date string itself has offset info (which it does not)
Using the same article I have tried to get to UTC with the following test scenario in a linqpad.
var str = "2/3/20,08:47:28";
var date = DateTime.Parse(str, new CultureInfo("en-Us"), DateTimeStyles.AssumeLocal);
TimeZoneInfo.ConvertTimeToUtc(date, TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")).Dump();
This doesn't seem to work because I think the DateTime.Parse is getting it's timezone info from my local machine and when I try to convert it to an example Eastern Standard Time it blows because that is not the timezone I am in.
My question is
Is there a way to parse a date from a string without the DateTime structure assuming the local computer's timezone?
If i understand the problem, this may work for you ¯\_(ツ)_/¯
Fair warning, date and times aren't my forte
var parsed = DateTime.Parse("2/3/20,08:47:28", CultureInfo.CreateSpecificCulture("en-EU"));
var Id = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var result = TimeZoneInfo.ConvertTime(parsed, Id, TimeZoneInfo.Local);
Console.WriteLine(result.ToUniversalTime());
Output
2/3/2020 1:47:28 PM
Demo

Is there a way to instantiate a datetime object in a timezone other than local?

I've been racking my brain all afternoon trying to figure this one out. Essentially, the problem itself seems simple. I'm given a date/time that is representative of a date and time in another time zone (not local). I want to convert this value to a UTC value to store in the database. However, all of the methods I find online seem to point to you either starting with UTC or starting with a local time zone. You can convert TO other time zones from these, but you can't start with anything other than those. As a result, it appears that I'll have to do some kind of convoluted offset math to do what I want. Here is an example of the problem:
var dateString = "8/20/2014 6:00:00 AM";
DateTime date1 = DateTime.Parse(dateString,
System.Globalization.CultureInfo.InvariantCulture);
var currentTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
// Now the server is set to Central Standard Time, so any automated offset calculation that it runs will come from that point of view:
var utcDate = date1.ToUniversalTime; // This is wrong
// Similarly, if I try to reverse-calculate it, it doesn't work either
var convertedDate = TimeZoneInfo.ConvertTime(date1, currentTimeZone);
utcDate = convertedDate.ToUniversalTime; // This is also wrong
In essence, I want to somehow tell the system that the datetime object I'm currently working with is from that time zone other than local, so that I know the conversion will be correct. I know that I'll eventually need to figure Daylight Savings Time in there, but that is a problem for another day.
Would this method be of any use to you ?
The TimeZoneInfo.ConvertTime method converts a time from one time zone
to another.
Alternatively, you could use the ConvertTimeToUtc method to simply convert any date (specifying the source time zone) to UTC.
var dateString = "8/20/2014 6:00:00 AM";
DateTime date1 = DateTime.Parse(dateString,
System.Globalization.CultureInfo.InvariantCulture);
var currentTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
var utcDate = TimeZoneInfo.ConvertTimeToUtc(date1, currentTimeZone);
The System.DateTime struct only has two bits for storing the "kind" information. That is why you can only have "local" or "universal" or "unknown" (or "magicl local").
Take a look at the System.DateTimeOffset struct. It is like a DateTime, but it also keeps the time zone (offset from (plus or minus) UTC).

DateTime.Now represented as GMT Time on a PST Server

I am storing information in a database and setting my POCO's property to DateTime.Now.
When this value is displayed it is appearing as the PST time. I would like it to to display as GMT time.
Do I do something like this to display/store it or is there a better way?
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("GMT");
var GMTTime = TimeZoneInfo.ConvertTimeToUtc(DateTime.Now, tz));
Also it needs to consider Daylight Savings as UK changes its clocks at different times in the year than USA:
UPDATE: I have found that in the TimeZone setting you can pass either GMT Standard Time or Greenwich Mean Time, the first taking into account DST
Store it as UTC. It's designed for universal timezone-independent time.
DateTime currentUtcTime = DateTime.UtcNow;
DateTime localTime = currentUtcTime.ToLocalTime();
DateTime backToUtcAgain = localTime.ToUniversalTime();
Whether a given DateTime is already UTC or local time is determined by DateTime.Kind. You have to keep this in mind when serializing/deserializing DateTime values (e.g from a database) because this information is often not stored and when you get your DateTime back, it will most of the time have the value DateTimeKind.Unspecified, which may cause issues with conversion methods. I just make sure to force DateTimeKind.Utc when I load something in from a persistent data store.
there's DateTime.UtcNow if that meets your needs.
Have a look at DateTimeOffset.
I'd propose to change your DateTime property to this type
MSDN
DateTime vs. DateTimeOffSet
You could add it into an extension method to make it nicer
public static DateTime ConvertToGreenwichMeanTime(this DateTime utcDateTime)
{
return TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time"));
}
Then just call it
DateTime.UtcNow.ConvertToGreenwichMeanTime();

How to handle conversion of a DateTime independently of the timezone of the hosting server?

I have an application which potentially rans in different timezones in the world, to name a few it runs in Germany & UK.
Now I have a requirement wherein I have to interpret datetime objects as they are GMT dates, and then get the equivalent UTC datetime out of it. This should happen irrespective of timezones, for example if the application is running in Germany as well the DateTime should be interpreted as GMT and converted to UTC before saving on the server.I do deal will DST shifts as well.
For ex:
If I have a datetime object like this:
var date = new Datetime(2011,03,28,01,00,00), this should be converted to it's equivalent UTC.In this case it should be 28/03/2011 01:00:00 +01:00:00, however while my server reads the saved datetime it finds it as a 28/03/2011 01:00:00 +02:00:00. My UI was running in Germany at the moment and I suspect the dates were interpreted as local dates(CET).
Can you please advise me how to perform the accurate conversion?
It's usually considered a best practice to
Store datetimes as UTC
Render this in timezone-aware user friendly format as late as possible
Thus, I would suggest you to not rely on DateTime.Now, but instead consider using DateTime.UtcNow.
Provided you allow each user to determine (through a Preferences/Options panel) to select its own timezone, then you could render an UTC date in the appropriate user-friendly format using:
string timeZoneInfoId = "Romance Standard Time"; // Or any valid Windows timezone id ;-)
var tzi = TimeZoneInfo.FindSystemTimeZoneById(timeZoneInfoId);
//Build a DateTimeOffset which holds the correct offset considering the user's timezone
var dto = new DateTimeOffset(TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, timeZoneInfo), timeZoneInfo.GetUtcOffset(utcDateTime));
var formated = string.Format("{0} {1} ({2})", dto.ToString("d"), dto.ToString("T"), dto.ToString("zzz")); //Or whatever format that fits you
Note: You can find the list of all valid Windows timeZoneId here.
Provided you're willing to add a selecting list for the user to choose its rendering timezone, you could use TimeZoneInfo.GetSystemTimeZones() to retrieve a list of TimeZoneInfo, then use the Id property of each TimeZoneInfo as the option's value and call the ToString() method of each TimeZoneInfo to render the option's content.
Your selecting list would render in a similar way than native Windows one:
For the first part of your query , you can get the UTC time from the DateTime object.
DateTime dt = DateTime.Now;
dt.ToUniversalTime().ToString() will give you UTC time.
Now incase you want to represent the same as local time, you will need to get the offset from the client end via javascript. Something like
var now = new Date();
var offset = now.getTimezoneOffset();
Now you may use this offset to display the Time for the client by adding or subtracting the minutes you get from this method.
Hope this helps.
Take a look at the TimeZoneInfo class: http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx
date += TimeZone.CurrentTimeZone.GetUtcOffset(date);

.NET Get timezone offset by timezone name

In database I store all date/times in UTC.
I know user's timezone name ("US Eastern Standard Time" for example).
In order to display correct time I was thinking that I need to add user's timezone offset to UTC date/time. But how would I get timezone offset by timezone name?
Thank You!
You can use TimeZoneInfo.FindSystemTimeZoneById to get the TimeZoneInfo object using the supplied Id, then TimeZoneInfo.GetUtcOffset from that:
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("US Eastern Standard Time");
TimeSpan offset = tzi.GetUtcOffset( myDateTime);
You can use the TimeZoneInfo class's GetSystemTimeZones() method to fetch the list of all timezones configured on your server and match it to the one from your client.
Though why do you have timezones in the format "US Eastern Standard Time"? Where did that come from?
Rather than doing some manual addition you should take advantage of the ConvertTime method of TimeZoneInfo which will handle converting your date based on the TimeZone you specify.
var localizedDateTime = TimeZoneInfo.ConvertTime(yourDateTime, localTimeZoneInfo);

Categories