Check whether an user input is a valid date or not

I have a telegram bot which connects to my node-red and triggers a flow which generates a report. for it to work correctly, i need the user to always input the date format in YYYY-MM-DD format, when the user enters correctly, it generates a report and sends a report back to telegram.
however if the user sends an incorrect syntax, the report obviously doesnt generate, i want to send the user a message the syntax was incorrect.

is there a way to

  1. check if the entered string is a valid date in the format YYYY-MM-DD and/or
  2. restrict the user to enter always in the given format. or
  3. generate a inline keyboard in telegram whcih is similar to a datepicker. (raised a separate topic in forum already)

any help / hint appreciated.

Here is a posibility

[{"id":"781cdcca88fe5c64","type":"inject","z":"b9860b4b9de8c8da","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"24/05/2023","payloadType":"str","x":110,"y":4400,"wires":[["c7f2fa132c1fee66"]]},{"id":"c7f2fa132c1fee66","type":"change","z":"b9860b4b9de8c8da","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$moment($replace($$.payload, /[^\\d]/, \"\"), \"DDMMYYYY\").format()","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":4440,"wires":[["4ca64e0ac228f163"]]},{"id":"e9aae64c35e743f1","type":"inject","z":"b9860b4b9de8c8da","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"24-05-223","payloadType":"str","x":100,"y":4460,"wires":[["c7f2fa132c1fee66"]]},{"id":"a4d56691df5e1b59","type":"inject","z":"b9860b4b9de8c8da","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"05/24/2023","payloadType":"str","x":110,"y":4520,"wires":[["c7f2fa132c1fee66"]]},{"id":"4ca64e0ac228f163","type":"debug","z":"b9860b4b9de8c8da","name":"debug 314","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":550,"y":4440,"wires":[]}]

[edit]
$moment().isAfter()
May work better if you want to limit valid dates by years.

[{"id":"7a0882e159aa5076","type":"inject","z":"b9860b4b9de8c8da","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"01-01-1970","payloadType":"str","x":190,"y":4260,"wires":[["c7f2fa132c1fee66"]]},{"id":"c7f2fa132c1fee66","type":"change","z":"b9860b4b9de8c8da","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$moment($replace($$.payload, \"/\", \"-\"), \"DD-MM-YYYY\").isAfter(\"12-12-1969\")","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":440,"y":4360,"wires":[["4ca64e0ac228f163"]]},{"id":"781cdcca88fe5c64","type":"inject","z":"b9860b4b9de8c8da","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"24/05/2023","payloadType":"str","x":210,"y":4320,"wires":[["c7f2fa132c1fee66"]]},{"id":"e9aae64c35e743f1","type":"inject","z":"b9860b4b9de8c8da","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"24-05-223","payloadType":"str","x":200,"y":4380,"wires":[["c7f2fa132c1fee66"]]},{"id":"a4d56691df5e1b59","type":"inject","z":"b9860b4b9de8c8da","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"05/24/2023","payloadType":"str","x":210,"y":4440,"wires":[["c7f2fa132c1fee66"]]},{"id":"4ca64e0ac228f163","type":"debug","z":"b9860b4b9de8c8da","name":"debug 314","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":650,"y":4360,"wires":[]}]

Will return true or false

this would satisfy my urgent need. thanks!
I understand the logic behind it, but would never be able to build a equation with jsonata like this. ever.
my ulterior goal is to get some 'datepicker' interface in telegram. still searching for it.

Another approach, while you search, might be to use the node-red-contrib-moment node to force conversion to the format you want. Since it would let the user enter a "wrong" format, it might be best to show what the node thinks he wants and ask for confirmation. (Note the difference in how "24-05-223" is handled.)

[{"id":"8ae7b91a13d0d297","type":"moment","z":"09a7be3f235dbc42","name":"","topic":"","input":"","inputType":"msg","inTz":"America/New_York","adjAmount":0,"adjType":"days","adjDir":"add","format":"YYYY-MM-DD","locale":"en_US","output":"","outputType":"msg","outTz":"America/New_York","x":400,"y":480,"wires":[["39012510ee2fd0e5"]]},{"id":"0f7d56d53b84f998","type":"debug","z":"09a7be3f235dbc42","name":"invalid","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":890,"y":460,"wires":[]},{"id":"ce8d574622f4c3b6","type":"inject","z":"09a7be3f235dbc42","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"24/05/2023","payloadType":"str","x":150,"y":400,"wires":[["8ae7b91a13d0d297"]]},{"id":"e585ac11d87dfe4a","type":"inject","z":"09a7be3f235dbc42","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"24-05-223","payloadType":"str","x":160,"y":460,"wires":[["8ae7b91a13d0d297"]]},{"id":"dc5bbe904849c877","type":"inject","z":"09a7be3f235dbc42","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"05/24/2023","payloadType":"str","x":150,"y":520,"wires":[["8ae7b91a13d0d297"]]},{"id":"39012510ee2fd0e5","type":"switch","z":"09a7be3f235dbc42","name":"blank?","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":570,"y":480,"wires":[["edddbc89badbec01"],["5fd64bf73aa3f03e"]]},{"id":"5fd64bf73aa3f03e","type":"debug","z":"09a7be3f235dbc42","name":"possibly valid","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":740,"y":500,"wires":[]},{"id":"edddbc89badbec01","type":"change","z":"09a7be3f235dbc42","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"invalid date","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":740,"y":460,"wires":[["0f7d56d53b84f998"]]},{"id":"e39b6f8213347be7","type":"inject","z":"09a7be3f235dbc42","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"foobar","payloadType":"str","x":170,"y":580,"wires":[["8ae7b91a13d0d297"]]}]