Friday, July 30, 2010

Convert Date Time to SharePoint Site Time Zone

Here was the requirement to default to the current date in a list field if there was no input by the user. You may think that's easy, just use DateTime.Now. The problem is the sharepoint site regional settings is set with a different time zone than that of the time zone of the machine hosting SharePoint.

So for example if the machine hosting sharepoint is in the time zone (UTC+05.30) Sri Jayawardenepura (Sri Lanka) and the current time is 06.00 PM and the SharePoint site has the regional settings time zone set to (GMT) Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London a call to DateTime.Now will return the date time in Sri Jayawardenepura - 06.00PM.
What we need is the time at London - 01.30 PM. Keep in mind that if the time zone observes daylight saving then we need to account for that. Given that the current date falls within the date span they observe daylight saving I'm going with a +04.30 time difference as opposed to a +05.30 time difference. I referenced this blog post before I came up with this code.


DateTime dateTime = DateTime.Now;
int timeZoneBiasMinutes = 0;

// convert to utc time
DateTime adjustedDateTime = dateTime.ToUniversalTime();

// timezone in site regional settings
SPTimeZoneInformation timezoneInformation =
SPContext.Current.Web.RegionalSettings.TimeZone.Information;

// timezone difference from utc time
timeZoneBiasMinutes = timezoneInformation.Bias;

// get daylight date start date
SPSystemTime timezoneDaylightDate = timezoneInformation.DaylightDate;

if (timezoneDaylightDate.Month > 0)
{
DateTime daylightDate = new DateTime(
dateTime.Year,
timezoneDaylightDate.Month,
timezoneDaylightDate.Day);

// get standard date start date
SPSystemTime timezoneStandardDate = timezoneInformation.StandardDate;

// handle daylight saving overlapping to next year
int standardDateYear = 0;
if (timezoneStandardDate.Month > timezoneDaylightDate.Month)
{
standardDateYear = dateTime.Year;
}
else
{
standardDateYear = dateTime.Year + 1;
}

DateTime standardDate = new DateTime(standardDateYear,timezoneStandardDate.Month, timezoneStandardDate.Day);

// adjust for daylight saving
if (((dateTime.CompareTo(daylightDate) > 0)
(dateTime.CompareTo(daylightDate) == 0)) &&
(dateTime.CompareTo(standardDate) <> 0)
{
timeZoneBiasMinutes = -timeZoneBiasMinutes;
}
else
{
timeZoneBiasMinutes = Math.Abs(timeZoneBiasMinutes);
}

// adjust based on daylight saving
adjustedDateTime = ((DateTime)adjustedDateTime).AddMinutes(timeZoneBiasMinutes);

}