Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
6
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
ical4android
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Labels
Merge Requests
0
Merge Requests
0
Requirements
Requirements
List
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Environments
Analytics
Analytics
CI / CD
Code Review
Insights
Issue
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
bitfire web engineering
ical4android
Commits
fe0b1bf5
Commit
fe0b1bf5
authored
Nov 06, 2016
by
Ricki Hirner
🐑
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Better handling of events without dtend/duration
parent
6198f476
Pipeline
#4888218
passed with stage
in 7 minutes and 17 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
55 additions
and
63 deletions
+55
-63
src/androidTest/java/at/bitfire/ical4android/AndroidEventTest.java
...idTest/java/at/bitfire/ical4android/AndroidEventTest.java
+13
-0
src/main/java/at/bitfire/ical4android/AndroidEvent.java
src/main/java/at/bitfire/ical4android/AndroidEvent.java
+33
-22
src/main/java/at/bitfire/ical4android/Event.java
src/main/java/at/bitfire/ical4android/Event.java
+0
-32
src/test/java/at/bitfire/ical4android/EventTest.java
src/test/java/at/bitfire/ical4android/EventTest.java
+9
-9
No files found.
src/androidTest/java/at/bitfire/ical4android/AndroidEventTest.java
View file @
fe0b1bf5
...
...
@@ -15,6 +15,7 @@ import android.Manifest;
import
android.accounts.Account
;
import
android.content.ContentProviderClient
;
import
android.content.ContentUris
;
import
android.content.ContentValues
;
import
android.net.Uri
;
import
android.os.RemoteException
;
import
android.provider.CalendarContract
;
...
...
@@ -271,4 +272,16 @@ public class AndroidEventTest extends InstrumentationTestCase {
assertTrue
(
event2
.
isAllDay
());
}
public
void
testPopulateEventWithoutDuration
()
throws
RemoteException
,
FileNotFoundException
,
CalendarStorageException
{
ContentValues
values
=
new
ContentValues
();
values
.
put
(
CalendarContract
.
Events
.
CALENDAR_ID
,
calendar
.
id
);
values
.
put
(
CalendarContract
.
Events
.
DTSTART
,
1381330800000L
);
values
.
put
(
CalendarContract
.
Events
.
EVENT_TIMEZONE
,
"Europe/Vienna"
);
values
.
put
(
CalendarContract
.
Events
.
TITLE
,
"Without dtend/duration"
);
Uri
uri
=
provider
.
insert
(
syncAdapterURI
(
CalendarContract
.
Events
.
CONTENT_URI
),
values
);
@Cleanup
(
"delete"
)
TestEvent
testEvent
=
new
TestEvent
(
calendar
,
ContentUris
.
parseId
(
uri
));
assertNull
(
testEvent
.
getEvent
().
dtEnd
);
}
}
src/main/java/at/bitfire/ical4android/AndroidEvent.java
View file @
fe0b1bf5
...
...
@@ -47,6 +47,7 @@ import net.fortuna.ical4j.model.property.Action;
import
net.fortuna.ical4j.model.property.Attendee
;
import
net.fortuna.ical4j.model.property.Description
;
import
net.fortuna.ical4j.model.property.DtEnd
;
import
net.fortuna.ical4j.model.property.DtStart
;
import
net.fortuna.ical4j.model.property.Duration
;
import
net.fortuna.ical4j.model.property.ExDate
;
import
net.fortuna.ical4j.model.property.ExRule
;
...
...
@@ -157,27 +158,33 @@ public abstract class AndroidEvent {
final
boolean
allDay
=
values
.
getAsInteger
(
Events
.
ALL_DAY
)
!=
0
;
final
long
tsStart
=
values
.
getAsLong
(
Events
.
DTSTART
);
final
Long
tsEnd
=
values
.
getAsLong
(
Events
.
DTEND
);
final
String
duration
=
values
.
getAsString
(
Events
.
DURATION
);
String
tzId
;
Long
tsEnd
=
values
.
getAsLong
(
Events
.
DTEND
);
if
(
allDay
)
{
event
.
setDtStart
(
tsStart
,
null
);
if
(
tsEnd
==
null
&&
duration
!=
null
)
{
Dur
dur
=
new
Dur
(
duration
);
java
.
util
.
Date
dEnd
=
dur
.
getTime
(
new
java
.
util
.
Date
(
tsStart
));
tsEnd
=
dEnd
.
getTime
();
}
event
.
setDtEnd
(
tsEnd
,
null
);
// use DATE values
event
.
dtStart
=
new
DtStart
(
new
Date
(
tsStart
));
if
(
tsEnd
!=
null
)
event
.
dtEnd
=
new
DtEnd
(
new
Date
(
tsEnd
));
else
if
(
duration
!=
null
)
event
.
duration
=
new
Duration
(
new
Dur
(
duration
));
}
else
{
// use the start time zone for the end time, too
// because apps like Samsung Planner allow the user to change "the" time zone but change the start time zone only
tzId
=
values
.
getAsString
(
Events
.
EVENT_TIMEZONE
);
event
.
setDtStart
(
tsStart
,
tzId
);
if
(
tsEnd
!=
null
)
event
.
setDtEnd
(
tsEnd
,
tzId
);
else
if
(!
StringUtils
.
isEmpty
(
duration
))
// use DATE-TIME values
TimeZone
tz
=
null
;
String
tzId
=
values
.
getAsString
(
Events
.
EVENT_TIMEZONE
);
if
(
tzId
!=
null
)
tz
=
DateUtils
.
tzRegistry
.
getTimeZone
(
tzId
);
DateTime
start
=
new
DateTime
(
tsStart
);
start
.
setTimeZone
(
tz
);
event
.
dtStart
=
new
DtStart
(
start
);
if
(
tsEnd
!=
null
)
{
DateTime
end
=
new
DateTime
(
tsEnd
);
end
.
setTimeZone
(
tz
);
event
.
dtEnd
=
new
DtEnd
(
end
);
}
else
if
(
duration
!=
null
)
event
.
duration
=
new
Duration
(
new
Dur
(
duration
));
}
...
...
@@ -497,23 +504,25 @@ public abstract class AndroidEvent {
builder
.
withValue
(
Events
.
CALENDAR_ID
,
calendar
.
getId
())
.
withValue
(
Events
.
ALL_DAY
,
event
.
isAllDay
()
?
1
:
0
)
.
withValue
(
Events
.
DTSTART
,
event
.
getDtStartInMillis
())
.
withValue
(
Events
.
DTSTART
,
event
.
dtStart
.
getDate
().
getTime
())
.
withValue
(
Events
.
EVENT_TIMEZONE
,
event
.
getDtStartTzID
())
.
withValue
(
Events
.
HAS_ATTENDEE_DATA
,
1
/* we know information about all attendees and not only ourselves */
);
// all-day events and "events on that day" must have a duration (set to one day if zero or missing)
if
(
event
.
isAllDay
()
&&
(
event
.
dtEnd
==
null
||
!
event
.
dtEnd
.
getDate
().
after
(
event
.
dtStart
.
getDate
())))
{
// ical4j is not set to use floating times, so DATEs are UTC times internally
Constants
.
log
.
log
(
Level
.
INFO
,
"Changing all-day event for Android compatibility:
DTEND := DTSTART
+ 1 day"
);
Constants
.
log
.
log
(
Level
.
INFO
,
"Changing all-day event for Android compatibility:
dtend := dtstart
+ 1 day"
);
java
.
util
.
Calendar
c
=
java
.
util
.
Calendar
.
getInstance
(
TimeZone
.
getTimeZone
(
TimeZones
.
UTC_ID
));
c
.
setTime
(
event
.
dtStart
.
getDate
());
c
.
add
(
java
.
util
.
Calendar
.
DATE
,
1
);
event
.
dtEnd
=
new
DtEnd
(
new
Date
(
c
.
getTimeInMillis
()));
}
// events without dtEnd (events with zero duration)
if
(
event
.
dtEnd
==
null
)
// fix events with zero or negative duration
else
if
(
event
.
dtEnd
==
null
||
event
.
dtEnd
.
getDate
().
getTime
()
<
event
.
dtStart
.
getDate
().
getTime
())
{
Constants
.
log
.
info
(
"Event without duration, setting dtend := dtstart"
);
event
.
dtEnd
=
new
DtEnd
(
event
.
dtStart
.
getDate
());
}
boolean
recurring
=
false
;
if
(
event
.
rRule
!=
null
)
{
...
...
@@ -541,10 +550,12 @@ public abstract class AndroidEvent {
// because that's the way Android likes it
if
(
recurring
)
{
// calculate DURATION from start and end date
Duration
duration
=
new
Duration
(
event
.
dtStart
.
getDate
(),
event
.
dtEnd
.
getDate
());
Duration
duration
=
(
event
.
duration
!=
null
)
?
event
.
duration
:
new
Duration
(
event
.
dtStart
.
getDate
(),
event
.
dtEnd
.
getDate
());
builder
.
withValue
(
Events
.
DURATION
,
duration
.
getValue
());
}
else
builder
.
withValue
(
Events
.
DTEND
,
event
.
getDtEndInMillis
())
builder
.
withValue
(
Events
.
DTEND
,
event
.
dtEnd
.
getDate
().
getTime
())
.
withValue
(
Events
.
EVENT_END_TIMEZONE
,
event
.
getDtEndTzID
());
if
(
event
.
summary
!=
null
)
...
...
src/main/java/at/bitfire/ical4android/Event.java
View file @
fe0b1bf5
...
...
@@ -17,8 +17,6 @@ import net.fortuna.ical4j.data.ParserException;
import
net.fortuna.ical4j.model.Calendar
;
import
net.fortuna.ical4j.model.Component
;
import
net.fortuna.ical4j.model.ComponentList
;
import
net.fortuna.ical4j.model.Date
;
import
net.fortuna.ical4j.model.DateTime
;
import
net.fortuna.ical4j.model.Property
;
import
net.fortuna.ical4j.model.PropertyList
;
import
net.fortuna.ical4j.model.TimeZone
;
...
...
@@ -387,41 +385,11 @@ public class Event extends iCalendar {
return
!
isDateTime
(
dtStart
);
}
public
long
getDtStartInMillis
()
{
return
dtStart
.
getDate
().
getTime
();
}
public
String
getDtStartTzID
()
{
return
getTzId
(
dtStart
);
}
public
void
setDtStart
(
long
tsStart
,
String
tzID
)
{
if
(
tzID
==
null
)
{
// all-day
dtStart
=
new
DtStart
(
new
Date
(
tsStart
));
}
else
{
DateTime
start
=
new
DateTime
(
tsStart
);
start
.
setTimeZone
(
DateUtils
.
tzRegistry
.
getTimeZone
(
tzID
));
dtStart
=
new
DtStart
(
start
);
}
}
public
long
getDtEndInMillis
()
{
return
dtEnd
.
getDate
().
getTime
();
}
public
String
getDtEndTzID
()
{
return
getTzId
(
dtEnd
);
}
public
void
setDtEnd
(
long
tsEnd
,
String
tzID
)
{
if
(
tzID
==
null
)
{
// all-day
dtEnd
=
new
DtEnd
(
new
Date
(
tsEnd
));
}
else
{
DateTime
end
=
new
DateTime
(
tsEnd
);
end
.
setTimeZone
(
DateUtils
.
tzRegistry
.
getTimeZone
(
tzID
));
dtEnd
=
new
DtEnd
(
end
);
}
}
}
\ No newline at end of file
src/test/java/at/bitfire/ical4android/EventTest.java
View file @
fe0b1bf5
...
...
@@ -88,9 +88,9 @@ public class EventTest {
public
void
testStartEndTimes
()
throws
IOException
,
InvalidCalendarException
{
// event with start+end date-time
Event
eViennaEvolution
=
parseCalendar
(
"vienna-evolution.ics"
,
null
)[
0
];
assertEquals
(
1381330800000L
,
eViennaEvolution
.
getDtStartInMillis
());
assertEquals
(
1381330800000L
,
eViennaEvolution
.
dtStart
.
getDate
().
getTime
());
assertEquals
(
"Europe/Vienna"
,
eViennaEvolution
.
getDtStartTzID
());
assertEquals
(
1381334400000L
,
eViennaEvolution
.
getDtEndInMillis
());
assertEquals
(
1381334400000L
,
eViennaEvolution
.
dtEnd
.
getDate
().
getTime
());
assertEquals
(
"Europe/Vienna"
,
eViennaEvolution
.
getDtEndTzID
());
}
...
...
@@ -98,29 +98,29 @@ public class EventTest {
public
void
testStartEndTimesAllDay
()
throws
IOException
,
InvalidCalendarException
{
// event with start date only
Event
eOnThatDay
=
parseCalendar
(
"event-on-that-day.ics"
,
null
)[
0
];
assertEquals
(
868838400000L
,
eOnThatDay
.
getDtStartInMillis
());
assertEquals
(
868838400000L
,
eOnThatDay
.
dtStart
.
getDate
().
getTime
());
assertEquals
(
TimeZones
.
UTC_ID
,
eOnThatDay
.
getDtStartTzID
());
// event with start+end date for all-day event (one day)
Event
eAllDay1Day
=
parseCalendar
(
"all-day-1day.ics"
,
null
)[
0
];
assertEquals
(
868838400000L
,
eAllDay1Day
.
getDtStartInMillis
());
assertEquals
(
868838400000L
,
eAllDay1Day
.
dtStart
.
getDate
().
getTime
());
assertEquals
(
TimeZones
.
UTC_ID
,
eAllDay1Day
.
getDtStartTzID
());
assertEquals
(
868838400000L
+
86400000
,
eAllDay1Day
.
getDtEndInMillis
());
assertEquals
(
868838400000L
+
86400000
,
eAllDay1Day
.
dtEnd
.
getDate
().
getTime
());
assertEquals
(
TimeZones
.
UTC_ID
,
eAllDay1Day
.
getDtEndTzID
());
// event with start+end date for all-day event (ten days)
Event
eAllDay10Days
=
parseCalendar
(
"all-day-10days.ics"
,
null
)[
0
];
assertEquals
(
868838400000L
,
eAllDay10Days
.
getDtStartInMillis
());
assertEquals
(
868838400000L
,
eAllDay10Days
.
dtStart
.
getDate
().
getTime
());
assertEquals
(
TimeZones
.
UTC_ID
,
eAllDay10Days
.
getDtStartTzID
());
assertEquals
(
868838400000L
+
10
*
86400000
,
eAllDay10Days
.
getDtEndInMillis
());
assertEquals
(
868838400000L
+
10
*
86400000
,
eAllDay10Days
.
dtEnd
.
getDate
().
getTime
());
assertEquals
(
TimeZones
.
UTC_ID
,
eAllDay10Days
.
getDtEndTzID
());
// event with start+end date on some day (0 sec-event)
Event
eAllDay0Sec
=
parseCalendar
(
"all-day-0sec.ics"
,
null
)[
0
];
assertEquals
(
868838400000L
,
eAllDay0Sec
.
getDtStartInMillis
());
assertEquals
(
868838400000L
,
eAllDay0Sec
.
dtStart
.
getDate
().
getTime
());
assertEquals
(
TimeZones
.
UTC_ID
,
eAllDay0Sec
.
getDtStartTzID
());
// DTEND is same as DTSTART which is not valid for Android – but this will be handled by AndroidEvent, not Event
assertEquals
(
868838400000L
,
eAllDay0Sec
.
getDtEndInMillis
());
assertEquals
(
868838400000L
,
eAllDay0Sec
.
dtEnd
.
getDate
().
getTime
());
assertEquals
(
TimeZones
.
UTC_ID
,
eAllDay0Sec
.
getDtEndTzID
());
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment