diff --git a/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php b/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php
index 8dc920906031dbd607b2bce8531d4401a7c1ed42..53d2444242c3605760bb42b4f345ca4df2498d94 100644
--- a/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php
+++ b/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php
@@ -22,7 +22,10 @@ use TYPO3\CMS\Backend\Form\NodeFactory;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Imaging\IconFactory;
+use TYPO3\CMS\Core\Localization\DateFormatter;
 use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Localization\Locale;
+use TYPO3\CMS\Core\Localization\Locales;
 use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction;
 use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -195,8 +198,13 @@ abstract class AbstractFormElement extends AbstractNode
                     $option = isset($formatOptions['option']) ? trim($formatOptions['option']) : '';
                     if ($option) {
                         if (isset($formatOptions['strftime']) && $formatOptions['strftime']) {
-                            // @todo Replace deprecated strftime in php 8.1. Suppress warning in v11.
-                            $value = @strftime($option, (int)$itemValue);
+                            $user = $this->getBackendUser();
+                            if ($user->user['lang'] ?? false) {
+                                $locale = GeneralUtility::makeInstance(Locales::class)->createLocale($user->user['lang']);
+                            } else {
+                                $locale = new Locale();
+                            }
+                            $value = (new DateFormatter())->strftime($option, (int)$itemValue, $locale);
                         } else {
                             $value = date($option, (int)$itemValue);
                         }
diff --git a/typo3/sysext/backend/Tests/Unit/Form/Element/AbstractFormElementTest.php b/typo3/sysext/backend/Tests/Unit/Form/Element/AbstractFormElementTest.php
index ec36959c6575caa98ee78b57a4e7575c8468b7c4..124ff1e16c02e48b06714a3ce997130ca9338965 100644
--- a/typo3/sysext/backend/Tests/Unit/Form/Element/AbstractFormElementTest.php
+++ b/typo3/sysext/backend/Tests/Unit/Form/Element/AbstractFormElementTest.php
@@ -18,6 +18,7 @@ declare(strict_types=1);
 namespace TYPO3\CMS\Backend\Tests\Unit\Form\Element;
 
 use TYPO3\CMS\Backend\Form\Element\AbstractFormElement;
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
 
 class AbstractFormElementTest extends UnitTestCase
@@ -270,6 +271,7 @@ class AbstractFormElementTest extends UnitTestCase
      */
     public function formatValueWithGivenConfiguration(array $config, ?string $itemValue, string $expectedResult): void
     {
+        $GLOBALS['BE_USER'] = new BackendUserAuthentication();
         $subject = $this->getAccessibleMock(AbstractFormElement::class, ['render'], [], '', false);
         $timezoneBackup = date_default_timezone_get();
         date_default_timezone_set('UTC');
diff --git a/typo3/sysext/core/Classes/Localization/DateFormatter.php b/typo3/sysext/core/Classes/Localization/DateFormatter.php
index a48268e6b6cf92c7f2051dcc6712028911d507a5..be6fa5f72dd358cb8ee80bcafde271cf3a64926a 100644
--- a/typo3/sysext/core/Classes/Localization/DateFormatter.php
+++ b/typo3/sysext/core/Classes/Localization/DateFormatter.php
@@ -58,4 +58,196 @@ class DateFormatter
         }
         return $dateFormatter->format($date) ?: '';
     }
+
+    /**
+     * Locale-formatted strftime using IntlDateFormatter (PHP 8.1 compatible)
+     * This provides a cross-platform alternative to strftime() for when it will be removed from PHP.
+     * Note that output can be slightly different between libc sprintf and this function as it is using ICU.
+     *
+     * Original author BohwaZ <https://bohwaz.net/>
+     * Adapted from https://github.com/alphp/strftime
+     * MIT licensed
+     */
+    public function strftime(string $format, int|string|\DateTimeInterface|null $timestamp, string|Locale|null $locale = null, $useUtcTimeZone = false): string
+    {
+        if (!($timestamp instanceof \DateTimeInterface)) {
+            $timestamp = is_int($timestamp) ? '@' . $timestamp : (string)$timestamp;
+            try {
+                $timestamp = new \DateTime($timestamp);
+            } catch (\Exception $e) {
+                throw new \InvalidArgumentException('$timestamp argument is neither a valid UNIX timestamp, a valid date-time string or a DateTime object.', 1679091446, $e);
+            }
+            $timestamp->setTimezone(new \DateTimeZone($useUtcTimeZone ? 'UTC' : date_default_timezone_get()));
+        }
+
+        if (empty($locale)) {
+            // get current locale
+            $locale = setlocale(LC_TIME, '0');
+        } else {
+            $locale = (string)$locale;
+        }
+        // remove trailing part not supported by ext-intl locale
+        $locale = preg_replace('/[^\w-].*$/', '', $locale);
+
+        $intl_formats = [
+            '%a' => 'EEE',	// An abbreviated textual representation of the day	Sun through Sat
+            '%A' => 'EEEE',	// A full textual representation of the day	Sunday through Saturday
+            '%b' => 'MMM',	// Abbreviated month name, based on the locale	Jan through Dec
+            '%B' => 'MMMM',	// Full month name, based on the locale	January through December
+            '%h' => 'MMM',	// Abbreviated month name, based on the locale (an alias of %b)	Jan through Dec
+        ];
+
+        $intl_formatter = function (\DateTimeInterface $timestamp, string $format) use ($intl_formats, $locale): string {
+            $tz = $timestamp->getTimezone();
+            $date_type = \IntlDateFormatter::FULL;
+            $time_type = \IntlDateFormatter::FULL;
+            $pattern = '';
+
+            switch ($format) {
+                // %c = Preferred date and time stamp based on locale
+                // Example: Tue Feb 5 00:45:10 2009 for February 5, 2009 at 12:45:10 AM
+                case '%c':
+                    $date_type = \IntlDateFormatter::LONG;
+                    $time_type = \IntlDateFormatter::SHORT;
+                    break;
+
+                    // %x = Preferred date representation based on locale, without the time
+                    // Example: 02/05/09 for February 5, 2009
+                case '%x':
+                    $date_type = \IntlDateFormatter::SHORT;
+                    $time_type = \IntlDateFormatter::NONE;
+                    break;
+
+                    // Localized time format
+                case '%X':
+                    $date_type = \IntlDateFormatter::NONE;
+                    $time_type = \IntlDateFormatter::MEDIUM;
+                    break;
+
+                default:
+                    $pattern = $intl_formats[$format];
+            }
+
+            // In October 1582, the Gregorian calendar replaced the Julian in much of Europe, and
+            //  the 4th October was followed by the 15th October.
+            // ICU (including IntlDateFormattter) interprets and formats dates based on this cutover.
+            // Posix (including strftime) and timelib (including DateTimeImmutable) instead use
+            //  a "proleptic Gregorian calendar" - they pretend the Gregorian calendar has existed forever.
+            // This leads to the same instants in time, as expressed in Unix time, having different representations
+            //  in formatted strings.
+            // To adjust for this, a custom calendar can be supplied with a cutover date arbitrarily far in the past.
+            $calendar = \IntlGregorianCalendar::createInstance();
+            $calendar->setGregorianChange(PHP_INT_MIN);
+
+            return (new \IntlDateFormatter($locale, $date_type, $time_type, $tz, $calendar, $pattern))->format($timestamp) ?: '';
+        };
+
+        // Same order as https://www.php.net/manual/en/function.strftime.php
+        $translation_table = [
+            // Day
+            '%a' => $intl_formatter,
+            '%A' => $intl_formatter,
+            '%d' => 'd',
+            '%e' => function (\DateTimeInterface $timestamp, string $_): string {
+                return sprintf('% 2u', $timestamp->format('j'));
+            },
+            '%j' => function (\DateTimeInterface $timestamp, string $_): string {
+                // Day number in year, 001 to 366
+                return sprintf('%03d', (int)($timestamp->format('z'))+1);
+            },
+            '%u' => 'N',
+            '%w' => 'w',
+
+            // Week
+            '%U' => function (\DateTimeInterface $timestamp, string $_): string {
+                // Number of weeks between date and first Sunday of year
+                $day = new \DateTime(sprintf('%d-01 Sunday', $timestamp->format('Y')));
+                return sprintf('%02u', 1 + ($timestamp->format('z') - $day->format('z')) / 7);
+            },
+            '%V' => 'W',
+            '%W' => function (\DateTimeInterface $timestamp, string $_): string {
+                // Number of weeks between date and first Monday of year
+                $day = new \DateTime(sprintf('%d-01 Monday', $timestamp->format('Y')));
+                return sprintf('%02u', 1 + ($timestamp->format('z') - $day->format('z')) / 7);
+            },
+
+            // Month
+            '%b' => $intl_formatter,
+            '%B' => $intl_formatter,
+            '%h' => $intl_formatter,
+            '%m' => 'm',
+
+            // Year
+            '%C' => function (\DateTimeInterface $timestamp, string $_): string {
+                // Century (-1): 19 for 20th century
+                return (string)floor($timestamp->format('Y') / 100);
+            },
+            '%g' => function (\DateTimeInterface $timestamp, string $_): string {
+                return substr($timestamp->format('o'), -2);
+            },
+            '%G' => 'o',
+            '%y' => 'y',
+            '%Y' => 'Y',
+
+            // Time
+            '%H' => 'H',
+            '%k' => function (\DateTimeInterface $timestamp, string $_): string {
+                return sprintf('% 2u', $timestamp->format('G'));
+            },
+            '%I' => 'h',
+            '%l' => function (\DateTimeInterface $timestamp, string $_): string {
+                return sprintf('% 2u', $timestamp->format('g'));
+            },
+            '%M' => 'i',
+            '%p' => 'A', // AM PM (this is reversed on purpose!)
+            '%P' => 'a', // am pm
+            '%r' => 'h:i:s A', // %I:%M:%S %p
+            '%R' => 'H:i', // %H:%M
+            '%S' => 's',
+            '%T' => 'H:i:s', // %H:%M:%S
+            '%X' => $intl_formatter, // Preferred time representation based on locale, without the date
+
+            // Timezone
+            '%z' => 'O',
+            '%Z' => 'T',
+
+            // Time and Date Stamps
+            '%c' => $intl_formatter,
+            '%D' => 'm/d/Y',
+            '%F' => 'Y-m-d',
+            '%s' => 'U',
+            '%x' => $intl_formatter,
+        ];
+
+        $out = preg_replace_callback('/(?<!%)%([_#-]?)([a-zA-Z])/', function ($match) use ($translation_table, $timestamp) {
+            $prefix = $match[1];
+            $char = $match[2];
+            $pattern = '%' . $char;
+            if ($pattern == '%n') {
+                return "\n";
+            }
+            if ($pattern == '%t') {
+                return "\t";
+            }
+
+            if (!isset($translation_table[$pattern])) {
+                throw new \InvalidArgumentException(sprintf('Format "%s" is unknown in time format', $pattern), 1679091475);
+            }
+
+            $replace = $translation_table[$pattern];
+
+            if (is_string($replace)) {
+                $result = $timestamp->format($replace);
+            } else {
+                $result = $replace($timestamp, $pattern);
+            }
+
+            return match ($prefix) {
+                '_' => preg_replace('/\G0(?=.)/', ' ', $result),
+                '#', '-' => preg_replace('/^0+(?=.)/', '', $result),
+                default => $result,
+            };
+        }, $format);
+        return str_replace('%%', '%', $out);
+    }
 }
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/RelationTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/RelationTest.php
index a02f23e4b33da11cd8604b8977719900679fd2ca..c0ac612e36619f1f94aa2e6c978984e4d92f711d 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/RelationTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/RelationTest.php
@@ -555,8 +555,7 @@ class RelationTest extends FunctionalTestCase
         $tags = clone $post->getTags();
         $post->setTags(new ObjectStorage());
 
-        // @todo Replace deprecated strftime in php 8.1. Suppress warning in v11.
-        $newTag = new Tag('INSERTED TAG at position 6 : ' . @strftime(''));
+        $newTag = new Tag('INSERTED TAG at position 6 : ');
 
         $counter = 1;
         foreach ($tags as $tag) {
diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/Format/DateViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/Format/DateViewHelper.php
index 462baa0bbb3ce4e58ad47f661118b5495f5850b3..3fc3fdd852ade70353d0a8c1780f089bb71f5fd6 100644
--- a/typo3/sysext/fluid/Classes/ViewHelpers/Format/DateViewHelper.php
+++ b/typo3/sysext/fluid/Classes/ViewHelpers/Format/DateViewHelper.php
@@ -195,8 +195,9 @@ final class DateViewHelper extends AbstractViewHelper
             return (new DateFormatter())->format($date, $pattern, $locale);
         }
         if (str_contains($format, '%')) {
-            // @todo Replace deprecated strftime in php 8.1. Suppress warning in v11.
-            return @strftime($format, (int)$date->format('U'));
+            // @todo: deprecate this syntax in TYPO3 v13.
+            $locale = $arguments['locale'] ?? self::resolveLocale($renderingContext);
+            return (new DateFormatter())->format($date, $format, $locale);
         }
         return $date->format($format);
     }
diff --git a/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php b/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
index 8d64ec2f4decd814a3e1638a7606cca137267a60..abb029fd17aa954ae2888c41b4b1319b97f2f051 100644
--- a/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
+++ b/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
@@ -1871,15 +1871,14 @@ class ContentObjectRenderer implements LoggerAwareInterface
      * @param string $content Input value undergoing processing in this function.
      * @param array $conf stdWrap properties for strftime.
      * @return string The processed input value
-     * @todo @todo Replace deprecated strftime/gmstrftime and whole method in php 8.1. Suppress warning in v11.
      */
     public function stdWrap_strftime($content = '', $conf = [])
     {
         // Check for zero length string to mimic default case of strtime/gmstrftime
         $content = (string)$content === '' ? $GLOBALS['EXEC_TIME'] : (int)$content;
         $content = (isset($conf['strftime.']['GMT']) && $conf['strftime.']['GMT'])
-            ? @gmstrftime($conf['strftime'] ?? null, $content)
-            : @strftime($conf['strftime'] ?? null, $content);
+            ? (new DateFormatter())->strftime($conf['strftime'] ?? '', $content, null, true)
+            : (new DateFormatter())->strftime($conf['strftime'] ?? '', $content);
         if (!empty($conf['strftime.']['charset'])) {
             $output = mb_convert_encoding((string)$content, 'utf-8', trim(strtolower($conf['strftime.']['charset'])));
             return $output ?: $content;
diff --git a/typo3/sysext/impexp/Classes/Export.php b/typo3/sysext/impexp/Classes/Export.php
index 973413c2e7d3f1e6e2dbb4f75b47814f9a98f2b0..2f518959ef40db9a024e68912e98aa9322252ac4 100644
--- a/typo3/sysext/impexp/Classes/Export.php
+++ b/typo3/sysext/impexp/Classes/Export.php
@@ -29,6 +29,9 @@ use TYPO3\CMS\Core\Database\ReferenceIndex;
 use TYPO3\CMS\Core\Exception;
 use TYPO3\CMS\Core\Html\HtmlParser;
 use TYPO3\CMS\Core\Information\Typo3Version;
+use TYPO3\CMS\Core\Localization\DateFormatter;
+use TYPO3\CMS\Core\Localization\Locale;
+use TYPO3\CMS\Core\Localization\Locales;
 use TYPO3\CMS\Core\Resource\Exception\InsufficientFolderWritePermissionsException;
 use TYPO3\CMS\Core\Resource\File;
 use TYPO3\CMS\Core\Resource\Folder;
@@ -314,6 +317,12 @@ class Export extends ImportExport
      */
     protected function setMetaData(): void
     {
+        $user = $this->getBackendUser();
+        if ($user->user['lang'] ?? false) {
+            $locale = GeneralUtility::makeInstance(Locales::class)->createLocale($user->user['lang']);
+        } else {
+            $locale = new Locale();
+        }
         $this->dat['header']['meta'] = [
             'title' => $this->title,
             'description' => $this->description,
@@ -322,8 +331,7 @@ class Export extends ImportExport
             'packager_name' => $this->getBackendUser()->user['realName'],
             'packager_email' => $this->getBackendUser()->user['email'],
             'TYPO3_version' => (string)GeneralUtility::makeInstance(Typo3Version::class),
-            // @todo Replace deprecated strftime in php 8.1. Suppress warning in v11.
-            'created' => @strftime('%A %e. %B %Y', $GLOBALS['EXEC_TIME']),
+            'created' => (new DateFormatter())->format($GLOBALS['EXEC_TIME'], 'EEE d. MMMM y', $locale),
         ];
     }
 
diff --git a/typo3/sysext/lowlevel/Classes/Controller/DatabaseIntegrityController.php b/typo3/sysext/lowlevel/Classes/Controller/DatabaseIntegrityController.php
index fe1014e76377755c6f9f776e3def88c37fcc5897..34cf2e48a89a9f8b3b0c0ee5d1dfa885c9f4dfdc 100644
--- a/typo3/sysext/lowlevel/Classes/Controller/DatabaseIntegrityController.php
+++ b/typo3/sysext/lowlevel/Classes/Controller/DatabaseIntegrityController.php
@@ -38,7 +38,10 @@ use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
 use TYPO3\CMS\Core\Database\ReferenceIndex;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
+use TYPO3\CMS\Core\Localization\DateFormatter;
 use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Localization\Locale;
+use TYPO3\CMS\Core\Localization\Locales;
 use TYPO3\CMS\Core\Messaging\FlashMessage;
 use TYPO3\CMS\Core\Messaging\FlashMessageRendererResolver;
 use TYPO3\CMS\Core\Messaging\FlashMessageService;
@@ -861,6 +864,12 @@ class DatabaseIntegrityController
     {
         $out = '';
         $fields = [];
+        $user = $this->getBackendUserAuthentication();
+        if ($user->user['lang'] ?? false) {
+            $locale = GeneralUtility::makeInstance(Locales::class)->createLocale($user->user['lang']);
+        } else {
+            $locale = new Locale();
+        }
         // Analysing the fields in the table.
         if (is_array($GLOBALS['TCA'][$table] ?? null)) {
             $fC = $GLOBALS['TCA'][$table]['columns'][$fieldName] ?? null;
@@ -945,18 +954,17 @@ class DatabaseIntegrityController
         switch ($fields['type']) {
             case 'date':
                 if ($fieldValue != -1) {
-                    // @todo Replace deprecated strftime in php 8.1. Suppress warning in v11.
-                    $out = (string)@strftime('%d-%m-%Y', (int)$fieldValue);
+                    $formatter = new DateFormatter();
+                    $out = $formatter->format((int)$fieldValue, 'SHORTDATE', $locale);
                 }
                 break;
             case 'time':
                 if ($fieldValue != -1) {
+                    $formatter = new DateFormatter();
                     if ($splitString === '<br />') {
-                        // @todo Replace deprecated strftime in php 8.1. Suppress warning in v11.
-                        $out = (string)@strftime('%H:%M' . $splitString . '%d-%m-%Y', (int)$fieldValue);
+                        $out = $formatter->format((int)$fieldValue, 'HH:mm\'' . $splitString . '\'dd-MM-yyyy', $locale);
                     } else {
-                        // @todo Replace deprecated strftime in php 8.1. Suppress warning in v11.
-                        $out = (string)@strftime('%H:%M %d-%m-%Y', (int)$fieldValue);
+                        $out = $formatter->format((int)$fieldValue, 'HH:mm dd-MM-yyyy', $locale);
                     }
                 }
                 break;