Skip to content

[Rendering] Adaptive Card Function - utcNow() is being evaluated wrongly when rtl is true with .NET SDK using AdaptiveCards.Templating 2.0.4 nuget #9108

@devanshuGit

Description

@devanshuGit

Target Platforms

Other

SDK Version

AdaptiveCards 3.1.0 and AdaptiveCards.Templating 2.0.4

Application Name

BotFramework WebChat

Problem Description

We are trying to render current date to Input.Date field when rtl property is set to true. We found when rtl property is set to true, it uses Hijri (Islamic) calendar instead of the Gregorian calendar. So we have added locale as 'en-US' explicitly. The element in the JSON Schema is as below: { "type": "Input.Date", "id": "date", "value": "${if(fromDateTime == null || fromDateTime == '', convertFromUTC(utcNow(),timeZone,'yyyy-MM-dd','en-US'), convertFromUTC(fromDateTime,timeZone,'yyyy-MM-dd','en-US'))}", }

Same JSON schema is working in Adaptive Card designer.

We tried to print utcNow() alone and utcNow() by converting to specific format to confirm the issue is with UTC. We got output as 08/05/1446 12:36:52 for "${utcNow()}" 1446-08-05 for "${convertFromUTC(utcNow(),timeZone,'yyyy-MM-dd','en-US')}". so, we got confirmation that issue is with utcNow() when rtl is set to true

Screenshots

Expected outcome

Expecting the function is evaluated and time is set in the field as in the designer

Image

Actual outcome

Specified time is not supported in this calendar. It should be between 04/30/1900 00:00:00 (Gregorian date) and 11/16/2077 23:59:59 (Gregorian date), inclusive. (Parameter 'time')

Actual value was 456180974699650000.

Image

Card JSON

{
  "type": "AdaptiveCard",
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.5",
  "rtl": true,
  "body": [
    {
      "type": "Container",
      "id": "plaintextbox",
      "items": [
        {
          "type": "TextBlock",
          "text": "${summary}",
          "color": "Dark",
          "wrap": true
        }
      ]
    },
    {
      "type": "Container",
      "id": "formfield",
      "items": [
        {
          "type": "TextBlock",
          "text": "${convertFromUTC(utcNow(),timeZone,'yyyy-MM-dd','en-US')}"
        },
        {
          "type": "TextBlock",
          "text": "تاريخ"
        },
        {
          "type": "Input.Date",
          "id": "date",
          "value": "${if(fromDateTime == null || fromDateTime == '', convertFromUTC(utcNow(),timeZone,'yyyy-MM-dd','en-US'), convertFromUTC(fromDateTime,timeZone,'yyyy-MM-dd','en-US'))}",
          "placeholder": "أدخل تاريخا"
        },
        {
          "type": "TextBlock",
          "text": "وقت البدء",
          "wrap": true
        },
        {
          "type": "Input.Time",
          "id": "fromDateTime",
          "value": "${if(fromDateTime == null || fromDateTime == '', convertFromUTC(utcNow(), timeZone,'HH:mm'), convertFromUTC(fromDateTime,timeZone,'HH:mm'))}"
        },
        {
          "type": "TextBlock",
          "text": "وقت النهاية",
          "wrap": true
        },
        {
          "type": "Input.Time",
          "id": "toDateTime",
          "$data": "${data}",
          "value": "${if($root.toDateTime != null && $root.toDateTime != '', convertFromUTC($root.toDateTime, $root.timeZone, 'HH:mm'), if($root.fromDateTime != null && $root.fromDateTime != '', convertFromUTC(addMinutes($root.fromDateTime, defaultDurationMinute), $root.timeZone, 'HH:mm'), convertFromUTC(addMinutes(utcNow(), defaultDurationMinute), $root.timeZone, 'HH:mm')))}"
        }
      ]
    },
    {
      "type": "Container",
      "id": "SpaceFeedbackContainer",
      "items": [
        {
          "type": "ColumnSet",
          "columns": [
            {
              "type": "Column",
              "width": "auto",
              "items": [
                {
                  "type": "ActionSet",
                  "actions": [
                    {
                      "type": "Action.Submit",
                      "title": "يتأكد",
                      "associatedInputs": "auto"
                    }
                  ]
                }
              ]
            },
            {
              "type": "Column",
              "width": "auto",
              "items": [
                {
                  "type": "ActionSet",
                  "id": "whiteBtn",
                  "actions": [
                    {
                      "type": "Action.Submit",
                      "title": "يلغي",
                      "associatedInputs": "none"
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

Sample Code Language

C#

Sample Code

Template JSON
{ "type": "AdaptiveCard", "$schema": "[http://adaptivecards.io/schemas/adaptive-card.json"](http://adaptivecards.io/schemas/adaptive-card.json%22), "version": "1.5", "rtl": true, "body": [ { "type": "Container", "id": "plaintextbox", "items": [ { "type": "TextBlock", "text": "${summary}", "color": "Dark", "wrap": true } ] }, { "type": "Container", "id": "formfield", "items": [ { "type": "TextBlock", "text": "${convertFromUTC(utcNow(),timeZone,'yyyy-MM-dd','en-US')}" }, { "type": "TextBlock", "text": "تاريخ" }, { "type": "Input.Date", "id": "date", "value": "${if(fromDateTime == null || fromDateTime == '', convertFromUTC(utcNow(),timeZone,'yyyy-MM-dd','en-US'), convertFromUTC(fromDateTime,timeZone,'yyyy-MM-dd','en-US'))}", "placeholder": "أدخل تاريخا" }, { "type": "TextBlock", "text": "وقت البدء", "wrap": true }, { "type": "Input.Time", "id": "fromDateTime", "value": "${if(fromDateTime == null || fromDateTime == '', convertFromUTC(utcNow(), timeZone,'HH:mm'), convertFromUTC(fromDateTime,timeZone,'HH:mm'))}" }, { "type": "TextBlock", "text": "وقت النهاية", "wrap": true }, { "type": "Input.Time", "id": "toDateTime", "$data": "${data}", "value": "${if($root.toDateTime != null && $root.toDateTime != '', convertFromUTC($root.toDateTime, $root.timeZone, 'HH:mm'), if($root.fromDateTime != null && $root.fromDateTime != '', convertFromUTC(addMinutes($root.fromDateTime, defaultDurationMinute), $root.timeZone, 'HH:mm'), convertFromUTC(addMinutes(utcNow(), defaultDurationMinute), $root.timeZone, 'HH:mm')))}" } ] }, { "type": "Container", "id": "SpaceFeedbackContainer", "items": [ { "type": "ColumnSet", "columns": [ { "type": "Column", "width": "auto", "items": [ { "type": "ActionSet", "actions": [ { "type": "Action.Submit", "title": "يتأكد", "associatedInputs": "auto" } ] } ] }, { "type": "Column", "width": "auto", "items": [ { "type": "ActionSet", "id": "whiteBtn", "actions": [ { "type": "Action.Submit", "title": "يلغي", "associatedInputs": "none" } ] } ] } ] } ] } ] }

Data JSON
{ "summary": "الرجاء تحديد التاريخ والوقت.", "isAllDayReservation": false, "timeZone": "India Standard Time", "data": [ { "defaultDurationMinute": 15, "maxARP": 0, "maxBookingDuration": 0, "spaceTypeId": 2, "subSpaceTypeIds": [ 2 ], "earlyCheckinMinute": 15, "spaceCheckIn": true, "notificationTimes": [ { "subSpaceTypeId": 2, "time": 15 } ] } ] }

using following method in .NET solution

private AdaptiveCard GenerateAdaptiveCard(string contentPath, string cardData) { if (string.IsNullOrWhiteSpace(contentPath)) throw new ArgumentNullException(nameof(contentPath)); /if (!string.IsNullOrWhiteSpace(cardData)) throw new ArgumentNullException(nameof(cardData));/ var cardTemplate = File.ReadAllText(contentPath); var template = new AdaptiveCardTemplate(cardTemplate); var cardJson = template.Expand(cardData); //return cardJson; //// Parse the JSON AdaptiveCardParseResult result = AdaptiveCard.FromJson(cardJson); //// Get card from result AdaptiveCard card = result.Card; //card.Version = new AdaptiveSchemaVersion("1.3"); return card; ////var cardJson = new AdaptiveTransformer().Transform(cardTemplate, cardData); ////return AdaptiveCard.FromJson(cardJson).Card; } public Activity GetActivityMessageForAdaptiveCard(string contentPath, string cardData) { if (string.IsNullOrWhiteSpace(contentPath)) throw new ArgumentNullException(nameof(contentPath)); /if (!string.IsNullOrWhiteSpace(cardData)) throw new ArgumentNullException(nameof(cardData));/ var adaptiveCard = this.GenerateAdaptiveCard(contentPath, cardData); var attachment = new Microsoft.Bot.Schema.Attachment { ContentType = AdaptiveCard.ContentType, Content = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(adaptiveCard)) //JsonConvert.DeserializeObject(adaptiveCard) }; var message = MessageFactory.Text(string.Empty); message.Attachments = new List { attachment }; message.InputHint = InputHints.IgnoringInput; ////message.Text = AdaptiveCardSpeakMessage.DefaultMessage; ////message.Speak = AdaptiveCardSpeakMessage.AdaptiveCardUserNotification; return message; } var cardDataPath = "./Resources/MeetingDateTimeSelectionData.json"; var cardData = File.ReadAllText(cardDataPath);//JsonConvert.DeserializeObject(File.ReadAllText(cardDataPath)); //var cardTemplateData = JsonConvert.SerializeObject(cardData); var cardTemplatePath = "./Resources/MeetingDateTimeSelectionTemplate.json"; //await stepContext.Context.SendActivityAsync(GetActivityMessageForAdaptiveCard(cardTemplatePath, cardData), cancellationToken); await stepContext.Context.SendActivityAsync(GetActivityMessageForAdaptiveCard(cardTemplatePath, cardData), cancellationToken);

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions