1
votes

I've looked through the wss 3.0 documentation, but I can't find anything. I would like to retrieve the locale for a Sharepoint 2007 site using web services (no access to server so can't deploy anything on it), so as to know what time zone is site the configured in. Is that possible?

thx

2

2 Answers

1
votes

The time zone of a SharePoint web site can be obtained by the GetList method of the Lists web service. It seems weird to ask for information about a list to get regional settings of a web site but that's it :-)

This is an excerpt of the method response about a single list:

<List>
  ...
  <RegionalSettings>
    <Language>1033</Language>
    <Locale>1033</Locale>
    <AdvanceHijri>0</AdvanceHijri>
    <CalendarType>1</CalendarType>
    <Time24>False</Time24>
    <TimeZone>-60</TimeZone>
    <SortOrder>2070</SortOrder>
    <Presence>True</Presence>
  </RegionalSettings>
  ...
</List>

The time zone is returned as an offset to the UTC time in minutes. If you add it to the time in the web site local time zone you will get the time in the UTC time zone. (If you want to get the correct value you will have to consider the daylight saving changes and apply them according to the season of the time.).

// Instantiate the web service. Don't forget to dispose it later.
// Append the web service suffix (/_vti_bin/Lists.asmx) to the URL
// of the web site which time zone of you are interested in.
// If you don't use IWA or the current user has no access to the
// web site set the service.Credentials instead.
var service = new Lists();
service.Url = "http://myhost/sites/mysite/_vti_bin/Lists.asmx";
service.UseDefaultCredentials = true;
// Get all lists from the web site you want to get the time zone of.
// Get the XML element at /Lists/List[1]. It can be any accessible list.
// We will use just the unique list identifier from the atribute ID.
var lists = service.GetListCollection();
var list = lists.ChildNodes.OfType<XmlElement>().FirstOrDefault();
if (list == null)
    throw new ApplicationException("The web has no lists.");
// Get information about the list which a little about the web too.
// Get the XML element at /List/RegionalSettings/TimeZone.
list = (XmlElement) service.GetList(list.GetAttribute("ID"));
var regionalSettings = list.ChildNodes.OfType<XmlElement>().First(
    item => item.LocalName == "RegionalSettings");
var timeZone = regionalSettings.ChildNodes.OfType<XmlElement>().First(
    item => item.LocalName == "TimeZone");
// The offset can be added to the time in the web site local time zone
// to get the UTC time. For example, UTC+1 has the offset -60 minutes.
var utcOffset = new TimeSpan(0, int.Parse(timeZone.InnerText), 0);

--- Ferda

1
votes

Ok, here's what I did to solve this:

  • make a query to the list for 1 element, getting times set for site's locale
  • make a query for that element, getting times in UTC
  • calculate the difference between the 2 results.

Code:

    /// <summary>
    /// Gets the difference between local time and UTC to calculate offset.
    /// Makes a query to the list that returns 1 element with times using the locale as set in the site's settings.
    /// Then makes another query for the same element with UTC times to calculate the difference.
    /// </summary>
    /// <param name="list">list to query</param>
    /// <param name="client">WS object</param>
    /// <returns>Time offset as TimeSpan object</returns>
    private TimeSpan getSiteTZOffset(List list, WSLists.Lists client )
    {
        //Set up query parameters
        XmlDocument xmlDoc = new XmlDocument();
        XmlNode emptyQuery = xmlDoc.CreateNode(XmlNodeType.Element, "Query", "");
        XmlNode queryWithID = xmlDoc.CreateNode(XmlNodeType.Element, "Query", "");

        XmlNode ndOptions = xmlDoc.CreateNode(XmlNodeType.Element, "QueryOptions", "");
        ndOptions.InnerXml = "<DateInUtc>True</DateInUtc>";

        XmlNamespaceManager xnm = new XmlNamespaceManager(xmlDoc.NameTable);
        xnm.AddNamespace("z", "#RowsetSchema");

        // Gets the attribute that serves as modified date
        MapAttribute modifiedDateAttr = attributes.Single(x => x.Value.DateTimeModifiedField).Value;
        // Gets the Id attribute
        MapAttribute idAttr = attributes.Single(x => x.Value.KeyReference).Value;

        //Get 1 result with site's local time
        XmlNode resLocalTime = client.GetListItems(list.ListID, list.ViewID, emptyQuery, null, "1", null, null);
        XmlNodeList itemsLocalTime = resLocalTime.SelectNodes("//z:row", xnm);

        // 2nd query filters on ID of the item returned by 1st query
        queryWithID.InnerXml = string.Format("<Where><Eq><FieldRef Name='ID' /><Value Type='Counter'>{0}</Value></Eq></Where>",
            itemsLocalTime[0].Attributes[idAttr.Name].Value);

        //get the result with UTC time
        XmlNode resUtc = client.GetListItems(list.ListID, list.ViewID, queryWithID, null, "1", ndOptions, null);
        XmlNodeList itemsUtc = resUtc.SelectNodes("//z:row", xnm);

        //Converts string values to DateTime objects
        DateTime localTime = DateTime.Parse(itemsLocalTime[0].Attributes[modifiedDateAttr.Name].Value);
        DateTime utcTime = getUtcTime(itemsUtc[0].Attributes[modifiedDateAttr.Name].Value);
        // Gets offset
        TimeSpan offset = localTime - utcTime;

        return offset;
    }