mirror of
https://github.com/godotengine/godot
synced 2024-09-05 07:39:34 +00:00
Fixes #65377: get_datetime_* functions can return wrong values
This commit is contained in:
parent
27e1323473
commit
0aecfc9254
|
@ -93,15 +93,14 @@ String Resource::get_path() const {
|
|||
String Resource::generate_scene_unique_id() {
|
||||
// Generate a unique enough hash, but still user-readable.
|
||||
// If it's not unique it does not matter because the saver will try again.
|
||||
OS::Date date = OS::get_singleton()->get_date();
|
||||
OS::Time time = OS::get_singleton()->get_time();
|
||||
OS::DateTime dt = OS::get_singleton()->get_datetime();
|
||||
uint32_t hash = hash_murmur3_one_32(OS::get_singleton()->get_ticks_usec());
|
||||
hash = hash_murmur3_one_32(date.year, hash);
|
||||
hash = hash_murmur3_one_32(date.month, hash);
|
||||
hash = hash_murmur3_one_32(date.day, hash);
|
||||
hash = hash_murmur3_one_32(time.hour, hash);
|
||||
hash = hash_murmur3_one_32(time.minute, hash);
|
||||
hash = hash_murmur3_one_32(time.second, hash);
|
||||
hash = hash_murmur3_one_32(dt.year, hash);
|
||||
hash = hash_murmur3_one_32(dt.month, hash);
|
||||
hash = hash_murmur3_one_32(dt.day, hash);
|
||||
hash = hash_murmur3_one_32(dt.hour, hash);
|
||||
hash = hash_murmur3_one_32(dt.minute, hash);
|
||||
hash = hash_murmur3_one_32(dt.second, hash);
|
||||
hash = hash_murmur3_one_32(Math::rand(), hash);
|
||||
|
||||
static constexpr uint32_t characters = 5;
|
||||
|
|
10
core/os/os.h
10
core/os/os.h
|
@ -202,18 +202,15 @@ public:
|
|||
MONTH_DECEMBER,
|
||||
};
|
||||
|
||||
struct Date {
|
||||
struct DateTime {
|
||||
int64_t year;
|
||||
Month month;
|
||||
uint8_t day;
|
||||
Weekday weekday;
|
||||
bool dst;
|
||||
};
|
||||
|
||||
struct Time {
|
||||
uint8_t hour;
|
||||
uint8_t minute;
|
||||
uint8_t second;
|
||||
bool dst;
|
||||
};
|
||||
|
||||
struct TimeZoneInfo {
|
||||
|
@ -221,8 +218,7 @@ public:
|
|||
String name;
|
||||
};
|
||||
|
||||
virtual Date get_date(bool p_utc = false) const = 0;
|
||||
virtual Time get_time(bool p_utc = false) const = 0;
|
||||
virtual DateTime get_datetime(bool utc = false) const = 0;
|
||||
virtual TimeZoneInfo get_time_zone_info() const = 0;
|
||||
virtual double get_unix_time() const;
|
||||
|
||||
|
|
|
@ -324,63 +324,60 @@ String Time::get_offset_string_from_offset_minutes(int64_t p_offset_minutes) con
|
|||
}
|
||||
|
||||
Dictionary Time::get_datetime_dict_from_system(bool p_utc) const {
|
||||
OS::Date date = OS::get_singleton()->get_date(p_utc);
|
||||
OS::Time time = OS::get_singleton()->get_time(p_utc);
|
||||
OS::DateTime dt = OS::get_singleton()->get_datetime(p_utc);
|
||||
Dictionary datetime;
|
||||
datetime[YEAR_KEY] = date.year;
|
||||
datetime[MONTH_KEY] = (uint8_t)date.month;
|
||||
datetime[DAY_KEY] = date.day;
|
||||
datetime[WEEKDAY_KEY] = (uint8_t)date.weekday;
|
||||
datetime[DST_KEY] = date.dst;
|
||||
datetime[HOUR_KEY] = time.hour;
|
||||
datetime[MINUTE_KEY] = time.minute;
|
||||
datetime[SECOND_KEY] = time.second;
|
||||
datetime[YEAR_KEY] = dt.year;
|
||||
datetime[MONTH_KEY] = (uint8_t)dt.month;
|
||||
datetime[DAY_KEY] = dt.day;
|
||||
datetime[WEEKDAY_KEY] = (uint8_t)dt.weekday;
|
||||
datetime[HOUR_KEY] = dt.hour;
|
||||
datetime[MINUTE_KEY] = dt.minute;
|
||||
datetime[SECOND_KEY] = dt.second;
|
||||
datetime[DST_KEY] = dt.dst;
|
||||
return datetime;
|
||||
}
|
||||
|
||||
Dictionary Time::get_date_dict_from_system(bool p_utc) const {
|
||||
OS::Date date = OS::get_singleton()->get_date(p_utc);
|
||||
OS::DateTime dt = OS::get_singleton()->get_datetime(p_utc);
|
||||
Dictionary date_dictionary;
|
||||
date_dictionary[YEAR_KEY] = date.year;
|
||||
date_dictionary[MONTH_KEY] = (uint8_t)date.month;
|
||||
date_dictionary[DAY_KEY] = date.day;
|
||||
date_dictionary[WEEKDAY_KEY] = (uint8_t)date.weekday;
|
||||
date_dictionary[DST_KEY] = date.dst;
|
||||
date_dictionary[YEAR_KEY] = dt.year;
|
||||
date_dictionary[MONTH_KEY] = (uint8_t)dt.month;
|
||||
date_dictionary[DAY_KEY] = dt.day;
|
||||
date_dictionary[WEEKDAY_KEY] = (uint8_t)dt.weekday;
|
||||
return date_dictionary;
|
||||
}
|
||||
|
||||
Dictionary Time::get_time_dict_from_system(bool p_utc) const {
|
||||
OS::Time time = OS::get_singleton()->get_time(p_utc);
|
||||
OS::DateTime dt = OS::get_singleton()->get_datetime(p_utc);
|
||||
Dictionary time_dictionary;
|
||||
time_dictionary[HOUR_KEY] = time.hour;
|
||||
time_dictionary[MINUTE_KEY] = time.minute;
|
||||
time_dictionary[SECOND_KEY] = time.second;
|
||||
time_dictionary[HOUR_KEY] = dt.hour;
|
||||
time_dictionary[MINUTE_KEY] = dt.minute;
|
||||
time_dictionary[SECOND_KEY] = dt.second;
|
||||
return time_dictionary;
|
||||
}
|
||||
|
||||
String Time::get_datetime_string_from_system(bool p_utc, bool p_use_space) const {
|
||||
OS::Date date = OS::get_singleton()->get_date(p_utc);
|
||||
OS::Time time = OS::get_singleton()->get_time(p_utc);
|
||||
OS::DateTime dt = OS::get_singleton()->get_datetime(p_utc);
|
||||
// vformat only supports up to 6 arguments, so we need to split this up into 2 parts.
|
||||
String timestamp = vformat("%04d-%02d-%02d", date.year, (uint8_t)date.month, date.day);
|
||||
String timestamp = vformat("%04d-%02d-%02d", dt.year, (uint8_t)dt.month, dt.day);
|
||||
if (p_use_space) {
|
||||
timestamp = vformat("%s %02d:%02d:%02d", timestamp, time.hour, time.minute, time.second);
|
||||
timestamp = vformat("%s %02d:%02d:%02d", timestamp, dt.hour, dt.minute, dt.second);
|
||||
} else {
|
||||
timestamp = vformat("%sT%02d:%02d:%02d", timestamp, time.hour, time.minute, time.second);
|
||||
timestamp = vformat("%sT%02d:%02d:%02d", timestamp, dt.hour, dt.minute, dt.second);
|
||||
}
|
||||
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
String Time::get_date_string_from_system(bool p_utc) const {
|
||||
OS::Date date = OS::get_singleton()->get_date(p_utc);
|
||||
OS::DateTime dt = OS::get_singleton()->get_datetime(p_utc);
|
||||
// Android is picky about the types passed to make Variant, so we need a cast.
|
||||
return vformat("%04d-%02d-%02d", date.year, (uint8_t)date.month, date.day);
|
||||
return vformat("%04d-%02d-%02d", dt.year, (uint8_t)dt.month, dt.day);
|
||||
}
|
||||
|
||||
String Time::get_time_string_from_system(bool p_utc) const {
|
||||
OS::Time time = OS::get_singleton()->get_time(p_utc);
|
||||
return vformat("%02d:%02d:%02d", time.hour, time.minute, time.second);
|
||||
OS::DateTime dt = OS::get_singleton()->get_datetime(p_utc);
|
||||
return vformat("%02d:%02d:%02d", dt.hour, dt.minute, dt.second);
|
||||
}
|
||||
|
||||
Dictionary Time::get_time_zone_from_system() const {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<return type="Dictionary" />
|
||||
<param index="0" name="utc" type="bool" default="false" />
|
||||
<description>
|
||||
Returns the current date as a dictionary of keys: [code]year[/code], [code]month[/code], [code]day[/code], [code]weekday[/code], and [code]dst[/code] (Daylight Savings Time).
|
||||
Returns the current date as a dictionary of keys: [code]year[/code], [code]month[/code], [code]day[/code], and [code]weekday[/code].
|
||||
The returned values are in the system's local time when [param utc] is [code]false[/code], otherwise they are in UTC.
|
||||
</description>
|
||||
</method>
|
||||
|
@ -57,7 +57,7 @@
|
|||
<return type="Dictionary" />
|
||||
<param index="0" name="utc" type="bool" default="false" />
|
||||
<description>
|
||||
Returns the current date as a dictionary of keys: [code]year[/code], [code]month[/code], [code]day[/code], [code]weekday[/code], [code]hour[/code], [code]minute[/code], and [code]second[/code].
|
||||
Returns the current date as a dictionary of keys: [code]year[/code], [code]month[/code], [code]day[/code], [code]weekday[/code], [code]hour[/code], [code]minute[/code], [code]second[/code], and [code]dst[/code] (Daylight Savings Time).
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_datetime_dict_from_unix_time" qualifiers="const">
|
||||
|
|
|
@ -200,7 +200,7 @@ double OS_Unix::get_unix_time() const {
|
|||
return (double)tv_now.tv_sec + double(tv_now.tv_usec) / 1000000;
|
||||
}
|
||||
|
||||
OS::Date OS_Unix::get_date(bool p_utc) const {
|
||||
OS::DateTime OS_Unix::get_datetime(bool p_utc) const {
|
||||
time_t t = time(nullptr);
|
||||
struct tm lt;
|
||||
if (p_utc) {
|
||||
|
@ -208,7 +208,7 @@ OS::Date OS_Unix::get_date(bool p_utc) const {
|
|||
} else {
|
||||
localtime_r(&t, <);
|
||||
}
|
||||
Date ret;
|
||||
DateTime ret;
|
||||
ret.year = 1900 + lt.tm_year;
|
||||
// Index starting at 1 to match OS_Unix::get_date
|
||||
// and Windows SYSTEMTIME and tm_mon follows the typical structure
|
||||
|
@ -216,24 +216,11 @@ OS::Date OS_Unix::get_date(bool p_utc) const {
|
|||
ret.month = (Month)(lt.tm_mon + 1);
|
||||
ret.day = lt.tm_mday;
|
||||
ret.weekday = (Weekday)lt.tm_wday;
|
||||
ret.dst = lt.tm_isdst;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
OS::Time OS_Unix::get_time(bool p_utc) const {
|
||||
time_t t = time(nullptr);
|
||||
struct tm lt;
|
||||
if (p_utc) {
|
||||
gmtime_r(&t, <);
|
||||
} else {
|
||||
localtime_r(&t, <);
|
||||
}
|
||||
Time ret;
|
||||
ret.hour = lt.tm_hour;
|
||||
ret.minute = lt.tm_min;
|
||||
ret.second = lt.tm_sec;
|
||||
get_time_zone_info();
|
||||
ret.dst = lt.tm_isdst;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,8 +63,7 @@ public:
|
|||
|
||||
virtual String get_name() const override;
|
||||
|
||||
virtual Date get_date(bool p_utc) const override;
|
||||
virtual Time get_time(bool p_utc) const override;
|
||||
virtual DateTime get_datetime(bool p_utc) const override;
|
||||
virtual TimeZoneInfo get_time_zone_info() const override;
|
||||
|
||||
virtual double get_unix_time() const override;
|
||||
|
|
|
@ -569,16 +569,15 @@ bool EditorExportPlatformAndroid::_should_compress_asset(const String &p_path, c
|
|||
}
|
||||
|
||||
zip_fileinfo EditorExportPlatformAndroid::get_zip_fileinfo() {
|
||||
OS::Time time = OS::get_singleton()->get_time();
|
||||
OS::Date date = OS::get_singleton()->get_date();
|
||||
OS::DateTime dt = OS::get_singleton()->get_datetime();
|
||||
|
||||
zip_fileinfo zipfi;
|
||||
zipfi.tmz_date.tm_hour = time.hour;
|
||||
zipfi.tmz_date.tm_mday = date.day;
|
||||
zipfi.tmz_date.tm_min = time.minute;
|
||||
zipfi.tmz_date.tm_mon = date.month - 1; // tm_mon is zero indexed
|
||||
zipfi.tmz_date.tm_sec = time.second;
|
||||
zipfi.tmz_date.tm_year = date.year;
|
||||
zipfi.tmz_date.tm_year = dt.year;
|
||||
zipfi.tmz_date.tm_mon = dt.month - 1; // tm_mon is zero indexed
|
||||
zipfi.tmz_date.tm_mday = dt.day;
|
||||
zipfi.tmz_date.tm_hour = dt.hour;
|
||||
zipfi.tmz_date.tm_min = dt.minute;
|
||||
zipfi.tmz_date.tm_sec = dt.second;
|
||||
zipfi.dosDate = 0;
|
||||
zipfi.external_fa = 0;
|
||||
zipfi.internal_fa = 0;
|
||||
|
|
|
@ -686,10 +686,9 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
|
|||
String renamed_path = path.get_base_dir() + "/" + file_name;
|
||||
|
||||
// Generates the .trashinfo file
|
||||
OS::Date date = OS::get_singleton()->get_date(false);
|
||||
OS::Time time = OS::get_singleton()->get_time(false);
|
||||
String timestamp = vformat("%04d-%02d-%02dT%02d:%02d:", date.year, (int)date.month, date.day, time.hour, time.minute);
|
||||
timestamp = vformat("%s%02d", timestamp, time.second); // vformat only supports up to 6 arguments.
|
||||
OS::DateTime dt = OS::get_singleton()->get_datetime(false);
|
||||
String timestamp = vformat("%04d-%02d-%02dT%02d:%02d:", dt.year, (int)dt.month, dt.day, dt.hour, dt.minute);
|
||||
timestamp = vformat("%s%02d", timestamp, dt.second); // vformat only supports up to 6 arguments.
|
||||
String trash_info = "[Trash Info]\nPath=" + path.uri_encode() + "\nDeletionDate=" + timestamp + "\n";
|
||||
{
|
||||
Error err;
|
||||
|
|
|
@ -1641,16 +1641,15 @@ void EditorExportPlatformMacOS::_zip_folder_recursive(zipFile &p_zip, const Stri
|
|||
continue;
|
||||
}
|
||||
if (da->is_link(f)) {
|
||||
OS::Time time = OS::get_singleton()->get_time();
|
||||
OS::Date date = OS::get_singleton()->get_date();
|
||||
OS::DateTime dt = OS::get_singleton()->get_datetime();
|
||||
|
||||
zip_fileinfo zipfi;
|
||||
zipfi.tmz_date.tm_hour = time.hour;
|
||||
zipfi.tmz_date.tm_mday = date.day;
|
||||
zipfi.tmz_date.tm_min = time.minute;
|
||||
zipfi.tmz_date.tm_mon = date.month - 1; // Note: "tm" month range - 0..11, Godot month range - 1..12, https://www.cplusplus.com/reference/ctime/tm/
|
||||
zipfi.tmz_date.tm_sec = time.second;
|
||||
zipfi.tmz_date.tm_year = date.year;
|
||||
zipfi.tmz_date.tm_year = dt.year;
|
||||
zipfi.tmz_date.tm_mon = dt.month - 1; // Note: "tm" month range - 0..11, Godot month range - 1..12, https://www.cplusplus.com/reference/ctime/tm/
|
||||
zipfi.tmz_date.tm_mday = dt.day;
|
||||
zipfi.tmz_date.tm_hour = dt.hour;
|
||||
zipfi.tmz_date.tm_min = dt.minute;
|
||||
zipfi.tmz_date.tm_sec = dt.second;
|
||||
zipfi.dosDate = 0;
|
||||
// 0120000: symbolic link type
|
||||
// 0000755: permissions rwxr-xr-x
|
||||
|
@ -1686,16 +1685,15 @@ void EditorExportPlatformMacOS::_zip_folder_recursive(zipFile &p_zip, const Stri
|
|||
} else {
|
||||
bool is_executable = (p_folder.ends_with("MacOS") && (f == p_pkg_name)) || p_folder.ends_with("Helpers") || f.ends_with(".command");
|
||||
|
||||
OS::Time time = OS::get_singleton()->get_time();
|
||||
OS::Date date = OS::get_singleton()->get_date();
|
||||
OS::DateTime dt = OS::get_singleton()->get_datetime();
|
||||
|
||||
zip_fileinfo zipfi;
|
||||
zipfi.tmz_date.tm_hour = time.hour;
|
||||
zipfi.tmz_date.tm_mday = date.day;
|
||||
zipfi.tmz_date.tm_min = time.minute;
|
||||
zipfi.tmz_date.tm_mon = date.month - 1; // Note: "tm" month range - 0..11, Godot month range - 1..12, https://www.cplusplus.com/reference/ctime/tm/
|
||||
zipfi.tmz_date.tm_sec = time.second;
|
||||
zipfi.tmz_date.tm_year = date.year;
|
||||
zipfi.tmz_date.tm_year = dt.year;
|
||||
zipfi.tmz_date.tm_mon = dt.month - 1; // Note: "tm" month range - 0..11, Godot month range - 1..12, https://www.cplusplus.com/reference/ctime/tm/
|
||||
zipfi.tmz_date.tm_mday = dt.day;
|
||||
zipfi.tmz_date.tm_hour = dt.hour;
|
||||
zipfi.tmz_date.tm_min = dt.minute;
|
||||
zipfi.tmz_date.tm_sec = dt.second;
|
||||
zipfi.dosDate = 0;
|
||||
// 0100000: regular file type
|
||||
// 0000755: permissions rwxr-xr-x
|
||||
|
|
|
@ -444,7 +444,7 @@ String OS_UWP::get_name() const {
|
|||
return "UWP";
|
||||
}
|
||||
|
||||
OS::Date OS_UWP::get_date(bool p_utc) const {
|
||||
OS::DateTime OS_UWP::get_datetime(bool p_utc) const {
|
||||
SYSTEMTIME systemtime;
|
||||
if (p_utc) {
|
||||
GetSystemTime(&systemtime);
|
||||
|
@ -452,28 +452,23 @@ OS::Date OS_UWP::get_date(bool p_utc) const {
|
|||
GetLocalTime(&systemtime);
|
||||
}
|
||||
|
||||
Date date;
|
||||
date.day = systemtime.wDay;
|
||||
date.month = Month(systemtime.wMonth);
|
||||
date.weekday = Weekday(systemtime.wDayOfWeek);
|
||||
date.year = systemtime.wYear;
|
||||
date.dst = false;
|
||||
return date;
|
||||
}
|
||||
|
||||
OS::Time OS_UWP::get_time(bool p_utc) const {
|
||||
SYSTEMTIME systemtime;
|
||||
if (p_utc) {
|
||||
GetSystemTime(&systemtime);
|
||||
} else {
|
||||
GetLocalTime(&systemtime);
|
||||
//Get DST information from Windows, but only if p_utc is false.
|
||||
TIME_ZONE_INFORMATION info;
|
||||
bool daylight = false;
|
||||
if (!p_utc && GetTimeZoneInformation(&info) == TIME_ZONE_ID_DAYLIGHT) {
|
||||
daylight = true;
|
||||
}
|
||||
|
||||
Time time;
|
||||
time.hour = systemtime.wHour;
|
||||
time.min = systemtime.wMinute;
|
||||
time.sec = systemtime.wSecond;
|
||||
return time;
|
||||
DateTime dt;
|
||||
dt.year = systemtime.wYear;
|
||||
dt.month = Month(systemtime.wMonth);
|
||||
dt.day = systemtime.wDay;
|
||||
dt.weekday = Weekday(systemtime.wDayOfWeek);
|
||||
dt.hour = systemtime.wHour;
|
||||
dt.minute = systemtime.wMinute;
|
||||
dt.second = systemtime.wSecond;
|
||||
dt.dst = daylight;
|
||||
return dt;
|
||||
}
|
||||
|
||||
OS::TimeZoneInfo OS_UWP::get_time_zone_info() const {
|
||||
|
|
|
@ -184,8 +184,7 @@ public:
|
|||
|
||||
virtual String get_name() const;
|
||||
|
||||
virtual Date get_date(bool p_utc) const;
|
||||
virtual Time get_time(bool p_utc) const;
|
||||
virtual DateTime get_datetime(bool p_utc) const;
|
||||
virtual TimeZoneInfo get_time_zone_info() const;
|
||||
virtual uint64_t get_unix_time() const;
|
||||
|
||||
|
|
|
@ -290,7 +290,7 @@ String OS_Windows::get_name() const {
|
|||
return "Windows";
|
||||
}
|
||||
|
||||
OS::Date OS_Windows::get_date(bool p_utc) const {
|
||||
OS::DateTime OS_Windows::get_datetime(bool p_utc) const {
|
||||
SYSTEMTIME systemtime;
|
||||
if (p_utc) {
|
||||
GetSystemTime(&systemtime);
|
||||
|
@ -305,28 +305,16 @@ OS::Date OS_Windows::get_date(bool p_utc) const {
|
|||
daylight = true;
|
||||
}
|
||||
|
||||
Date date;
|
||||
date.day = systemtime.wDay;
|
||||
date.month = Month(systemtime.wMonth);
|
||||
date.weekday = Weekday(systemtime.wDayOfWeek);
|
||||
date.year = systemtime.wYear;
|
||||
date.dst = daylight;
|
||||
return date;
|
||||
}
|
||||
|
||||
OS::Time OS_Windows::get_time(bool p_utc) const {
|
||||
SYSTEMTIME systemtime;
|
||||
if (p_utc) {
|
||||
GetSystemTime(&systemtime);
|
||||
} else {
|
||||
GetLocalTime(&systemtime);
|
||||
}
|
||||
|
||||
Time time;
|
||||
time.hour = systemtime.wHour;
|
||||
time.minute = systemtime.wMinute;
|
||||
time.second = systemtime.wSecond;
|
||||
return time;
|
||||
DateTime dt;
|
||||
dt.year = systemtime.wYear;
|
||||
dt.month = Month(systemtime.wMonth);
|
||||
dt.day = systemtime.wDay;
|
||||
dt.weekday = Weekday(systemtime.wDayOfWeek);
|
||||
dt.hour = systemtime.wHour;
|
||||
dt.minute = systemtime.wMinute;
|
||||
dt.second = systemtime.wSecond;
|
||||
dt.dst = daylight;
|
||||
return dt;
|
||||
}
|
||||
|
||||
OS::TimeZoneInfo OS_Windows::get_time_zone_info() const {
|
||||
|
|
|
@ -146,8 +146,7 @@ public:
|
|||
|
||||
virtual void initialize_joypads() override {}
|
||||
|
||||
virtual Date get_date(bool p_utc) const override;
|
||||
virtual Time get_time(bool p_utc) const override;
|
||||
virtual DateTime get_datetime(bool p_utc) const override;
|
||||
virtual TimeZoneInfo get_time_zone_info() const override;
|
||||
virtual double get_unix_time() const override;
|
||||
|
||||
|
|
Loading…
Reference in a new issue