diff -Nuar a/vendor/magento/module-catalog/Block/Product/View/Options/Type/Date.php b/vendor/magento/module-catalog/Block/Product/View/Options/Type/Date.php
--- a/vendor/magento/module-catalog/Block/Product/View/Options/Type/Date.php
+++ b/vendor/magento/module-catalog/Block/Product/View/Options/Type/Date.php
@@ -83,7 +83,7 @@ class Date extends \Magento\Catalog\Block\Product\View\Options\AbstractOptions
         $yearEnd = $this->_catalogProductOptionTypeDate->getYearEnd();
 
         $dateFormat = $this->_localeDate->getDateFormat(\IntlDateFormatter::SHORT);
-        /** Escape invisible characters which are present in some locales and may corrupt formatting */
+        /** Escape RTL characters which are present in some locales and corrupt formatting */
         $escapedDateFormat = preg_replace('/[^MmDdYy\/\.\-]/', '', $dateFormat);
         $calendar = $this->getLayout()->createBlock(
             'Magento\Framework\View\Element\Html\Date'
diff -Nuar a/vendor/magento/module-catalog/Model/Product/Option/Type/Date.php b/vendor/magento/module-catalog/Model/Product/Option/Type/Date.php
--- a/vendor/magento/module-catalog/Model/Product/Option/Type/Date.php
+++ b/vendor/magento/module-catalog/Model/Product/Option/Type/Date.php
@@ -142,7 +142,7 @@ class Date extends \Magento\Catalog\Model\Product\Option\Type\DefaultType
 
             if ($this->_dateExists()) {
                 if ($this->useCalendar()) {
-                    $timestamp += $this->_localeDate->date($value['date'], null, true)->getTimestamp();
+                    $timestamp += $this->_localeDate->date($value['date'], null, true, false)->getTimestamp();
                 } else {
                     $timestamp += mktime(0, 0, 0, $value['month'], $value['day'], $value['year']);
                 }
diff -Nuar a/vendor/magento/framework/Stdlib/DateTime/Timezone.php b/vendor/magento/framework/Stdlib/DateTime/Timezone.php
--- a/vendor/magento/framework/Stdlib/DateTime/Timezone.php
+++ b/vendor/magento/framework/Stdlib/DateTime/Timezone.php
@@ -151,27 +151,33 @@ class Timezone implements TimezoneInterface
 
     /**
      * {@inheritdoc}
-     * @SuppressWarnings(PHPMD.NPathComplexity)
      */
-    public function date($date = null, $locale = null, $useTimezone = true)
+    public function date($date = null, $locale = null, $useTimezone = true, $includeTime = true)
     {
         $locale = $locale ?: $this->_localeResolver->getLocale();
         $timezone = $useTimezone
             ? $this->getConfigTimezone()
             : date_default_timezone_get();
 
-        if (empty($date)) {
-            return new \DateTime('now', new \DateTimeZone($timezone));
-        } elseif ($date instanceof \DateTime) {
-            return $date->setTimezone(new \DateTimeZone($timezone));
-        } elseif (!is_numeric($date)) {
-            $formatter = new \IntlDateFormatter(
-                $locale,
-                \IntlDateFormatter::SHORT,
-                \IntlDateFormatter::NONE
-            );
-            $date = $formatter->parse($date) ?: (new \DateTime($date))->getTimestamp();
+        switch (true) {
+            case (empty($date)):
+                return new \DateTime('now', new \DateTimeZone($timezone));
+            case ($date instanceof \DateTime):
+                return $date->setTimezone(new \DateTimeZone($timezone));
+            case ($date instanceof \DateTimeImmutable):
+                return new \DateTime($date->format('Y-m-d H:i:s'), $date->getTimezone());
+            case (!is_numeric($date)):
+                $timeType = $includeTime ? \IntlDateFormatter::SHORT : \IntlDateFormatter::NONE;
+                $formatter = new \IntlDateFormatter(
+                    $locale,
+                    \IntlDateFormatter::SHORT,
+                    $timeType,
+                    new \DateTimeZone($timezone)
+                );
+                $date = $formatter->parse($date) ?: (new \DateTime($date))->getTimestamp();
+                break;
         }
+
         return (new \DateTime(null, new \DateTimeZone($timezone)))->setTimestamp($date);
     }
 
@@ -195,7 +201,7 @@ class Timezone implements TimezoneInterface
     {
         $formatTime = $showTime ? $format : \IntlDateFormatter::NONE;
 
-        if (!($date instanceof \DateTime)) {
+        if (!($date instanceof \DateTimeInterface)) {
             $date = new \DateTime($date);
         }
 
@@ -258,7 +264,7 @@ class Timezone implements TimezoneInterface
         $timezone = null,
         $pattern = null
     ) {
-        if (!($date instanceof \DateTime)) {
+        if (!($date instanceof \DateTimeInterface)) {
             $date = new \DateTime($date);
         }
 
@@ -294,8 +300,12 @@ class Timezone implements TimezoneInterface
      */
     public function convertConfigTimeToUtc($date, $format = 'Y-m-d H:i:s')
     {
-        if (!($date instanceof \DateTime)) {
-            $date = new \DateTime($date, new \DateTimeZone($this->getConfigTimezone()));
+        if (!($date instanceof \DateTimeInterface)) {
+            if ($date instanceof \DateTimeImmutable) {
+                $date = new \DateTime($date->format('Y-m-d H:i:s'), new \DateTimeZone($this->getConfigTimezone()));
+            } else {
+                $date = new \DateTime($date, new \DateTimeZone($this->getConfigTimezone()));
+            }
         } else {
             if ($date->getTimezone()->getName() !== $this->getConfigTimezone()) {
                 throw new LocalizedException(
diff -Nuar a/vendor/magento/framework/Stdlib/DateTime/TimezoneInterface.php b/vendor/magento/framework/Stdlib/DateTime/TimezoneInterface.php
--- a/vendor/magento/framework/Stdlib/DateTime/TimezoneInterface.php
+++ b/vendor/magento/framework/Stdlib/DateTime/TimezoneInterface.php
@@ -65,9 +65,10 @@ interface TimezoneInterface
      * @param mixed $date
      * @param string $locale
      * @param bool $useTimezone
+     * @param bool $includeTime
      * @return \DateTime
      */
-    public function date($date = null, $locale = null, $useTimezone = true);
+    public function date($date = null, $locale = null, $useTimezone = true, $includeTime = true);
 
     /**
      * Create \DateTime object with date converted to scope timezone and scope Locale
