using Ryujinx.HLE.HOS.Services.Time.Clock;
using Ryujinx.HLE.Utilities;
using System.IO;
using static Ryujinx.HLE.HOS.Services.Time.TimeZone.TimeZoneRule;
namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
{
class TimeZoneManager
private bool _isInitialized;
private TimeZoneRule _myRules;
private string _deviceLocationName;
private UInt128 _timeZoneRuleVersion;
private uint _totalLocationNameCount;
private SteadyClockTimePoint _timeZoneUpdateTimePoint;
private object _lock;
public TimeZoneManager()
_isInitialized = false;
_deviceLocationName = "UTC";
_timeZoneRuleVersion = new UInt128();
_lock = new object();
// Empty rules
_myRules = new TimeZoneRule
Ats = new long[TzMaxTimes],
Types = new byte[TzMaxTimes],
Ttis = new TimeTypeInfo[TzMaxTypes],
Chars = new char[TzCharsArraySize]
};
_timeZoneUpdateTimePoint = SteadyClockTimePoint.GetRandom();
}
public bool IsInitialized()
bool res;
lock (_lock)
res = _isInitialized;
return res;
public void MarkInitialized()
_isInitialized = true;
public ResultCode GetDeviceLocationName(out string deviceLocationName)
ResultCode result = ResultCode.UninitializedClock;
deviceLocationName = null;
if (_isInitialized)
deviceLocationName = _deviceLocationName;
result = ResultCode.Success;
return result;
public ResultCode SetDeviceLocationNameWithTimeZoneRule(string locationName, Stream timeZoneBinaryStream)
ResultCode result = ResultCode.TimeZoneConversionFailed;
bool timeZoneConversionSuccess = TimeZone.ParseTimeZoneBinary(out TimeZoneRule rules, timeZoneBinaryStream);
if (timeZoneConversionSuccess)
_deviceLocationName = locationName;
_myRules = rules;
public void SetTotalLocationNameCount(uint totalLocationNameCount)
_totalLocationNameCount = totalLocationNameCount;
public ResultCode GetTotalLocationNameCount(out uint totalLocationNameCount)
totalLocationNameCount = 0;
totalLocationNameCount = _totalLocationNameCount;
public ResultCode SetUpdatedTime(SteadyClockTimePoint timeZoneUpdatedTimePoint, bool bypassUninitialized = false)
if (_isInitialized || bypassUninitialized)
_timeZoneUpdateTimePoint = timeZoneUpdatedTimePoint;
public ResultCode GetUpdatedTime(out SteadyClockTimePoint timeZoneUpdatedTimePoint)
ResultCode result;
timeZoneUpdatedTimePoint = _timeZoneUpdateTimePoint;
else
timeZoneUpdatedTimePoint = SteadyClockTimePoint.GetRandom();
result = ResultCode.UninitializedClock;
public ResultCode ParseTimeZoneRuleBinary(out TimeZoneRule outRules, Stream timeZoneBinaryStream)
ResultCode result = ResultCode.Success;
bool timeZoneConversionSuccess = TimeZone.ParseTimeZoneBinary(out outRules, timeZoneBinaryStream);
if (!timeZoneConversionSuccess)
result = ResultCode.TimeZoneConversionFailed;
public void SetTimeZoneRuleVersion(UInt128 timeZoneRuleVersion)
_timeZoneRuleVersion = timeZoneRuleVersion;
public ResultCode GetTimeZoneRuleVersion(out UInt128 timeZoneRuleVersion)
timeZoneRuleVersion = _timeZoneRuleVersion;
timeZoneRuleVersion = new UInt128();
public ResultCode ToCalendarTimeWithMyRules(long time, out CalendarInfo calendar)
result = ToCalendarTime(_myRules, time, out calendar);
calendar = new CalendarInfo();
public ResultCode ToCalendarTime(TimeZoneRule rules, long time, out CalendarInfo calendar)
result = TimeZone.ToCalendarTime(rules, time, out calendar);
public ResultCode ToPosixTimeWithMyRules(CalendarTime calendarTime, out long posixTime)
result = ToPosixTime(_myRules, calendarTime, out posixTime);
posixTime = 0;
public ResultCode ToPosixTime(TimeZoneRule rules, CalendarTime calendarTime, out long posixTime)
result = TimeZone.ToPosixTime(rules, calendarTime, out posixTime);