Skip to content

Commit

Permalink
Chenmo/add time zone (microsoft#192)
Browse files Browse the repository at this point in the history
* fix timezone problem

* clean som code

* removeTimezone

* add date time entities usage

* fix return null meeting list bug

* remove the update logic in delete flow

* add null check in parsing datetimeprompt result

* remove unused exception e

* fix some bug

* add null check in parsing datetimeprompt result

* fix some time zone issues

* select the last one in multiple date
  • Loading branch information
ChengxianMo authored Nov 2, 2018
1 parent fc64681 commit fc97111
Show file tree
Hide file tree
Showing 15 changed files with 532 additions and 237 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
<PackageReference Include="Microsoft.Bot.Schema" Version="4.0.7" />
<PackageReference Include="Microsoft.Graph" Version="1.10.0" />
<PackageReference Include="AsyncUsageAnalyzers" Version="1.0.0-alpha003" PrivateAssets="all" />
<PackageReference Include="Microsoft.Recognizers.Text.DateTime" Version="1.1.2" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.0-beta008" PrivateAssets="all" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ public CalendarSkillState()
StartTime = null;
StartTimeString = null;
StartDateTime = null;
EndDate = null;
EndTime = null;
EndDateTime = null;
OriginalStartDate = null;
OriginalStartTime = null;
OriginalEndDate = null;
OriginalEndTime = null;
Location = null;
Attendees = new List<EventModel.Attendee>();
APIToken = null;
Expand Down Expand Up @@ -48,12 +54,34 @@ public CalendarSkillState()

public string Content { get; set; }

// user time zone
public DateTime? StartDate { get; set; }

// user time zone
public DateTime? StartTime { get; set; }

// UTC
public DateTime? StartDateTime { get; set; }

// user time zone
public DateTime? EndDate { get; set; }

// user time zone
public DateTime? EndTime { get; set; }

// user time zone
public DateTime? OriginalStartDate { get; set; }

// user time zone
public DateTime? OriginalStartTime { get; set; }

// user time zone
public DateTime? OriginalEndDate { get; set; }

// user time zone
public DateTime? OriginalEndTime { get; set; }

// UTC
public DateTime? EndDateTime { get; set; }

public string Location { get; set; }
Expand All @@ -64,7 +92,8 @@ public CalendarSkillState()

public List<EventModel> Events { get; set; }

public object NewStartDateTime { get; set; }
// UTC
public DateTime? NewStartDateTime { get; set; }

public EventSource EventSource { get; set; }

Expand Down Expand Up @@ -108,7 +137,13 @@ public void Clear()
StartTime = null;
StartTimeString = null;
StartDateTime = null;
EndDate = null;
EndTime = null;
EndDateTime = null;
OriginalStartDate = null;
OriginalStartTime = null;
OriginalEndDate = null;
OriginalEndTime = null;
Location = null;
Attendees = new List<EventModel.Attendee>();
APIToken = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ public static class TimeConverter
{
public static DateTime ConvertLuisLocalToUtc(DateTime time, TimeZoneInfo timeZone)
{
if (time.Kind != DateTimeKind.Local)
DateTime unspecified = time;
if (time.Kind != DateTimeKind.Unspecified)
{
throw new Exception("Input time is not a Lius time.");
unspecified = DateTime.SpecifyKind(time, DateTimeKind.Unspecified);
}

DateTime unspecified = DateTime.SpecifyKind(time, DateTimeKind.Unspecified);
DateTime utc = TimeZoneInfo.ConvertTimeToUtc(unspecified, timeZone);
return utc;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using CalendarSkill.Dialogs.CreateEvent.Resources;
using CalendarSkill.Common;
using CalendarSkill.Dialogs.CreateEvent.Resources;
using CalendarSkill.Dialogs.Shared.Resources;
using Luis;
using Microsoft.Bot.Builder;
Expand Down Expand Up @@ -171,7 +172,7 @@ public CreateEventDialog(
return await sc.EndDialogAsync(true);
}

var calendarService = _serviceManager.InitCalendarService(state.APIToken, state.EventSource, state.GetUserTimeZone());
var calendarService = _serviceManager.InitCalendarService(state.APIToken, state.EventSource);
if (state.Attendees.Count == 0)
{
return await sc.BeginDialogAsync(Actions.UpdateAddress);
Expand Down Expand Up @@ -308,13 +309,13 @@ public CreateEventDialog(
Title = state.Title,
Content = state.Content,
Attendees = state.Attendees,
StartTime = (DateTime)state.StartDateTime,
EndTime = (DateTime)state.EndDateTime,
TimeZone = state.GetUserTimeZone(),
StartTime = state.StartDateTime.Value,
EndTime = state.EndDateTime.Value,
TimeZone = TimeZoneInfo.Utc,
Location = state.Location,
};

var replyMessage = sc.Context.Activity.CreateAdaptiveCardReply(CreateEventResponses.ConfirmCreate, newEvent.OnlineMeetingUrl == null ? "Dialogs/Shared/Resources/Cards/CalendarCardNoJoinButton.json" : "Dialogs/Shared/Resources/Cards/CalendarCard.json", newEvent.ToAdaptiveCardData());
var replyMessage = sc.Context.Activity.CreateAdaptiveCardReply(CreateEventResponses.ConfirmCreate, newEvent.OnlineMeetingUrl == null ? "Dialogs/Shared/Resources/Cards/CalendarCardNoJoinButton.json" : "Dialogs/Shared/Resources/Cards/CalendarCard.json", newEvent.ToAdaptiveCardData(state.GetUserTimeZone()));

return await sc.PromptAsync(Actions.TakeFurtherAction, new PromptOptions
{
Expand Down Expand Up @@ -345,13 +346,13 @@ public CreateEventDialog(
Attendees = state.Attendees,
StartTime = (DateTime)state.StartDateTime,
EndTime = (DateTime)state.EndDateTime,
TimeZone = state.GetUserTimeZone(),
TimeZone = TimeZoneInfo.Utc,
Location = state.Location,
};
var calendarService = _serviceManager.InitCalendarService(state.APIToken, state.EventSource, state.GetUserTimeZone());
var calendarService = _serviceManager.InitCalendarService(state.APIToken, state.EventSource);
if (await calendarService.CreateEvent(newEvent) != null)
{
var replyMessage = sc.Context.Activity.CreateAdaptiveCardReply(CreateEventResponses.EventCreated, newEvent.OnlineMeetingUrl == null ? "Dialogs/Shared/Resources/Cards/CalendarCardNoJoinButton.json" : "Dialogs/Shared/Resources/Cards/CalendarCard.json", newEvent.ToAdaptiveCardData());
var replyMessage = sc.Context.Activity.CreateAdaptiveCardReply(CreateEventResponses.EventCreated, newEvent.OnlineMeetingUrl == null ? "Dialogs/Shared/Resources/Cards/CalendarCardNoJoinButton.json" : "Dialogs/Shared/Resources/Cards/CalendarCard.json", newEvent.ToAdaptiveCardData(state.GetUserTimeZone()));
await sc.Context.SendActivityAsync(replyMessage);
}
else
Expand Down Expand Up @@ -678,31 +679,34 @@ public CreateEventDialog(
if (sc.Result != null)
{
IList<DateTimeResolution> dateTimeResolutions = sc.Result as List<DateTimeResolution>;
var dateTime = DateTime.Parse(dateTimeResolutions.First().Value);
var dateTimeConvertType = dateTimeResolutions.First().Timex;

if (dateTime != null)
if (dateTimeResolutions.First().Value != null)
{
bool isRelativeTime = IsRelativeTime(sc.Context.Activity.Text, dateTimeResolutions.First().Value, dateTimeResolutions.First().Timex);
if (ContainsTime(dateTimeConvertType))
{
state.StartTime = TimeZoneInfo.ConvertTime(dateTime, TimeZoneInfo.Local, state.GetUserTimeZone());
}
var dateTime = DateTime.Parse(dateTimeResolutions.First().Value);
var dateTimeConvertType = dateTimeResolutions.First().Timex;

// Workaround as DateTimePrompt only return as local time
if (isRelativeTime)
if (dateTime != null)
{
dateTime = new DateTime(
dateTime.Year,
dateTime.Month,
dateTime.Day,
DateTime.Now.Hour,
DateTime.Now.Minute,
DateTime.Now.Second);
}
bool isRelativeTime = IsRelativeTime(sc.Context.Activity.Text, dateTimeResolutions.First().Value, dateTimeResolutions.First().Timex);
if (ContainsTime(dateTimeConvertType))
{
state.StartTime = TimeZoneInfo.ConvertTime(dateTime, TimeZoneInfo.Local, state.GetUserTimeZone());
}

state.StartDate = isRelativeTime ? TimeZoneInfo.ConvertTime(dateTime, TimeZoneInfo.Local, state.GetUserTimeZone()) : dateTime;
return await sc.EndDialogAsync();
// Workaround as DateTimePrompt only return as local time
if (isRelativeTime)
{
dateTime = new DateTime(
dateTime.Year,
dateTime.Month,
dateTime.Day,
DateTime.Now.Hour,
DateTime.Now.Minute,
DateTime.Now.Second);
}

state.StartDate = isRelativeTime ? TimeZoneInfo.ConvertTime(dateTime, TimeZoneInfo.Local, state.GetUserTimeZone()) : dateTime;
return await sc.EndDialogAsync();
}
}
}

Expand Down Expand Up @@ -758,13 +762,16 @@ public CreateEventDialog(
if (sc.Result != null && state.StartTime == null)
{
IList<DateTimeResolution> dateTimeResolutions = sc.Result as List<DateTimeResolution>;
var dateTime = DateTime.Parse(dateTimeResolutions.First().Value);
var dateTimeConvertType = dateTimeResolutions.First().Timex;

if (dateTime != null)
if (dateTimeResolutions.First().Value != null)
{
bool isRelativeTime = IsRelativeTime(sc.Context.Activity.Text, dateTimeResolutions.First().Value, dateTimeResolutions.First().Timex);
state.StartTime = isRelativeTime ? TimeZoneInfo.ConvertTime(dateTime, TimeZoneInfo.Local, state.GetUserTimeZone()) : dateTime;
var dateTime = DateTime.Parse(dateTimeResolutions.First().Value);
var dateTimeConvertType = dateTimeResolutions.First().Timex;

if (dateTime != null)
{
bool isRelativeTime = IsRelativeTime(sc.Context.Activity.Text, dateTimeResolutions.First().Value, dateTimeResolutions.First().Timex);
state.StartTime = isRelativeTime ? TimeZoneInfo.ConvertTime(dateTime, TimeZoneInfo.Local, state.GetUserTimeZone()) : dateTime;
}
}
}

Expand All @@ -777,6 +784,7 @@ public CreateEventDialog(
state.StartTime.Value.Hour,
state.StartTime.Value.Minute,
state.StartTime.Value.Second);
state.StartDateTime = TimeZoneInfo.ConvertTimeToUtc(state.StartDateTime.Value, state.GetUserTimeZone());
return await sc.EndDialogAsync();
}

Expand All @@ -795,7 +803,7 @@ public CreateEventDialog(
try
{
var state = await _accessor.GetAsync(sc.Context);
if (state.Duration > 0)
if (state.Duration > 0 || state.EndTime != null || state.EndDate != null)
{
return await sc.NextAsync();
}
Expand Down Expand Up @@ -826,13 +834,36 @@ public CreateEventDialog(
try
{
var state = await _accessor.GetAsync(sc.Context);
if (state.EndDate != null || state.EndTime != null)
{
DateTime? startDate = state.StartDate == null ? TimeConverter.ConvertUtcToUserTime(DateTime.UtcNow, state.GetUserTimeZone()) : state.StartDate;
DateTime? endDate = state.EndDate;
DateTime? endTime = state.EndTime;
state.EndDateTime = endDate == null ?
new DateTime(startDate.Value.Year,
startDate.Value.Month,
startDate.Value.Day,
endTime.Value.Hour,
endTime.Value.Minute,
endTime.Value.Second) :
new DateTime(endDate.Value.Year,
endDate.Value.Month,
endDate.Value.Day, 23, 59, 59);
state.EndDateTime = TimeZoneInfo.ConvertTimeToUtc(state.EndDateTime.Value, state.GetUserTimeZone());
TimeSpan ts = state.StartDateTime.Value.Subtract(state.EndDateTime.Value).Duration();
state.Duration = (int)ts.TotalSeconds;
}

if (state.Duration <= 0 && sc.Result != null)
{
sc.Context.Activity.Properties.TryGetValue("OriginText", out var content);

IList<DateTimeResolution> dateTimeResolutions = sc.Result as List<DateTimeResolution>;
int.TryParse(dateTimeResolutions.First().Value, out int duration);
state.Duration = duration;
if (dateTimeResolutions.First().Value != null)
{
int.TryParse(dateTimeResolutions.First().Value, out int duration);
state.Duration = duration;
}
}

if (state.Duration > 0)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using CalendarSkill.Dialogs.DeleteEvent.Resources;
using CalendarSkill.Common;
using CalendarSkill.Dialogs.DeleteEvent.Resources;
using CalendarSkill.Dialogs.Main.Resources;
using CalendarSkill.Dialogs.Shared.Resources;
using Microsoft.Bot.Builder;
Expand Down Expand Up @@ -60,7 +61,7 @@ public DeleteEventDialog(
}

var deleteEvent = state.Events[0];
var replyMessage = sc.Context.Activity.CreateAdaptiveCardReply(DeleteEventResponses.ConfirmDelete, deleteEvent.OnlineMeetingUrl == null ? "Dialogs/Shared/Resources/Cards/CalendarCardNoJoinButton.json" : "Dialogs/Shared/Resources/Cards/CalendarCard.json", deleteEvent.ToAdaptiveCardData());
var replyMessage = sc.Context.Activity.CreateAdaptiveCardReply(DeleteEventResponses.ConfirmDelete, deleteEvent.OnlineMeetingUrl == null ? "Dialogs/Shared/Resources/Cards/CalendarCardNoJoinButton.json" : "Dialogs/Shared/Resources/Cards/CalendarCard.json", deleteEvent.ToAdaptiveCardData(state.GetUserTimeZone()));

return await sc.PromptAsync(Actions.TakeFurtherAction, new PromptOptions
{
Expand All @@ -80,7 +81,7 @@ public DeleteEventDialog(
try
{
var state = await _accessor.GetAsync(sc.Context);
var calendarService = _serviceManager.InitCalendarService(state.APIToken, state.EventSource, state.GetUserTimeZone());
var calendarService = _serviceManager.InitCalendarService(state.APIToken, state.EventSource);
var confirmResult = (bool)sc.Result;
if (confirmResult)
{
Expand Down Expand Up @@ -114,8 +115,7 @@ public DeleteEventDialog(
return await sc.EndDialogAsync(true);
}

var calendarService = _serviceManager.InitCalendarService(state.APIToken, state.EventSource, state.GetUserTimeZone());

var calendarService = _serviceManager.InitCalendarService(state.APIToken, state.EventSource);
if (state.StartDateTime == null)
{
return await sc.BeginDialogAsync(Actions.UpdateStartTime, new UpdateDateTimeDialogOptions(UpdateDateTimeDialogOptions.UpdateReason.NotFound));
Expand Down Expand Up @@ -152,20 +152,10 @@ public DeleteEventDialog(
}
else
{
if (state.DialogName == "DeleteEvent")
{
return await sc.PromptAsync(Actions.DateTimePromptForUpdateDelete, new PromptOptions
{
Prompt = sc.Context.Activity.CreateReply(DeleteEventResponses.NoDeleteStartTime),
});
}
else
return await sc.PromptAsync(Actions.DateTimePromptForUpdateDelete, new PromptOptions
{
return await sc.PromptAsync(Actions.DateTimePromptForUpdateDelete, new PromptOptions
{
Prompt = sc.Context.Activity.CreateReply(DeleteEventResponses.NoUpdateStartTime),
});
}
Prompt = sc.Context.Activity.CreateReply(DeleteEventResponses.NoDeleteStartTime),
});
}
}
catch
Expand All @@ -182,11 +172,11 @@ public DeleteEventDialog(
var state = await _accessor.GetAsync(sc.Context);
var events = new List<EventModel>();

var calendarService = _serviceManager.InitCalendarService(state.APIToken, state.EventSource, state.GetUserTimeZone());
var calendarService = _serviceManager.InitCalendarService(state.APIToken, state.EventSource);

if (state.StartDate != null || state.StartTime != null)
{
events = await GetEventsByTime(state.StartDate, state.StartTime, null, state.GetUserTimeZone(), calendarService);
events = await GetEventsByTime(state.StartDate, state.StartTime, state.EndDate, state.EndTime, state.GetUserTimeZone(), calendarService);
state.StartDate = null;
state.StartTime = null;
}
Expand Down Expand Up @@ -259,7 +249,7 @@ public DeleteEventDialog(
var cardsData = new List<CalendarCardData>();
foreach (var item in events)
{
var meetingCard = item.ToAdaptiveCardData();
var meetingCard = item.ToAdaptiveCardData(state.GetUserTimeZone());
var replyTemp = sc.Context.Activity.CreateAdaptiveCardReply(CalendarMainResponses.GreetingMessage, item.OnlineMeetingUrl == null ? "Dialogs/Shared/Resources/Cards/CalendarCardNoJoinButton.json" : "Dialogs/Shared/Resources/Cards/CalendarCard.json", meetingCard);
replyToConversation.Attachments.Add(replyTemp.Attachments[0]);
}
Expand Down
Loading

0 comments on commit fc97111

Please sign in to comment.