如何在Outlook插件中存储并读取精确到秒的UserProperty日期时间?
Outlook AppointmentItem UserProperty 日期时间秒数丢失问题解决
你遇到的问题是Outlook对象模型的默认行为导致的:当使用olDateTime类型的UserProperty存储约会项的日期时间时,Outlook会自动将时间截断到分钟级别,重启后读取就看不到秒数了。
解决方案一:改用文本类型存储
将DateTime转换为包含秒数的字符串存储,读取时再解析回DateTime,绕过Outlook的时间粒度限制:
创建属性时:
AppointmentItem copiedAppointmentItem = sourceAppointmentItem.ReferenceItem.CopyTo(calendar, OlAppointmentCopyOptions.olCreateAppointment); // 转成带秒的字符串格式存储 copiedAppointmentItem.UserProperties.Add(SynchronizationTags.LAST_SYNCHRONIZATION_DATETIME, OlUserPropertyType.olText, false).Value = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"); copiedAppointmentItem.Save();
读取属性时:
UserProperty ls = copiedAppointmentItem.UserProperties.Find(SynchronizationTags.LAST_SYNCHRONIZATION_DATETIME); if (ls != null && DateTime.TryParseExact(ls.Value.ToString(), "yyyy/MM/dd HH:mm:ss", null, System.Globalization.DateTimeStyles.None, out DateTime syncTime)) { // 这里的syncTime会包含精确到秒的时间 }
解决方案二:使用命名空间属性(Named Properties)
通过PropertyAccessor操作命名属性,这种方式不受Outlook对UserProperty的粒度限制,能完整保留秒数:
首先生成一个唯一的GUID作为自定义命名空间(可以用工具生成一个专属GUID),然后操作属性:
创建属性时:
AppointmentItem copiedAppointmentItem = sourceAppointmentItem.ReferenceItem.CopyTo(calendar, OlAppointmentCopyOptions.olCreateAppointment); Guid customNamespace = new Guid("12345678-1234-1234-1234-1234567890AB"); // 替换成你的唯一GUID // 设置命名属性值 copiedAppointmentItem.PropertyAccessor.SetProperty( $"http://schemas.microsoft.com/mapi/string/{customNamespace.ToString("B").ToUpper()}/{SynchronizationTags.LAST_SYNCHRONIZATION_DATETIME}", DateTime.Now ); copiedAppointmentItem.Save();
读取属性时:
Guid customNamespace = new Guid("12345678-1234-1234-1234-1234567890AB"); // 和创建时一致的GUID DateTime syncTime = (DateTime)copiedAppointmentItem.PropertyAccessor.GetProperty( $"http://schemas.microsoft.com/mapi/string/{customNamespace.ToString("B").ToUpper()}/{SynchronizationTags.LAST_SYNCHRONIZATION_DATETIME}" ); // syncTime会保留完整的秒数
注意事项
- 文本存储方式实现简单,但要注意字符串格式的一致性,避免解析失败;
- 命名属性方式需要确保GUID唯一,防止和其他自定义属性冲突,适合需要精确时间存储的场景。
内容的提问来源于stack exchange,提问作者Gab
相关产品推荐
相关产品推荐

