我正在使用CalendarContract.Instances来获取一组日历事件。一般来说,我的查询工作正常。但是,“假期”日历中事件的开始和结束时间将返回错误的时区。我个人日历中的活动来自正确的时间。
例如:
New Year's day "begins" at 04:00 PM, 31 Dec 2014.
其中
Opera "begins" at 02:00 PM, 11 Jan 2015.
我使用完全相同的代码来显示两者:
SimpleDateFormat formatter = new SimpleDateFormat ("hh:mm a, d MMM yyyy", Locale.US);
logD (prefix + i + ": " + formatter.format (data.startTime) + "; " + data.note);
其中data.startTime映射到Instances.BEGIN,data.note映射到Instances.TITLE。歌剧院正好在正确的时间出现,新年的一天显然是8小时(我在美国太平洋时区)。
如果我在Android日历应用中查看这些内容,则会显示正确的时间。
显然,我可以查看事件来自哪个日历,并相应地设置时区以使其显示正确的时间。但是,我希望有一个我不知道的更合适的解决方案。
这是从代码中获取事件值的代码片段:
@Override
public View getView (int position, View convertView, ViewGroup parent)
{
...
EventFields fields = new EventFields();
cursor.moveToPosition (position);
fields.title = cursor.getString (cursor.getColumnIndex (Instances.TITLE));
fields.dtStart = cursor.getLong (cursor.getColumnIndex (Instances.BEGIN));
fields.dtEnd = cursor.getLong (cursor.getColumnIndex (Instances.END));
fields.iCalDuration = cursor.getString (cursor.getColumnIndex (Instances.DURATION));
fields.rrule = cursor.getString (cursor.getColumnIndex (Instances.RRULE));
...
}
以下是查询:
@Override
public void refreshData (String constraint)
{
long begin = ... some date ...
long end = ... another date ...
final Uri uri = Uri.parse(CalendarContract.Instances.CONTENT_URI + "/" +
Long.toString(begin) + "/" +
Long.toString(end));
// Setup query - projection ordering must match statics above.
final String[] projection = new String[] {
Instances._ID,
Instances.EVENT_ID,
Instances.TITLE,
Instances.BEGIN,
Instances.END,
Instances.DURATION,
Instances.RRULE,
Instances.DESCRIPTION,
};
final String sortOrder = Instances.BEGIN;
String selection = null;
if (constraint != null)
selection = Instances.TITLE + " like '%" + constraint.toString() + "%'";
cursor = getActivity().getContentResolver().query (
uri,
projection,
selection,
null,
sortOrder);
}
上述例子,元旦
New Year's day dtStart = 1419984000000 and
另一个真正在下午4点开始的活动
Roger dtStart = 1420052400000
答案 0 :(得分:3)
正如评论中所讨论的,我们确定这是与以UTC显示时间的全天事件相关的问题。
看起来这是just how Android handles it。
查看Format Time class in the Android Docs
public boolean allDay
如果这是一个allDay事件,则为True。小时,分钟,秒字段均为零,日期在所有时区显示相同。
最后在CalendarContract.Events docs
如果allDay设置为1,则eventTimezone必须为TIMEZONE_UTC且时间必须对应于午夜边界。
因此,您通过格式化全天事件所做的工作是正确的
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
<强>更新强>
默认情况下,如果您没有明确设置SimpleDateFormat的时区,它将默认为您设备的本地时区。
您的BEGIN和END时间应该以UTC时间返回。
所有日期事件始终设置为UTC时区的午夜,因此除了UTC时区之外的任何其他格式都将为您提供非午夜时间。
您可以使用继承的字段检查日历事件实例的时区:
EVENT_TIMEZONE
答案 1 :(得分:0)
尝试添加:formatter.setTimeZone(TimeZone.getTimeZone("US/Pacific"));
答案 2 :(得分:0)
您实际上可以在日历上设置时区。仔细检查您比较的两个日历的时区是否设置为相同的值。