Search code examples
datedatepickerbotframeworkmicrosoft-teamsadaptive-cards

Why does Adaptive Card Input.Date subtract 1 day from the selected date?


Using botframework with msteams channel.

enter image description here

The adaptive card. Nothing special, just a few textblocks and date inputs. The input values are saved to memory.

{
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "type": "AdaptiveCard",
  "version": "1.3",
  "body": [
    {
      "type": "ColumnSet",
      "columns": [
        {
          "type": "Column",
          "style": "emphasis",
          "width": 2,
          "items": [
            {
              "type": "TextBlock",
              "text": "Please enter the information below",
              "size": "Large"
            },
            {
              "type": "Container",
              "style": "emphasis",
              "items": [
                {
                  "type": "TextBlock",
                  "text": "End Of Last Month",
                  "wrap": true
                },
                {
                  "type": "Input.Date",                  
                  "id": "Date_EndOfLastMonth",
                  "value": "${dialog.requestForm.Date_EndOfLastMonth}",
                  "placeholder": ""
                },
                {
                  "type": "TextBlock",
                  "text": "${dialog.requestForm.Date_EndOfLastMonthError}",
                  "size": "small",
                  "wrap": true,
                  "color": "attention"
                }
              ]
            },
            {
              "type": "Container",
              "style": "emphasis",
              "items": [
                {
                  "type": "TextBlock",
                  "text": "End Of Last Year",
                  "wrap": true
                },
                {
                  "type": "Input.Date",                  
                  "id": "Date_EndOfLastYear",
                  "value": "${dialog.requestForm.Date_EndOfLastYear}",
                  "placeholder": ""
                },
                {
                  "type": "TextBlock",
                  "text": "${dialog.requestForm.Date_EndOfLastYearError}",
                  "size": "small",
                  "wrap": true,
                  "color": "attention"
                }
              ]
            },
            {
              "type": "Container",
              "style": "emphasis",
              "items": [
                {
                  "type": "TextBlock",
                  "text": "Valuation Key Date",
                  "wrap": true
                },
                {
                  "type": "Input.Date",                  
                  "id": "ValuationKeyDate",
                  "value": "${dialog.requestForm.ValuationKeyDate}",
                  "placeholder": ""
                },
                {
                  "type": "TextBlock",
                  "text": "${dialog.requestForm.ValuationKeyDateError}",
                  "size": "small",
                  "wrap": true,
                  "color": "attention"
                }
              ]
            },
            {
              "type": "Container",
              "style": "emphasis",
              "items": [
                {
                  "type": "ActionSet",
                  "actions": [
                    {
                      "type": "Action.Submit",
                      "title": "Submit",
                      "data": {
                        "msteams": {
                          "type": "messageBack",
                          "displayText": "Form Submitted",
                          "text": "submitform"
                        }
                      }
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

The code that goes with the card. I save the input values to memory, so when there is a reprompt happening, I can fill them back to the form. In the last part are the lines for debugging. I am printing out the values directly from the activity, so nothing happens between the submission and the debug.

new CodeAction(async (dc, options) =>
                            {
                                dc.State.SetValue("dialog.requestForm.Date_EndOfLastMonth", "");
                                dc.State.SetValue("dialog.requestForm.Date_EndOfLastYear", "");
                                dc.State.SetValue("dialog.requestForm.ValuationKeyDate", ""); //ValuationKeyDate

                                dc.State.SetValue("dialog.requestForm.Date_EndOfLastMonthError", "");
                                dc.State.SetValue("dialog.requestForm.Date_EndOfLastYearError", "");
                                dc.State.SetValue("dialog.requestForm.ValuationKeyDateError", "");

                                return await dc.EndDialogAsync();
                            }),
                            new TextInput()
                            {
                                Id = "repromptTRT",
                                Prompt = new ActivityTemplate("${TreasuryCase()}"),
                                AllowInterruptions = true,
                                MaxTurnCount = "if(turn.activity.text != 'submitform', '0', '100')",
                            },                            
                            // deal with interrupt, cancel everything else                            
                            new IfCondition()
                            {
                                Condition = "turn.activity.text != 'submitform'",
                                Actions = new List<Dialog>()
                                {
                                    new EndDialog()
                                }
                            },
                            // save form
                            new CodeAction(async (dc, options) =>
                            {
                                var json = JsonConvert.SerializeObject(dc.Context.Activity.Value);

                                await dc.Context.SendActivityAsync(MessageFactory.Text(json));

                                var d = JsonConvert.SerializeObject(DateTime.Now);

                                await dc.Context.SendActivityAsync(MessageFactory.Text(d));

                                var o = JsonConvert.DeserializeObject<TC>(json);                                

                                dc.State.SetValue("dialog.requestForm", o);

                                return await dc.EndDialogAsync();
                            }),  

Solution

  • For more visibility, adding answer here from comment section: The fix should be rolling through the rings, so the change should manifest in public clients in a couple of weeks.