otris/ews-cpp

Time zones

Closed this issue · 8 comments

I'm in the process of implementing the time zones. By creating a enum class with all available time zone IDs. The respective to-string and from-string functions. The option to get/set the time zone in the basic_service class. And the option to get/set the MeetingTimeZone/EndTimeZone/StartTimeZone of a calendar_item.

But right now, I can't find a way to set (or get) the time zone element in the respective function in the calendar_item class.
Other setter function in that class use xml().set_or_update(const std::string& node_name, const std::string& node_value) to add or update xml elements in the xml_subtree.
What is the best way to add (if not exists) an element and define an attribute for element.

To paint a picture, it should look like this:

<EndTimeZone Id="Central European Standard Time" />

I will create a branch for this on my fork on Monday.

Cool. I added an additional set_or_update that allows you to write code like this:

xml().set_or_update(
        "StartTimeZone",
        {{"Id", "W. Europe Standard Time"},
         {"Name",
          "(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna"}});

Does that help?

Well, it works. But with vc11 I have to:

internal::xml_subtree::attribute id_attribute = { "Id", internal::enum_to_string(time_zone) };
std::vector<internal::xml_subtree::attribute> attributes;
attributes.emplace_back(id_attribute);
xml().set_or_update("StartTimeZone", attributes);

I could use a local typedef for internal::xml_subtree::attribute but other than that, I don't see a cleaner C++11 way to implement it.

On a side note. How do I read the attribute from the xml_subtree? ;) Is there a get_attribute_from_node function or something?

Well there is

template <typename Func>
void for_each_attribute(const rapidxml::xml_node<>& node, Func func);

Otherwise I'd directly use rapidxml API for this. Something like

for (auto attr = node->first_attribute(); attr; attr = attr->next_attribute())
{
    cout << "Node foo has attribute " << attr->name() << " ";
    cout << "with value " << attr->value() << "\n";
}

BTW are you guys still on Visual Studio 2012?

Thanks for the help.
Yeah, we are still on VS2012. Though I use VS2017 but compile with the VC11 compiler.
We are planing on switching to VS2017 at the end of the year probably. (hopefully)

I have one issue right now...
As already described, when setting the time zone for a calendar item, I add the StartTimeZone node with the Id attribute containing the ID of the time zone.
But what I just found out... When receiving a calendar item, it has no StartTimeZone node anymore. But instead a StartTimeZoneId node which contains the ID as it's value.
According to the documentation of StartTimeZoneId, it's a child of CalendarItem. But the documentation of CalendarItem only lists StartTimeZone but no StartTimeZoneId.

So the getter functions for the time zones will try to get the time zone from the StartTimeZoneId node if available. And if not, it checks the StartTimeZones Id attribute. If none exist, it returns ews::time_zone::none.

Yeah, we are still on VS2012.

Yeah, we're too 😞

Anyhow, good to know. Not that we suddenly/accidentally drop support for VS2012 without you knowing.

So the getter functions for the time zones will try to get the time zone from the StartTimeZoneId node if available. And if not, it checks the StartTimeZones Id attribute. If none exist, it returns ews::time_zone::none.

Sounds reasonable to me.

Done, right?