Fix some CalDAV time zone conversions

pull/1322/head
Alex Baker 4 years ago
parent d8658b1db0
commit d8e8c1b1a6

@ -237,7 +237,7 @@ class Task : Parcelable {
repeatUntil = 0
recurrence = null
} else {
repeatUntil = rrule.recur.until?.let { DateTime.from(it).millis } ?: 0
repeatUntil = rrule.recur.until?.let { DateTime(it).millis } ?: 0
recurrence = "RRULE:${rrule.value.sanitizeRRule()}" + if (repeatAfterCompletion()) ";FROM=COMPLETION" else ""
}
}

@ -1,18 +1,15 @@
package org.tasks.caldav;
import static com.todoroo.andlib.utility.DateUtilities.now;
import static com.todoroo.astrid.data.Task.URGENCY_SPECIFIC_DAY;
import static com.todoroo.astrid.data.Task.URGENCY_SPECIFIC_DAY_TIME;
import static org.tasks.caldav.iCalendar.getLocal;
import static org.tasks.date.DateTimeUtils.newDateTime;
import static org.tasks.time.DateTime.UTC;
import static org.tasks.time.DateTimeUtils.startOfDay;
import at.bitfire.ical4android.DateUtils;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.Task.Priority;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.TimeZone;
import net.fortuna.ical4j.model.Date;
import net.fortuna.ical4j.model.DateTime;
@ -26,12 +23,10 @@ import timber.log.Timber;
public class CaldavConverter {
static final DateFormat DUE_DATE_FORMAT = new SimpleDateFormat("yyyyMMdd", Locale.US);
public static void apply(Task local, at.bitfire.ical4android.Task remote) {
Completed completedAt = remote.getCompletedAt();
if (completedAt != null) {
local.setCompletionDate(remote.getCompletedAt().getDate().getTime());
local.setCompletionDate(getLocal(completedAt));
} else if (remote.getStatus() == Status.VTODO_COMPLETED) {
if (!local.isCompleted()) {
local.setCompletionDate(now());
@ -39,32 +34,15 @@ public class CaldavConverter {
} else {
local.setCompletionDate(0L);
}
Long createdAt = remote.getCreatedAt();
if (createdAt != null) {
local.setCreationDate(newDateTime(createdAt).toLocal().getMillis());
local.setCreationDate(newDateTime(createdAt, UTC).toLocal().getMillis());
}
local.setTitle(remote.getSummary());
local.setNotes(remote.getDescription());
local.setPriority(fromRemote(remote.getPriority()));
local.setRecurrence(remote.getRRule());
Due due = remote.getDue();
if (due == null) {
local.setDueDate(0L);
} else {
Date dueDate = due.getDate();
if (dueDate instanceof DateTime) {
local.setDueDate(Task.createDueDate(URGENCY_SPECIFIC_DAY_TIME, dueDate.getTime()));
} else {
try {
local.setDueDate(
Task.createDueDate(
URGENCY_SPECIFIC_DAY, DUE_DATE_FORMAT.parse(due.getValue()).getTime()));
} catch (ParseException e) {
Timber.e(e);
}
}
}
iCalendar.Companion.apply(remote.getDue(), local);
iCalendar.Companion.apply(remote.getDtStart(), local);
}

@ -5,18 +5,16 @@ import at.bitfire.ical4android.Task.Companion.tasksFromReader
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task.Companion.HIDE_UNTIL_SPECIFIC_DAY
import com.todoroo.astrid.data.Task.Companion.HIDE_UNTIL_SPECIFIC_DAY_TIME
import com.todoroo.astrid.data.Task.Companion.URGENCY_SPECIFIC_DAY
import com.todoroo.astrid.data.Task.Companion.URGENCY_SPECIFIC_DAY_TIME
import com.todoroo.astrid.helper.UUIDHelper
import com.todoroo.astrid.service.TaskCreator
import net.fortuna.ical4j.model.DateTime
import net.fortuna.ical4j.model.Parameter
import net.fortuna.ical4j.model.Property
import net.fortuna.ical4j.model.parameter.RelType
import net.fortuna.ical4j.model.property.DtStart
import net.fortuna.ical4j.model.property.Geo
import net.fortuna.ical4j.model.property.RelatedTo
import net.fortuna.ical4j.model.property.XProperty
import net.fortuna.ical4j.model.property.*
import org.tasks.Strings.isNullOrEmpty
import org.tasks.caldav.CaldavConverter.DUE_DATE_FORMAT
import org.tasks.caldav.GeoUtils.equalish
import org.tasks.caldav.GeoUtils.toGeo
import org.tasks.caldav.GeoUtils.toLikeString
@ -24,10 +22,13 @@ import org.tasks.data.*
import org.tasks.jobs.WorkManager
import org.tasks.location.GeofenceApi
import org.tasks.preferences.Preferences
import org.tasks.time.DateTime.UTC
import timber.log.Timber
import java.io.ByteArrayOutputStream
import java.io.StringReader
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*
import javax.inject.Inject
@Suppress("ClassName")
@ -58,7 +59,7 @@ class iCalendar @Inject constructor(
place.id = locationDao.insert(place)
workManager.reverseGeocode(place)
}
val existing: Location? = locationDao.getGeofences(taskId)
val existing = locationDao.getGeofences(taskId)
if (existing == null) {
val geofence = Geofence(place.uid, preferences)
geofence.task = taskId
@ -161,7 +162,8 @@ class iCalendar @Inject constructor(
}
companion object {
const val APPLE_SORT_ORDER = "X-APPLE-SORT-ORDER"
private val DUE_DATE_FORMAT = SimpleDateFormat("yyyyMMdd", Locale.US)
private const val APPLE_SORT_ORDER = "X-APPLE-SORT-ORDER"
private val IS_PARENT = { r: RelatedTo ->
r.parameters.getParameter<RelType>(Parameter.RELTYPE).let {
it === RelType.PARENT || it == null || it.value.isNullOrBlank()
@ -172,21 +174,47 @@ class iCalendar @Inject constructor(
x?.name.equals(APPLE_SORT_ORDER, true)
}
fun Due?.apply(task: com.todoroo.astrid.data.Task) {
task.dueDate = when (this?.date) {
null -> 0
is DateTime -> com.todoroo.astrid.data.Task.createDueDate(
URGENCY_SPECIFIC_DAY_TIME,
getLocal(this)
)
else -> com.todoroo.astrid.data.Task.createDueDate(
URGENCY_SPECIFIC_DAY,
getLocal(this)
)
}
}
fun DtStart?.apply(task: com.todoroo.astrid.data.Task) {
when (this?.date) {
task.hideUntil = when (this?.date) {
null -> 0
is DateTime -> task.createHideUntil(HIDE_UNTIL_SPECIFIC_DAY_TIME, date.time)
else -> try {
DUE_DATE_FORMAT.parse(value)?.let {
task.createHideUntil(HIDE_UNTIL_SPECIFIC_DAY, it.time)
is DateTime -> task.createHideUntil(HIDE_UNTIL_SPECIFIC_DAY_TIME, getLocal(this))
else -> task.createHideUntil(HIDE_UNTIL_SPECIFIC_DAY, getLocal(this))
}
}
@JvmStatic
fun getLocal(property: DateProperty): Long {
val dateTime = if (property.date is DateTime) {
val dt = property.date as DateTime
org.tasks.time.DateTime(
dt.time,
dt.timeZone ?: if (dt.isUtc) UTC else TimeZone.getDefault()
)
} else {
try {
DUE_DATE_FORMAT.parse(property.value)?.let {
org.tasks.time.DateTime(it)
}
} catch (e: ParseException) {
Timber.e(e)
null
}
}?.let {
task.hideUntil = it
}
return dateTime?.toLocal()?.millis ?: 0
}
fun fromVtodo(vtodo: String): Task? {

@ -21,6 +21,9 @@ object DateTimeUtils {
@JvmStatic
fun newDateTime(timestamp: Long): DateTime = DateTime(timestamp)
@JvmStatic
fun newDateTime(timestamp: Long, timeZone: TimeZone): DateTime = DateTime(timestamp, timeZone)
fun Long.toAppleEpoch(): Long = DateTime(this).toAppleEpoch()
fun Long.toDateTime(): DateTime = DateTime(this)

@ -18,11 +18,11 @@ import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Objects;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import net.fortuna.ical4j.model.Date;
import org.tasks.locale.Locale;
public class DateTime {
@ -76,7 +76,7 @@ public class DateTime {
this(timestamp, TimeZone.getDefault());
}
private DateTime(long timestamp, TimeZone timeZone) {
public DateTime(long timestamp, TimeZone timeZone) {
this.timestamp = timestamp;
this.timeZone = timeZone;
}
@ -96,12 +96,8 @@ public class DateTime {
return new DateTime(dateValue.year(), dateValue.month(), dateValue.day());
}
public static DateTime from(Date date) {
return new DateTime(date.getTime(), UTC);
}
public static DateTime from(net.fortuna.ical4j.model.DateTime dateTime) {
return new DateTime(dateTime.getTime(), dateTime.getTimeZone());
public DateTime(Date date) {
this(date.getTime());
}
private DateTime setTime(int hours, int minutes, int seconds, int milliseconds) {

Loading…
Cancel
Save