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 |