Как правильно спарсить формат даты и времени для андройда и других устройств?

Код сохраняет пару ключ-значение в PlayerPrefs при выходе из игры. При входе в игру на компьютере, всё работает нормально, дата парситься и присваивается в поле lastPlayedTime, потому что в DateTime.ParseExact(s,format,provider), format стоит именно для моего компьютера. А если изменить format или скомпилировать в Apk и запустить на андройде, то выбивает исключение: FormatException: String was not recognized as a valid DateTime.

Код:

private void OnApplicationQuit()
    {
        PlayerPrefs.SetString("LastPlayedTime", DateTime.UtcNow.ToString());
    }//запись времени в PlayerPrefs при выходе из игры

private void CalcOfflineTime()
    {
        int timeSpanRestriction= 24 * 60 * 60;
        string lastPlayedTimeString = PlayerPrefs.GetString("LastPlayedTime", null);
        if (lastPlayedTimeString == null)
        return;
        //на строке ниже выбивает исключение
        DateTime date = DateTime.ParseExact(lastPlayedTimeString, "dd.MM.yyyy H:mm:ss", CultureInfo.CurrentCulture);

        double secondsSpan = (DateTime.UtcNow - date).TotalSeconds;
        if (secondsSpan > timeSpanRestriction)
            secondsSpan = timeSpanRestriction;
        data.money += secondsSpan * Power();
    }

С Thread.CurrentCulture не могу разобраться, как работает, а проблема думаю в ней. Как сделать, чтобы парсило на любом устройстве, независимо от его региональных настроек?

Обернул в try-catch. Изменил как предложено в комментариях. На компе работает, исключение в лог не пишет, на телефоне - не работает так же. Выбивает это же исключение. Код изменённый:

private void OnApplicationQuit()
    {
        PlayerPrefs.SetString("LastPlayedTime", DateTime.UtcNow.ToString(CultureInfo.InvariantCulture));
    }//запись времени в PlayerPrefs при выходе из игры

private void CalcOfflineTime()
    {
        int timeSpanRestriction = 24 * 60 * 60;
        try
        {
            var lastPlayedTimeString = PlayerPrefs.GetString("LastPlayedTime", null);
            if (lastPlayedTimeString == null)
                return;
            DateTime date = DateTime.Parse(lastPlayedTimeString, CultureInfo.InvariantCulture);
            double secondsSpan = (DateTime.UtcNow - date).TotalSeconds;
            if (secondsSpan > timeSpanRestriction)
                secondsSpan = timeSpanRestriction;
            data.money += secondsSpan * Power();
        }
        catch (Exception ex)
        {
            Debug.Log(ex);
        }
    }

Ответы (1 шт):

Автор решения: aepot

Чтобы не мучаться с культурами и хранить дату независимо от часового пояса в UTC в универсальном формате.

Вот пример для демонстрации с преобразованием туда и обратно.

DateTime date = DateTime.UtcNow;
string saveDate = date.ToString("u");
Console.WriteLine(saveDate);

DateTime newDate = DateTime.Parse(saveDate).ToUniversalTime();
Console.WriteLine(newDate.ToString("u"));

Вывод в консоль

2021-09-30 10:54:15Z
2021-09-30 10:54:15Z

То есть из исходной даты и даты, полученной после чтения из строки, получился идентичный результат, что и требовалось изначально.

→ Ссылка