EWS update changes time zone to UTC - exchangewebservices

I've seen this question asked several times on the web, but cannot find an answer.
When I create an appointment (meeting) using managed EWS 2.0, the invitation email correctly shows the time and time zone. When I update the meeting, the new invitation emails show the time in the UTC time zone. It is the correct time for UTC, but should display in Pacific.
I have tried setting the zone when creating the service connection, but this makes the initial invitation also show the time zone as UTC, as well as any updates.
I've tried setting the StartTimeZone and EndTimeZone properties, and have included those properties in the property set when binding the appointment for modification.
Is there another property somewhere that controls how Exchange formats the time when sending out the invitations? Here is some code showing how I am performing the updates:
Dim EWS As ExchangeService = GetEWSConnection(UserEmailAddress)
Dim meeting As Appointment = Appointment.Bind(EWS, New ItemId(CalendarEvent.ItemKey), New PropertySet(BasePropertySet.IdOnly, AppointmentSchema.Start, AppointmentSchema.End, AppointmentSchema.ReminderDueBy, AppointmentSchema.StartTimeZone, AppointmentSchema.EndTimeZone, AppointmentSchema.TimeZone, AppointmentSchema.Subject, AppointmentSchema.Location, AppointmentSchema.Body))
Dim timeZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(LocalTimeZoneID)
With meeting
.Subject = CalendarEvent.Subject
.Location = CalendarEvent.Location
.Body = CalendarEvent.Body
.Start = CalendarEvent.StartTime
.End = CalendarEvent.EndTime
.StartTimeZone = timeZone
.EndTimeZone = timeZone
' snip (removed attendee add/remove)
.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToChangedAndSaveCopy)
End With

I realize that this is a frustrating answer, but I believe this to be an Exchange bug. No matter how you adjust the various time zone properties exposed by the API, this behavior still occurs. As far as I can tell, there aren't any server-level settings that would affect this either, although I admittedly haven't combed through all of them.
In my case, what seems to go along with the appended UTC time is that the message is changed from its original HTML to a plain text version upon update. That bug (http://support.microsoft.com/kb/2689810) has been fixed, but my organization hasn't applied the patch yet. It's possible, I suppose, that this bug was rendered obsolete when the other was fixed. If installing an update on your Exchange server is an option, then that might be worth a shot.

Related

Why is Time not setting when inserting new task using Task Service?

I am trying to insert new task with due date and time in Google Tasks using Tasks Service. The issue i am facing is that date is setting correctly while time is not setting. The code is given below:
I had tried all the solutions given on stackoverflow and other platform, none of them worked.
var task = Tasks.newTask().setTitle(data[i]);
task.setDue("2019-6-25T10:10:10.000Z");
Tasks.Tasks.insert(task, taskList.id);
I expect both the date and time to be set but only date is setting.
The official document says as follows.
Due date of the task (as a RFC 3339 timestamp). Optional. The due date only records date information; the time portion of the timestamp is discarded when setting the due date. It isn't possible to read or write the time that a task is due via the API.
Unfortunately, in the current stage, by above specification, even if 2019-6-25T10:10:10.000Z is used for due, it becomes 2019-06-25T00:00:00.000Z. So it seems that in order to modify the time, it is required to manually modify it.
Reference:
Resource representations of Tasks

Correct timezone handling with TYPO3 and Fluid

Its confusing me. I've a property in my Model which is annotated with DateTime. In my Database its stored as timestamp. In Frontend I use the f:format.date viewhelper to output this property.
When I create a new record, and add f.e. 01.06.2017 10:00 in this field, in my database is stored the timestamp for 01.06.2017 08:00. In Frontend the output is correct. Until here everything is fine.
The last timechange in March lead to a + of two hours in output. I assume in October that will change again and the output will be than this: 01.06.2017 08:00.
How can I prevent this. Its definitely a problem when these dates change, because its important for the business.
How can I test what will happen in October?
The Problem occurs as TYPO3 saves times normalized as UTC. for normalization (and afterwards denormalization) it respects the timezone-settings of the server. Or settings given in LocalConfiguration.php.
Up to 6.2 there were two settings [SYS][serverTimeZone] and [SYS][phpTimeZone].
With 7.6 it is only [SYS][phpTimeZone] as the servertimezone is detected from php itself.
You now have the option to fake the timezone of your server to "UTC" by setting [SYS][phpTimeZone] to the string "UTC". In this way no times should be changed any more.
TYPO3 9.5 and newer
Use the environment (documentation)
// use TYPO3\CMS\Core\Utility\GeneralUtility;
// use TYPO3\CMS\Core\Context\Context;
$context = GeneralUtility::makeInstance(Context::class);
// Reading the current data instead of $GLOBALS
$currentTimezone = $context->getPropertyFromAspect('date', 'timezone');
$currentTstamp = $context->getPropertyFromAspect('date', 'timestamp');
$current = new DateTime('#'.$currentTstamp);
$current->setTimezone(new DateTimeZone($currentTimezone) );
In Fluid you may use a DateTime-Object:
// in PHP-ode of Viewhelper
//...
$this->registerArgument('date', 'mixed', 'Either an object implementing DateTimeInterface or a string that is accepted by DateTime constructor');
// ...
In HTML
{dateTimeObject -> f:format.date()}
<f:format.date format="d.m.Y">{dateTimeObject}</f:format.date>

Cant update exchange appointment in EWS

Im using EWS to update exchange appointments but sometimes I can't update them after they are created. I'm receiving:
"At least one recipient isn't valid., A message can't be sent because it contains no recipients."
The code is essentially:
Appointment appointment = getAppointment();
... set some properties
appointment.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToNone);
Isn't that supposed to work? Beforehand I didn't use the SendInvitationsOrCancellationsMode.SendToNone enum, but even with that I get the same exception.
It's never a problem to create the appointment, it's always the updates that we are having problems with.
For the sake of the log, I send a solution here. I managed to solve it with a workaround. It accepts it if I add a new item to the OptionalAttendees collection, when it is empty. Since I add the SendInvitationsOrCancellationsMode.SendToNone flag, it will send nothing, but finally accepts it without an exception.
if (EWSItem.OptionalAttendees.Count == 0)
EWSItem.OptionalAttendees.Add("me#me.com");
EWSItem.Update(ConflictResolutionMode.AlwaysOverwrite,
SendInvitationsOrCancellationsMode.SendToNone);

Strange results returning from Response.getId() in GAS

I am working with a script to pull the response ID from a form submission so that when users edit their response, I can match the edit to the initial response. My script creates a .pdf of the contents of each form submitted, but when users edit responses, it creates a new form containing only the edited data, without linking it to the initial response.
The edit response contains a timestamp and the edited information, and the timestamp is used with Response.getId(timestamp), iirc, and returns the ID of the form submission. However, I am sometimes getting a very strange return, and I don't know where it comes from. The response is much shorter than a typical response ID (10-12 alphanumeric instead of 30+). I will try to comeback and edit this question with the code, but I'm on a different log in at the moment, so I'll have to swap over and copy code and come back. Running unit tests hasn't really helped, as I get the expected result most of the time. It's just an occasional hiccup, but I have to find where the incorrect information is coming from.
function getResponseId(timestamp){
var form = FormApp.openById('<formID>');
if(typeof(timestamp) != 'number'){
timestamp = new Date(timestamp);
}
var responses = form.getResponses(timestamp);
var entryId = responses[0].getId();
return entryId;
}
That's is. I suppose the if(typeof... may be throwing things off if it's passing in a Date string instead of the actual timestamp of entry, but I don't think so. I'll double check it and debug it in the meantime, and if I answer my own question, I'll come back and fix it.
Hmm. Sounds like the same behavior. What I decided to do instead was to match the timestamps that are recorded, but you have to grab the stamps in the 3rd line of code, as the old stamp is overwritten quickly. I just subtracted oldTime from newTime, left a 5 sec window to match them, and that worked. I just haven't had a chance to post it yet, as I just got it working for new submissions, edits, and failed writes about an hour ago.

Exchange Web Services and Property Sets

I need to retrieve calendar information by invoking the Exchange Web Service in BPOS. I'm using a CalendarView with a PropertySet to retrieve as little data as possible. However, property sets seems to be limited. I need the EmailAddress of the one who made the calendar appointment so I thought I could use the AppointmentSchema.Organizer in the PropertySet.
When fetching a whole appointment I can get the e-mail through appt.Organizer.EmailAddress. But with the code below the Organizer.EmailAddress is always null. I've enabled the trace and checked it and only the Organizer.Name property is sent, nothing else. Does anyone have a solution on how to get the EmailAddress when using a PropertySet?
CalendarView view = new CalendarView(dtFrom, dtTo);
view.PropertySet = new PropertySet(ItemSchema.Subject);
view.PropertySet.Add(ItemSchema.Id);
view.PropertySet.Add(AppointmentSchema.Start);
view.PropertySet.Add(AppointmentSchema.End);
view.PropertySet.Add(AppointmentSchema.Organizer); // This should contain EmailAddress but it doesn't
Mailbox mailbox = new Mailbox("myemail#test.ab");
FolderId id = new FolderId(WellKnownFolderName.Calendar, mailbox);
CalendarFolder folder = CalendarFolder.Bind(service, id);
FindItemsResults<Appointment> findResults = folder.FindAppointments(view);
This should work (does for me):
service.FindAppointments(WellKnownFolderName.Calendar, new CalendarView(start, end)).Where(s => DateTime.Now < s.Start);
service.LoadPropertiesForItems(appointments, PropertySet.FirstClassProperties);
As best as I have been able to figure out EWS is a little buggy when it comes to populating the full EmailAddress details both in Appointments for Organizer and for other things like "EmailMessage.From". When you do a query for multiple items, you don't get the EmailAddress properties being fully populated. E.g. using APIs like:
Folder.FindItems
ExchangeService.FindAppointments
I find that only the display name in the EmailAddress fields gets populated.
To get the EmailAddress fully populated I find I need to load/bind to the specific item and specify the relevant EmailAddress property, e.g. AppointmentSchema.Organizer in your case. So although you specify exactly the same property to load, you are loading using a single item call rather than a bulk query. E.g. using:
ServiceObject.Load
Which is available for both Appointment and EmailMessage as they both derive off ServiceObject. Using Item.Bind with the appropriate property set defined should also work.
As an aside I figured this out looking at the code for EwsEditor which is mentioned here:
http://blogs.msdn.com/webdav_101/archive/2009/11/10/ews-has-more-happy-now-ews-managed-api-and-ewseditor.aspx
The usability of EwsEditor is fairly sucky, and the code takes some trawling to figure out, but at least it does show examples of exercising many of the APIs.
service.FindAppointments(WellKnownFolderName.Calendar, new CalendarView(start, end)).Where(s => DateTime.Now < s.Start);
service.LoadPropertiesForItems(appointments, PropertySet.FirstClassProperties);
It worked for me.