Skip to content

Commit 090568e

Browse files
committed
Merge branch 'prime'
2 parents 1cf4012 + 93d9a6a commit 090568e

File tree

4 files changed

+41
-9
lines changed

4 files changed

+41
-9
lines changed

exch/ews/context.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,13 +1813,16 @@ void EWSContext::toContent(const std::string& dir, tCalendarItem& item, sShape&
18131813
shape.write(TAGGED_PROPVAL{PR_MESSAGE_CLASS, deconst("IPM.Appointment")});
18141814
int64_t startOffset = 0, endOffset = 0;
18151815
time_t startTime = 0, endTime = 0;
1816+
bool calcStartOffset, calcEndOffset = false;
18161817
if(item.Start) {
18171818
startTime = clock::to_time_t(item.Start.value().time);
18181819
startOffset = std::chrono::duration_cast<std::chrono::minutes>(item.Start.value().offset).count();
1820+
calcStartOffset = item.Start.value().needCalcOffset();
18191821
}
18201822
if(item.End) {
18211823
endTime = clock::to_time_t(item.End.value().time);
18221824
endOffset = std::chrono::duration_cast<std::chrono::minutes>(item.Start.value().offset).count();
1825+
calcEndOffset = item.Start.value().needCalcOffset();
18231826
}
18241827
// TODO handle no start and/or end times
18251828

@@ -2035,17 +2038,20 @@ void EWSContext::toContent(const std::string& dir, tCalendarItem& item, sShape&
20352038
shape.write(NtAppointmentTimeZoneDefinitionEndDisplay,
20362039
TAGGED_PROPVAL{PT_BINARY, temp_bin});
20372040

2038-
// If the offsets of start or end times are not set, probably
2039-
// the client didn't send the offset information in date tags.
2040-
// Try to get the offset from the timezone definition.
2041-
if(startOffset == 0 || endOffset == 0)
2041+
// If the offsets of start or end times are 0 and
2042+
// the client didn't send the offset information in date tags,
2043+
// try to get the offset from the timezone definition.
2044+
if((startOffset == 0 && calcStartOffset) || (endOffset == 0 && calcEndOffset))
20422045
{
20432046
EXT_PULL ext_pull;
20442047
TIMEZONEDEFINITION tzdef;
20452048
ext_pull.init(buf->data(), buf->size(), alloc, EXT_FLAG_UTF16);
20462049
if(ext_pull.g_tzdef(&tzdef) != EXT_ERR_SUCCESS)
20472050
throw EWS::DispatchError(E3294);
2048-
startOffset = endOffset = offset_from_tz(&tzdef, startTime);
2051+
if(calcStartOffset)
2052+
startOffset = offset_from_tz(&tzdef, startTime);
2053+
if(calcEndOffset)
2054+
endOffset = offset_from_tz(&tzdef, endTime);
20492055
}
20502056
item.Start.value().offset = std::chrono::minutes(startOffset);
20512057
item.End.value().offset = std::chrono::minutes(endOffset);

exch/ews/serialization.hpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,7 @@ struct ExplicitConvert<std::string>
131131
static tinyxml2::XMLError deserialize(const tinyxml2::XMLElement *xml, std::string &value)
132132
{
133133
const char* data = xml->GetText();
134-
if(!data)
135-
return tinyxml2::XML_NO_TEXT_NODE;
136-
value = data;
134+
value = data ? data : std::string("");
137135
return tinyxml2::XML_SUCCESS;
138136
}
139137

exch/ews/structures.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1194,6 +1194,24 @@ sTimePoint::sTimePoint(time_point tp, const tSerializableTimeZone& tz) :
11941194
/**
11951195
* @brief Create time point from date-time string
11961196
*
1197+
* As of 2025-01-27 we have identified 3 different datetime formats sent by
1198+
* the clients.
1199+
* Zulu time (UTC), no DST, no offset:
1200+
* `<t:Start>2024-04-29T19:30:00Z</t:Start>`
1201+
* With the offset information in datetime, additionally a timezone tag:
1202+
* `<t:Start>2024-11-27T13:00:00+01:00</t:Start>`
1203+
* `<t:StartTimeZone Id="W. Europe Standard Time"/>`
1204+
* `<t:EndTimeZone Id="W. Europe Standard Time"/>`
1205+
* Local time with a timezone tag, it's necessary to calculate the offset:
1206+
* `<t:Start>2024-09-25T09:00:00</t:Start>`
1207+
* ```
1208+
* <t:ExtendedProperty>
1209+
* <t:ExtendedFieldURI PropertyName="CalendarTimeZone" PropertySetId="A7B529B5-4B75-47A7-A24F-20743D6C55CD" PropertyType="String"/>
1210+
* <t:Value>Europe/Vienna</t:Value>
1211+
* </t:ExtendedProperty>
1212+
* ```
1213+
* `<t:MeetingTimeZone TimeZoneName="W. Europe Standard Time"/>`
1214+
*
11971215
* @throw DeserializationError Conversion failed
11981216
*
11991217
* @param Date-time string
@@ -1217,7 +1235,9 @@ sTimePoint::sTimePoint(const char* dtstr)
12171235
throw EWSError::ValueOutOfRange(E3152);
12181236
time = clock::from_time_t(timestamp);
12191237
time += std::chrono::duration_cast<time_point::duration>(std::chrono::duration<double>(seconds));
1220-
offset = std::chrono::minutes(60*tz_hour+(tz_hour < 0? -tz_min : tz_min));
1238+
offset = std::chrono::minutes(60 * (-tz_hour) + (tz_hour > 0 ? -tz_min : tz_min));
1239+
if(strlen(dtstr) == 19)
1240+
calcOffset = true;
12211241
}
12221242

12231243
/**
@@ -1232,6 +1252,12 @@ sTimePoint sTimePoint::fromNT(uint64_t timestamp)
12321252
uint64_t sTimePoint::toNT() const
12331253
{return rop_util_unix_to_nttime(time-offset);}
12341254

1255+
/**
1256+
* @brief Whether it's necessary to calculate the offset from timezone
1257+
*/
1258+
bool sTimePoint::needCalcOffset() const
1259+
{return calcOffset;}
1260+
12351261
///////////////////////////////////////////////////////////////////////////////////////////////////
12361262
// Types implementation
12371263

exch/ews/structures.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,9 +452,11 @@ struct sTimePoint
452452

453453
static sTimePoint fromNT(uint64_t);
454454
uint64_t toNT() const;
455+
bool needCalcOffset() const;
455456

456457
time_point time{};
457458
std::chrono::minutes offset = std::chrono::minutes(0);
459+
bool calcOffset = false;
458460
};
459461

460462
///////////////////////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)