I have the following code, which should return an offset of 60 (to show that in the UK at present, we are in British Summer Time - ie. 60 minutes ahead of GMT):
var info = TimeZoneInfo.FindSystemTimeZoneById("Greenwich Standard Time");
DateTimeOffset localServerTime = DateTimeOffset.Now;
double off = localServerTime.Offset.TotalMinutes;
return off;
However, it returns 0.
Could anyone please help fix this for me?
Use TimeZoneInfo.IsDaylightSavingTime Method (DateTimeOffset) to find if it is currently Daylight saving for your Timezone.
var info = TimeZoneInfo.FindSystemTimeZoneById("Greenwich Standard Time");
DateTimeOffset localServerTime = DateTimeOffset.Now;
bool isDaylightSaving = info.IsDaylightSavingTime(localServerTime);
There are further examples here
Your machine is not configured correctly if you get 0 and live in the UK. Probable causes are:
The machine's time zone is not set correctly. Click the clock on the taskbar to correct.
The machine is not configured to observe daylight savings. Click the clock.
The database that TimeZoneInfo consults for daylight savings rules in out of date or corrupted. It is stored in the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones registry key.
Be careful about making radical changes, having it configured wrong might well have been done intentionally to work around some kind of flaw in a business-critical app that runs on the server. Talk to whomever administers the server first.
Another option is to use Noda Time.
The following code works with Noda Time 1.4 and higher:
var zone = NodaTime.TimeZones.TzdbDateTimeZoneSource.Default.ForId("Europe/London");
var zonedClock = NodaTime.SystemClock.Instance.InZone(zone);
var zonedDateTime = zonedClock.GetCurrentZonedDateTime();
bool isDST = zonedDateTime.IsDaylightSavingTime();
Console.WriteLine(isDST);
zone is a DateTimeZone object representing the UK's timezone, "Europe/London"
zonedClock is a ZonedClock object which represents, in this case, the system clock and the UK's timezone
zonedDateTime is a ZonedDateTime object representing the current date and time in the timezone ("the current instant provided by the underlying clock, adjusted to the time zone of this object")
isDST is a boolean indicating whether the current instant is in DST or not. At the time of writing (April 2018) this evaluates to true
With earlier versions of Noda where ZonedClock is not available, we can do this instead:
var zone = NodaTime.TimeZones.TzdbDateTimeZoneSource.Default.ForId("Europe/London");
var now = Instant.FromDateTimeOffset(DateTimeOffset.Now);
var zonedDateTime = new ZonedDateTime(now, zone);
bool isDST = zonedDateTime.IsDaylightSavingTime();
To master conversion from one timezone to anther you need to see what's supported (how?) and what's not.
foreach (var tz in TimeZoneInfo.GetSystemTimeZones())
{
Console.WriteLine("TimeZone Offset: {0} Name : {1}, Supports DLS: {2}", tz.BaseUtcOffset,tz.StandardName,tz.SupportsDaylightSavingTime);
}
This should give you the list all timezones including info about DayLightSaving.
Notice that:
TimeZone Offset: 00:00:00 Name : Greenwich Standard Time, Supports DLS: False
TimeZone Offset: 00:00:00 Name : GMT Standard Time, Supports DLS: True
So you need to use "GMT Standard Time" because it supports daylight saving already. No work needs to be done.
Here is sample code:
private static string GetBSTTimeStamp(string timestamp)
{
DateTime dt = DateTime.Parse(timestamp);
//TimeZoneInfo bst = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
//Console.WriteLine("Time zone supports dls? {0}", bst.SupportsDaylightSavingTime);
//Console.WriteLine("Time zone offset? {0}", bst.BaseUtcOffset);
DateTime dateTimeInUtc = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(dt, "Eastern Standard Time", "GMT Standard Time");
return dateTimeInUtc.ToString();
}
Related
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);
I am trying to convert date to UTC format where I can get correct offset. I am using ToString("O") in simple DateTime.Now which works.
Now when I am converting my current time (EST) to CST (Central) or MST (Mountain) then I am not getting offset. What am I missing here? Is there any other way to do it?
Code:
var currentTimeToUtc = DateTime.Now.ToString("O");
// Output = "2018-12-27T12:31:21.9946661-05:00" --This is perfect.
var centralTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.Now, "Central Standard Time");
var centralTimeToUtc = centralTime.ToString("O");
// Output = "2018-12-27T11:31:19.8046052"
// Expected Output = "2018-12-27T11:31:19.8046052-06:00"
var mountainTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.Now, "Mountain Standard Time");
var mountainTimeToUtc = mountainTime.ToString("O");
// Output = "2018-12-27T10:31:25.2438418"
// Expected Output = "2018-12-27T10:31:25.2438418-07:00"
This is the expected behavior of DateTime. If you need to keep time zone information, use DateTimeOffset instead.
The reason for the difference in the output is that DateTime.Now and centralTime / mountainTime are of different kind: DateTime before conversion is Local, but after conversion it becomes Unspecified.
Run the program below to confirm this:
var now = DateTime.Now;
Console.WriteLine(now.Kind);
var centralTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(now, "Central Standard Time");
Console.WriteLine(centralTime.Kind);
var mountainTime = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(now, "Mountain Standard Time");
Console.WriteLine(mountainTime.Kind);
The behavior cannot be changed because DateTime does not store offset; it relies on two well-known offsets for interpretation of the time zone - Local means your local time zone, and UTC means UTC time zone.
The third option, Unspecified, means that the value of DateTime cannot be interpreted as an absolute value by itself, because time zone has been stripped from it. Your code knows what time zone it is, because you did the conversion, but the information about the time zone is part of your program's design, not part of the corresponding DateTime object. .NET added DateTimeOffset objects specifically to address this problem.
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
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");
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.