c# DataTime: Assume EST convert to GTM - c#

I have a server running in New York that saves a DateTime into the database in local time.
I then have a client application running in GMT timezone that needs to save down a DateTime in the same local New York time
Can I do using:
TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"))
Or I need to consider daylight savings?
Now in my UI I need to display 2 columns. 1) the DateTime from the database and the DateTime in the database converted to GMT
How can I do this?

The TimeZoneInfo class should give you what you need.
var date = (DateTime)reader[0]; // Retrieve data from database however you normally get it
var est = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var utcTime = TimeZoneInfo.ConvertTimeToUtc(date, est);
var localTime = utcTime.ToLocalTime();
Edit: You modified your question to indicate you have looked at TimeZoneInfo, so this doesn't add much anymore. However to resolve the ambiguous time issue mentioned by Jon, take a look at the IsAmbiguousTime() and GetAmbiguousTimeOffsets() methods to be able to detect values that can't be definitively converted.

Here's a sample to show that it should work as expected. That is, it will do the DST conversion.
DateTime dt1 = new DateTime(2016, 06, 01, 08, 00, 00, DateTimeKind.Unspecified); // Daylight saving time
DateTime dt2 = new DateTime(2016, 12, 01, 08, 00, 00, DateTimeKind.Unspecified); // Standard time
var dt1Converted = TimeZoneInfo.ConvertTimeToUtc(dt1,
TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"));
var dt2Converted = TimeZoneInfo.ConvertTimeToUtc(dt2,
TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"));
var diff1 = (dt1Converted - dt1).TotalHours;
var diff2 = (dt2Converted - dt2).TotalHours;
Console.WriteLine($"dt1: {dt1}, converted: {dt1Converted}, diff: {diff1}");
Console.WriteLine($"dt2: {dt2}, converted: {dt2Converted}, diff: {diff2}");
Output:
dt1: 2016-06-01 08:00:00, converted: 2016-06-01 12:00:00, diff: 4
dt2: 2016-12-01 08:00:00, converted: 2016-12-01 13:00:00, diff: 5

Is there any chance you can change this to use DateTimeOffset ? It was designed to resolve all of these problems

Related

Apply TimeZone to a specific date?

For example, server time is 11 pm.
User timezone, specified within the app, is US Mountain Standard Time.
So I need to get 4 pm, user time.
Tried with
var UserTimeZoneInfo = "US Mountain Standard Time";
var userTime =TimeZoneInfo.ConvertTimeToUtc(now, _UserTimeZoneInfo);
and this
var userTime = new DateTimeOffset(now, this._UserTimeZoneInfo.BaseUtcOffset);
but in both cases, I get 8am instead of 4pm. TimeZone difference gets added to server time , instead of subtracted. I see there are other DateTime functions, but not sure which one to use ?
You need to use ConvertTimeFromUtc method if you want change to specified timezone time from UTC.
var timeZone = TimeZoneInfo.FindSystemTimeZoneById("US Mountain Standard Time");
DateTime arizonaTime = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(2017, 11, 9, 23, 0, 0,DateTimeKind.Utc), timeZone);
DotNetFiddle
You can use ConvertTime which Converts a time to the time in a particular time zone.
DateTime currentDt = DateTime.Now;
var timeZone = TimeZoneInfo.FindSystemTimeZoneById("US Mountain Standard Time");
var userTime = TimeZoneInfo.ConvertTime(currentDt, timeZone);

C# DateTime Convert from string to DateTime in differents TimeZones

I'm struggling with a problem. i have a string date looks like this, "2015-05-02 01:00:00", extracted from a database.
I know that it's british time, but my local time is belgian time.
I'm trying to store the date in UTC and in (CEST or CET depend of the season), converting it from the British time i've extract.
I tried to set Kind property to British time, but the result seems to be in local or utc time. So, i can do half of the job, but not the rest (e.g. I still need the CEST/CET time).
I tried to use this :
string dateString = (string) line["stringDate"];
DateTime ukTime = DateTime.Parse(dateString, new CultureInfo("en-GB", false));
DateTime belgianTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(ukTime, "Romance Standard Time");
The result is the same for both ukTime and belgianTime: 2015-05-02 01:00:00 with kind = unspecified.
It should be 2015-05-02 02:00:00 for belgianTime
If you just add the source time zone to the conversion method it gives the desired answer, even without specifying the IFormatProvider.
string dateString = (string) line["stringDate"];
DateTime ukTime = DateTime.Parse(dateString);
DateTime belgianTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(ukTime,
"GMT Standard Time",
"Romance Standard Time");
This gives time Kind == Unspecified. However if you use:
var belgianTime = TimeZoneInfo.ConvertTime(ukTime,
TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time"),
TimeZoneInfo.Local);
for the conversion, you get Kind == Local
Use the following line of code.
var time = DateTime.Parse(DateTime.Now.ToString());
var clientZone = TimeZoneInfo.FindSystemTimeZoneById("India Standard Time");
var utcTime = TimeZoneInfo.ConvertTimeToUtc(time, clientZone);
You have to use the ConvertTime method. ConvertTime
a quick sample -
string s = "2015-05-02 01:00:00";
var dt = new DateTime(2015, 05, 02, 1, 0, 0);
var t = TimeZoneInfo.ConvertTime(dt, TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time"),
TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time"));

How can I create a new instance of DateTime in specific time zone?

Given a specific TimeZoneInfo instance how can I create a new DateTime instance in the specified time zone? For example if I have:
var tz = TimeZoneInfo.FindSystemTimeZoneById("US Eastern Standard Time");
var date = new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Unspecified);
Console.WriteLine(TimeZoneInfo.ConvertTime(date, tz));
I am always getting 12/31/2016 7:00:00 PM regardless of what DateTimeKind I define (Utc, Local or Unspecified).
How can I declare a new DateTime that will be January 1st of 2017 at 0:00:00 in US Eastern Standard Time?
You can use TimeZoneInfo to retrieve your zone
You can find timezones here
var zn = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
to express that you are using a local eastern standard time use DateTimeOffset struct instead of DateTime
DateTimeOffset dateTimeOffset = new DateTimeOffset(new DateTime(2017, 1, 1, 0, 0, 0, DateTimeKind.Unspecified), zn.BaseUtcOffset);
Why DateTimeOffset
DateTimeOffset is a representation of instantaneous time (also known as absolute time).
you can use the timezoneID as you are using it to specify what timezone you want to create your datetime object.
TimeZoneInfo tzone= TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard
Time");
DateTime dt = DateTime.Now;
later you just convert the datetime to your required timezone.
var datetime2 = TimeZoneInfo.ConvertTimeFromUtc(dt , tzone);
this is the link where you can find all timezones ID. TimeZoneIDs
Thank you, hope this can help you.

How to convert a datetime to specific timezone in c#?

I need help converting a DateTime to a specific time zone. What I have below is not working correctly.
gmTime = 03/02/2013 1:00:00 AM
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var time = timeZoneInfo.ConvertTime(gmTime, timeZone);
When I debug the value of time, which should be 03/01/2013 8:00:00 PM when the zone is applied, it comes back as 03/02/2013 1:00:00 AM.
If I do time.ToLocalTime() then I get the correct value. However, I need to convert time to different time zones.
DateTime objects have a "Kind" variable which helps TimeZoneInfo know how to treat it. In the MSDN documentation for TimeZone.ConvertTime it has the following:
DateTimeKind.Local, Converts the local time to the time in destinationTimeZone.
DateTimeKind.Utc, Converts Coordinated Universal Time (UTC) to the time in destinationTimeZone.
DateTimeKind.Unspecified, Assumed to be Local.
For example:
Console.WriteLine("Local time zone is '{0}'.", TimeZoneInfo.Local.Id);
var gmTime = new DateTime(2013, 03, 02, 01, 00, 00, DateTimeKind.Utc);
var localTime = new DateTime(2013, 03, 02, 01, 00, 00, DateTimeKind.Local);
var unspecifiedTime = new DateTime(2013, 03, 02, 01, 00, 00);
var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var gmTimeConverted = TimeZoneInfo.ConvertTime(gmTime, timeZone); // 03/02/2013 8:00:00AM
var localTimeConverted = TimeZoneInfo.ConvertTime(localTime, timeZone); // 03/02/2013
var unspecifiedTimeConverted = TimeZoneInfo.ConvertTime(unspecifiedTime, timeZone);
Console.WriteLine("Converting GMT to EST: {0}", gmTimeConverted);
Console.WriteLine("Converting Local to EST: {0}", localTimeConverted);
Console.WriteLine("Converting Unspecified to EST: {0}", unspecifiedTimeConverted);
Results in:
Local time zone is 'Pacific Standard Time'.
Converting GMT to EST: 3/1/2013 8:00:00 PM
Converting Local to EST: 3/2/2013 4:00:00 AM
Converting Unspecified to EST: 3/2/2013 4:00:00 AM
Or if your local timezone is 'Eastern Standard Time' you get these results
Local time zone is 'Eastern Standard Time'.
Converting GMT to EST: 3/1/2013 8:00:00 PM
Converting Local to EST: 3/2/2013 1:00:00 AM
Converting Unspecified to EST: 3/2/2013 1:00:00 AM
If you'd like TimeZoneInfo to treat 'Unspecified' like Utc, you should function like TimeZoneInfo.ConvertTimeFromUtc. Again from MSDN documentation
DateTimeKind.Local, Throws an ArgumentException.
DateTimeKind.Unspecified or DateTimeKind.Utc, Converts from Coordinated Universal Time (UTC).
Try something like the following Chace
TimeZoneInfo estTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime estDateTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, estTimeZone);
The following code will let you go from any arbitrary time zone to any other. We make use of DateTimeOffset which will allow you to pass the UTC Offset in. You may consider whether just using DateTimeOffset instead of DateTime will suit your needs. But if you want to use DateTime instead, here is some code that will do the conversion for you:
public DateTime ChangeTimeZone(DateTime dateTimeInput, TimeZoneInfo sourceTimeZone, TimeZoneInfo destTimeZone)
{
var zonedTime = new DateTimeOffset(DateTime.SpecifyKind(dateTimeInput, DateTimeKind.Unspecified),
sourceTimeZone.GetUtcOffset(dateTimeInput));
var utcTime = zonedTime.UtcDateTime;
return TimeZoneInfo.ConvertTime(utcTime, destTimeZone);
}
You may notice that we explicitly call SpecifyKind and set it to Unspecified. The reason for this is because if the Kind is specified on the dateTimeInput then the UtcOffset must match that Kind -- so if it is DateTimeKind.Utc, then that number must be 0. If it is Local, then it must be whatever the local time offset is or you will get an exception. Of course, if you already know the Kind then you could skip this function and just go straight to TimeZoneInfo.ConvertTime.

DateTimeOffset proper usage

If I have a DateTime instance which represents a valid UTC time, and an offset that converts that DateTime to the time zone where it applies, how do I construct a DateTimeOffset instance to represent this?
var utcDateTime = new DateTime(2011, 02, 29, 12, 43, 0, /*DateTimeKind.Utc*/);
var localOffset = TimeSpan.FromHours(2.0);
var dto = ...
// Here the properties should be as follows;
// dto.UtcDateTime = 2011-02-29 12:43:00
// dto.LocalDateTime = 2011-02-29 14:43:00
Perhaps I'm not understanding the DateTimeOffset structure correctly, but I'm unable to get the expected output.
Thanks in advance
Looks like you want:
var utcDateTime = new DateTime(2012, 02, 29, 12, 43, 0, DateTimeKind.Utc);
var dto = new DateTimeOffset(utcDateTime).ToOffset(TimeSpan.FromHours(2));
Note that I changed the year from 2011 (which is not a leap year and does not have 29 days in February) to 2012.
Test:
Console.WriteLine("Utc = {0}, Original = {1}", dto.UtcDateTime, dto.DateTime);
Output:
Utc = 2/29/2012 12:43:00 PM, Original = 2/29/2012 2:43:00 PM
Do note that you probably don't want the LocalDateTime property, which may represent the instant in time as of the local system's timezone.

Categories

Resources