View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0003822 | SOGo | ActiveSync | public | 2016-09-27 04:29 | 2016-10-03 13:12 |
| Reporter | rogiervandervelde | Assigned To | ludovic | ||
| Priority | normal | Severity | minor | Reproducibility | always |
| Status | resolved | Resolution | fixed | ||
| Platform | [Server] Linux | OS | RHEL/CentOS | OS Version | 6 |
| Product Version | 3.1.5 | ||||
| Target Version | 3.2.0 | Fixed in Version | 3.2.0 | ||
| Summary | 0003822: Recurring events with timezones are not on the correct time in Outlook | ||||
| Description | When creating and event in the webcalendar, the timezone in Outlook is displayed as (UTC+09:00) Jakoetsk, althought the timezone is Asia/Tokyo (also +9:00) on the server and client. It is displayed at the correct time however. When changing this event to a recurring event in the webcalendar, the event jumps back 9 hours in Outlook. This also is happening when creating a new recurring event in the webcalendar. | ||||
| Additional Information | This machine has moved from Europe to Japan, so there are also old events with a different timezone in the database. But I've just tried with a fresh install and the result is the same, the event jumps back 9 hours after changing it to a recurring event. | ||||
| Tags | No tags attached. | ||||
|
collection_event.txt (2,587 bytes)
<Collection>
<Class>Calendar</Class>
<SyncKey>1474957993</SyncKey>
<CollectionId>vevent%2Fpersonal</CollectionId>
<Status>1</Status>
<Commands>
<Add>
<ServerId>1B2-57EA1280-1-417A8880</ServerId>
<ApplicationData>
<AllDayEvent xmlns="Calendar:">0</AllDayEvent>
<DTStamp xmlns="Calendar:">20160927T063313Z</DTStamp>
<StartTime xmlns="Calendar:">20160929T060000Z</StartTime>
<EndTime xmlns="Calendar:">20160929T064500Z</EndTime>
<TimeZone xmlns="Calendar:">5P3//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADoXAAA8H8AAOhc8/LwfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD
QnVvv8H8AAOhc8/LwfwAAHAIAAA==</TimeZone>
<MeetingStatus xmlns="Calendar:">0</MeetingStatus>
<Subject xmlns="Calendar:">test</Subject>
<Location xmlns="Calendar:">test</Location>
<UID xmlns="Calendar:">1B2-57EA1280-1-417A8880</UID>
<Sensitivity xmlns="Calendar:">0</Sensitivity>
<NativeBodyType xmlns="AirSyncBase:">1</NativeBodyType>
</ApplicationData>
</Add>
</Commands>
</Collection>
<Collection>
<Class>Calendar</Class>
<SyncKey>1474958060</SyncKey>
<CollectionId>vevent%2Fpersonal</CollectionId>
<Status>1</Status>
<Commands>
<Change>
<ServerId>1B2-57EA1280-1-417A8880</ServerId>
<ApplicationData>
<AllDayEvent xmlns="Calendar:">0</AllDayEvent>
<DTStamp xmlns="Calendar:">20160927T063313Z</DTStamp>
<StartTime xmlns="Calendar:">20160929T060000Z</StartTime>
<EndTime xmlns="Calendar:">20160929T064500Z</EndTime>
<TimeZone xmlns="Calendar:">5P3//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIiwAA8H8AAMiL6vLwfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD
QnVvv8H8AAMiL6vLwfwAAHAIAAA==</TimeZone>
<MeetingStatus xmlns="Calendar:">0</MeetingStatus>
<Subject xmlns="Calendar:">test</Subject>
<Location xmlns="Calendar:">test</Location>
<UID xmlns="Calendar:">1B2-57EA1280-1-417A8880</UID>
<Recurrence xmlns="Calendar:">
<Recurrence_DayOfWeek>16</Recurrence_DayOfWeek>
<Recurrence_Interval>1</Recurrence_Interval>
<Recurrence_Type>1</Recurrence_Type>
</Recurrence>
<Sensitivity xmlns="Calendar:">0</Sensitivity>
<NativeBodyType xmlns="AirSyncBase:">1</NativeBodyType>
</ApplicationData>
</Change>
</Commands>
</Collection>
|
|
|
Can you please show the raw ics data of the events. |
|
|
TEST (web).ics (604 bytes)
BEGIN:VCALENDAR PRODID:-//Inverse inc./SOGo 3.1.5//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Tokyo X-LIC-LOCATION:Asia/Tokyo BEGIN:STANDARD TZOFFSETFROM:+0900 TZOFFSETTO:+0900 TZNAME:JST DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE BEGIN:VEVENT UID:64A-57EE2300-1-323C4640 SUMMARY:TEST LOCATION:test DESCRIPTION:TEST CLASS:PUBLIC X-SOGO-SEND-APPOINTMENT-NOTIFICATIONS:NO RRULE:FREQ=WEEKLY DTSTART;TZID=Asia/Tokyo:20160930T150000 DTEND;TZID=Asia/Tokyo:20160930T160000 CREATED:20160930T083123Z DTSTAMP:20160930T083123Z LAST-MODIFIED:20160930T083123Z END:VEVENT END:VCALENDAR |
|
|
TEST (Outlook).ics (973 bytes)
BEGIN:VCALENDAR PRODID:-//Microsoft Corporation//Outlook 16.0 MIMEDIR//EN VERSION:2.0 METHOD:PUBLISH X-MS-OLK-FORCEINSPECTOROPEN:TRUE BEGIN:VTIMEZONE TZID:Yakutsk Standard Time BEGIN:STANDARD DTSTART:16010101T000000 TZOFFSETFROM:+0900 TZOFFSETTO:+0900 END:STANDARD END:VTIMEZONE BEGIN:VEVENT CLASS:PUBLIC CREATED:20160930T083435Z DESCRIPTION:TEST DTEND;TZID="Yakutsk Standard Time":20160930T070000 DTSTAMP:20160930T083435Z DTSTART;TZID="Yakutsk Standard Time":20160930T060000 LAST-MODIFIED:20160930T083435Z LOCATION:test RRULE:FREQ=WEEKLY;BYDAY=FR SEQUENCE:0 SUMMARY:TEST UID:64A-57EE2300-1-323C4640 X-ALT-DESC;FMTTYPE=text/html:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//E N">\n<HTML>\n<HEAD>\n<META NAME="Generator" CONTENT="MS Exchange Server ve rsion rmj.rmm.rup.rpr">\n<TITLE></TITLE>\n</HEAD>\n<BODY>\n<!-- Converted from text/plain format -->\n\n<P><FONT SIZE=2>TEST</FONT>\n</P>\n\n</BODY> \n</HTML> END:VEVENT END:VCALENDAR |
|
|
I've uploaded the same event twice, one is the ics data from the web interface (web), the other from Outlook. The timezone is different (the happens to non-recurring events as well, if you want an example of this, I can upload them as well). Compiling from source is no problem, currently running a selfcompiled version from the 3.1.5 source. |
|
|
3822.diff (3,627 bytes)
diff --git a/ActiveSync/iCalRecurrenceRule+ActiveSync.m b/ActiveSync/iCalRecurrenceRule+ActiveSync.m
index 621d6f8..66c778c 100644
--- a/ActiveSync/iCalRecurrenceRule+ActiveSync.m
+++ b/ActiveSync/iCalRecurrenceRule+ActiveSync.m
@@ -37,6 +37,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <NGCards/iCalEvent.h>
#import <NGCards/iCalByDayMask.h>
+#import <NGCards/iCalDateTime.h>
+#import <NGCards/iCalTimeZone.h>
+
#import "NSCalendarDate+ActiveSync.h"
#import "NSDate+ActiveSync.h"
@@ -90,7 +93,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
// No byDayMask, we take the event's start date to compute the DayOfWeek
// 0 == Sunday, 6 == Saturday
- v = (1 << [[[self parent] startDate] dayOfWeek]);
+ v = (1 << [[[(iCalDateTime *)[[self parent] firstChildWithTag: @"dtstart"] timeZone] computedDateForDate: [[self parent] startDate]] dayOfWeek]);
}
[s appendFormat: @"<Recurrence_DayOfWeek xmlns=\"Calendar:\">%d</Recurrence_DayOfWeek>", v];
@@ -140,7 +143,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Simple reccurrence rule of type "Monthly"
type = 2;
[s appendFormat: @"<Recurrence_DayOfMonth xmlns=\"Calendar:\">%d</Recurrence_DayOfMonth>",
- (int)[[[self parent] startDate] dayOfMonth]];
+ (int)[[[(iCalDateTime *)[[self parent] firstChildWithTag: @"dtstart"] timeZone] computedDateForDate: [[self parent] startDate]] dayOfMonth]];
}
}
else if ([self frequency] == iCalRecurrenceFrequenceYearly)
@@ -179,9 +182,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
type = 5;
[s appendFormat: @"<Recurrence_DayOfMonth xmlns=\"Calendar:\">%d</Recurrence_DayOfMonth>",
- (int)[[[self parent] startDate] dayOfMonth]];
+ (int)[[[(iCalDateTime *)[[self parent] firstChildWithTag: @"dtstart"] timeZone] computedDateForDate: [[self parent] startDate]] dayOfMonth]];
[s appendFormat: @"<Recurrence_MonthOfYear xmlns=\"Calendar:\">%d</Recurrence_MonthOfYear>",
- (int)[[[self parent] startDate] monthOfYear]];
+ (int)[[[(iCalDateTime *)[[self parent] firstChildWithTag: @"dtstart"] timeZone] computedDateForDate: [[self parent] startDate]] monthOfYear]];
}
}
diff --git a/ActiveSync/iCalTimeZone+ActiveSync.m b/ActiveSync/iCalTimeZone+ActiveSync.m
index c4c0071..0842535 100644
--- a/ActiveSync/iCalTimeZone+ActiveSync.m
+++ b/ActiveSync/iCalTimeZone+ActiveSync.m
@@ -128,7 +128,7 @@ struct SYSTEMTIME {
//uint16_t wStandardYear;
struct SYSTEMTIME stStandardDate;
//uint16_t wDaylightYear;
- struct SYSTEMTIME stDaylightDate;
+ struct SYSTEMTIME stDaylightDate ={0,0,0,0,0,0,0,0};
char standardName[64], daylightName[64];
@@ -144,13 +144,17 @@ struct SYSTEMTIME {
period = [self _mostRecentPeriodWithName: @"DAYLIGHT"];
if (!period)
- stStandardDate.wMonth = 0;
-
- lDaylightBias = (uint32_t) -([period secondsOffsetFromGMT] / 60) - lBias;
- [period _fillTZDate: &stDaylightDate];
- //wStandardYear = stStandardDate.wYear;
- //wDaylightYear = stDaylightDate.wYear;
-
+ {
+ stStandardDate.wMonth = 0;
+ lDaylightBias = 0;
+ }
+ else
+ {
+ lDaylightBias = (uint32_t) -([period secondsOffsetFromGMT] / 60) - lBias;
+ [period _fillTZDate: &stDaylightDate];
+ //wStandardYear = stStandardDate.wYear;
+ //wDaylightYear = stDaylightDate.wYear;
+ }
// We build the timezone
[bytes appendBytes: &lBias length: 4];
|
|
|
Please test attached patch and provide feedback. |
|
|
3822-2.diff (3,988 bytes)
diff --git a/ActiveSync/iCalRecurrenceRule+ActiveSync.m b/ActiveSync/iCalRecurrenceRule+ActiveSync.m
index 621d6f8..786a31e 100644
--- a/ActiveSync/iCalRecurrenceRule+ActiveSync.m
+++ b/ActiveSync/iCalRecurrenceRule+ActiveSync.m
@@ -37,11 +37,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <NGCards/iCalEvent.h>
#import <NGCards/iCalByDayMask.h>
+#import <NGCards/iCalDateTime.h>
+#import <NGCards/iCalTimeZone.h>
+
#import "NSCalendarDate+ActiveSync.h"
#import "NSDate+ActiveSync.h"
@implementation iCalRecurrenceRule (ActiveSync)
+- (NSCalendarDate *) _getAdjustedStartDate
+{
+ iCalTimeZone *timeZone;
+
+ timeZone = [(iCalDateTime *)[[self parent] firstChildWithTag: @"dtstart"] timeZone];
+ if (timeZone)
+ return [timeZone computedDateForDate: [[self parent] startDate]];
+ else
+ return [[self parent] startDate];
+}
+
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context
{
NSMutableString *s;
@@ -90,7 +104,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
// No byDayMask, we take the event's start date to compute the DayOfWeek
// 0 == Sunday, 6 == Saturday
- v = (1 << [[[self parent] startDate] dayOfWeek]);
+ v = (1 << [[self _getAdjustedStartDate] dayOfWeek]);
}
[s appendFormat: @"<Recurrence_DayOfWeek xmlns=\"Calendar:\">%d</Recurrence_DayOfWeek>", v];
@@ -139,8 +153,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
// Simple reccurrence rule of type "Monthly"
type = 2;
- [s appendFormat: @"<Recurrence_DayOfMonth xmlns=\"Calendar:\">%d</Recurrence_DayOfMonth>",
- (int)[[[self parent] startDate] dayOfMonth]];
+ [s appendFormat: @"<Recurrence_DayOfMonth xmlns=\"Calendar:\">%d</Recurrence_DayOfMonth>", [[self _getAdjustedStartDate] dayOfMonth]];
}
}
else if ([self frequency] == iCalRecurrenceFrequenceYearly)
@@ -178,10 +191,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
else
{
type = 5;
- [s appendFormat: @"<Recurrence_DayOfMonth xmlns=\"Calendar:\">%d</Recurrence_DayOfMonth>",
- (int)[[[self parent] startDate] dayOfMonth]];
- [s appendFormat: @"<Recurrence_MonthOfYear xmlns=\"Calendar:\">%d</Recurrence_MonthOfYear>",
- (int)[[[self parent] startDate] monthOfYear]];
+ [s appendFormat: @"<Recurrence_DayOfMonth xmlns=\"Calendar:\">%d</Recurrence_DayOfMonth>", [[self _getAdjustedStartDate] dayOfMonth]];
+ [s appendFormat: @"<Recurrence_MonthOfYear xmlns=\"Calendar:\">%d</Recurrence_MonthOfYear>", [[self _getAdjustedStartDate] monthOfYear]];
}
}
diff --git a/ActiveSync/iCalTimeZone+ActiveSync.m b/ActiveSync/iCalTimeZone+ActiveSync.m
index c4c0071..0842535 100644
--- a/ActiveSync/iCalTimeZone+ActiveSync.m
+++ b/ActiveSync/iCalTimeZone+ActiveSync.m
@@ -128,7 +128,7 @@ struct SYSTEMTIME {
//uint16_t wStandardYear;
struct SYSTEMTIME stStandardDate;
//uint16_t wDaylightYear;
- struct SYSTEMTIME stDaylightDate;
+ struct SYSTEMTIME stDaylightDate ={0,0,0,0,0,0,0,0};
char standardName[64], daylightName[64];
@@ -144,13 +144,17 @@ struct SYSTEMTIME {
period = [self _mostRecentPeriodWithName: @"DAYLIGHT"];
if (!period)
- stStandardDate.wMonth = 0;
-
- lDaylightBias = (uint32_t) -([period secondsOffsetFromGMT] / 60) - lBias;
- [period _fillTZDate: &stDaylightDate];
- //wStandardYear = stStandardDate.wYear;
- //wDaylightYear = stDaylightDate.wYear;
-
+ {
+ stStandardDate.wMonth = 0;
+ lDaylightBias = 0;
+ }
+ else
+ {
+ lDaylightBias = (uint32_t) -([period secondsOffsetFromGMT] / 60) - lBias;
+ [period _fillTZDate: &stDaylightDate];
+ //wStandardYear = stStandardDate.wYear;
+ //wDaylightYear = stDaylightDate.wYear;
+ }
// We build the timezone
[bytes appendBytes: &lBias length: 4];
|
|
|
Modified patch to also deal with allday-events. |
|
|
I've tried the patch (both) on my test system, and it seems to solve the problem. The calendar shows on the correct date/timezone in Outlook, but timezone changes in Outlook are converted to localtime on the backend however, so timezone information is lost (although the time itself is correct). |
|
|
Currently the timezone sent by the client is not used during the event update, user's timezone specified in SOGo is used instead. |
|
|
Then the problem is solved as far as I can tell, thank you very much! |
|
|
Applied a slightly modified version of the patch. |
|
|
sogo: master 23fa9c0e 2016-10-03 08:59 Details Diff |
(fix) fixed recurring events with timezones for EAS (fixes 0003822) |
Affected Issues 0003822 |
|
| mod - ActiveSync/iCalRecurrenceRule+ActiveSync.m | Diff File | ||
| mod - ActiveSync/iCalTimeZone+ActiveSync.m | Diff File | ||
|
sogo: v2 665367f8 2016-10-03 08:59 Details Diff |
(fix) fixed recurring events with timezones for EAS (fixes 0003822) |
Affected Issues 0003822 |
|
| mod - ActiveSync/iCalRecurrenceRule+ActiveSync.m | Diff File | ||
| mod - ActiveSync/iCalTimeZone+ActiveSync.m | Diff File | ||
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2016-09-27 04:29 | rogiervandervelde | New Issue | |
| 2016-09-27 06:49 | rogiervandervelde | File Added: collection_event.txt | |
| 2016-09-30 07:43 | tfu | Note Added: 0010709 | |
| 2016-09-30 08:37 | rogiervandervelde | File Added: TEST (web).ics | |
| 2016-09-30 08:37 | rogiervandervelde | File Added: TEST (Outlook).ics | |
| 2016-09-30 08:41 | rogiervandervelde | Note Added: 0010710 | |
| 2016-09-30 21:04 | tfu | File Added: 3822.diff | |
| 2016-09-30 21:08 | tfu | Note Added: 0010712 | |
| 2016-10-01 07:26 | tfu | File Added: 3822-2.diff | |
| 2016-10-01 07:27 | tfu | Note Added: 0010713 | |
| 2016-10-01 15:39 | rogiervandervelde | Note Added: 0010714 | |
| 2016-10-01 21:40 | tfu | Note Added: 0010715 | |
| 2016-10-02 12:57 | rogiervandervelde | Note Added: 0010716 | |
| 2016-10-02 13:46 | ludovic | Target Version | => 3.2.0 |
| 2016-10-03 13:02 | ludovic | Changeset attached | => sogo master 23fa9c0e |
| 2016-10-03 13:02 | ludovic | Assigned To | => ludovic |
| 2016-10-03 13:02 | ludovic | Resolution | open => fixed |
| 2016-10-03 13:03 | ludovic | Changeset attached | => sogo v2 665367f8 |
| 2016-10-03 13:12 | ludovic | Note Added: 0010718 | |
| 2016-10-03 13:12 | ludovic | Status | new => resolved |
| 2016-10-03 13:12 | ludovic | Fixed in Version | => 3.2.0 |