Browse Source

Merge pull request #58485 from aaronfranke/time-offset

Rémi Verschelde 3 years ago
parent
commit
26fd6fe2b2
4 changed files with 31 additions and 4 deletions
  1. 18 2
      core/os/time.cpp
  2. 3 2
      core/os/time.h
  3. 7 0
      doc/classes/Time.xml
  4. 3 0
      tests/core/test_time.h

+ 18 - 2
core/os/time.cpp

@@ -270,7 +270,7 @@ Dictionary Time::get_datetime_dict_from_string(String p_datetime, bool p_weekday
 	return dict;
 	return dict;
 }
 }
 
 
-String Time::get_datetime_string_from_dict(Dictionary p_datetime, bool p_use_space) const {
+String Time::get_datetime_string_from_dict(const Dictionary p_datetime, bool p_use_space) const {
 	ERR_FAIL_COND_V_MSG(p_datetime.is_empty(), "", "Invalid datetime Dictionary: Dictionary is empty.");
 	ERR_FAIL_COND_V_MSG(p_datetime.is_empty(), "", "Invalid datetime Dictionary: Dictionary is empty.");
 	EXTRACT_FROM_DICTIONARY
 	EXTRACT_FROM_DICTIONARY
 	// vformat only supports up to 6 arguments, so we need to split this up into 2 parts.
 	// vformat only supports up to 6 arguments, so we need to split this up into 2 parts.
@@ -283,7 +283,7 @@ String Time::get_datetime_string_from_dict(Dictionary p_datetime, bool p_use_spa
 	return timestamp;
 	return timestamp;
 }
 }
 
 
-int64_t Time::get_unix_time_from_datetime_dict(Dictionary p_datetime) const {
+int64_t Time::get_unix_time_from_datetime_dict(const Dictionary p_datetime) const {
 	ERR_FAIL_COND_V_MSG(p_datetime.is_empty(), 0, "Invalid datetime Dictionary: Dictionary is empty");
 	ERR_FAIL_COND_V_MSG(p_datetime.is_empty(), 0, "Invalid datetime Dictionary: Dictionary is empty");
 	EXTRACT_FROM_DICTIONARY
 	EXTRACT_FROM_DICTIONARY
 	VALIDATE_YMDHMS
 	VALIDATE_YMDHMS
@@ -298,6 +298,21 @@ int64_t Time::get_unix_time_from_datetime_string(String p_datetime) const {
 	return day_number * SECONDS_PER_DAY + hour * 3600 + minute * 60 + second;
 	return day_number * SECONDS_PER_DAY + hour * 3600 + minute * 60 + second;
 }
 }
 
 
+String Time::get_offset_string_from_offset_minutes(int64_t p_offset_minutes) const {
+	String sign;
+	if (p_offset_minutes < 0) {
+		sign = "-";
+		p_offset_minutes = -p_offset_minutes;
+	} else {
+		sign = "+";
+	}
+	// These two lines can be optimized to one instruction on x86 and others.
+	// Note that % is acceptable here only because we ensure it's positive.
+	int64_t offset_hours = p_offset_minutes / 60;
+	int64_t offset_minutes = p_offset_minutes % 60;
+	return vformat("%s%02d:%02d", sign, offset_hours, offset_minutes);
+}
+
 Dictionary Time::get_datetime_dict_from_system(bool p_utc) const {
 Dictionary Time::get_datetime_dict_from_system(bool p_utc) const {
 	OS::Date date = OS::get_singleton()->get_date(p_utc);
 	OS::Date date = OS::get_singleton()->get_date(p_utc);
 	OS::Time time = OS::get_singleton()->get_time(p_utc);
 	OS::Time time = OS::get_singleton()->get_time(p_utc);
@@ -389,6 +404,7 @@ void Time::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_datetime_string_from_dict", "datetime", "use_space"), &Time::get_datetime_string_from_dict);
 	ClassDB::bind_method(D_METHOD("get_datetime_string_from_dict", "datetime", "use_space"), &Time::get_datetime_string_from_dict);
 	ClassDB::bind_method(D_METHOD("get_unix_time_from_datetime_dict", "datetime"), &Time::get_unix_time_from_datetime_dict);
 	ClassDB::bind_method(D_METHOD("get_unix_time_from_datetime_dict", "datetime"), &Time::get_unix_time_from_datetime_dict);
 	ClassDB::bind_method(D_METHOD("get_unix_time_from_datetime_string", "datetime"), &Time::get_unix_time_from_datetime_string);
 	ClassDB::bind_method(D_METHOD("get_unix_time_from_datetime_string", "datetime"), &Time::get_unix_time_from_datetime_string);
+	ClassDB::bind_method(D_METHOD("get_offset_string_from_offset_minutes", "offset_minutes"), &Time::get_offset_string_from_offset_minutes);
 
 
 	ClassDB::bind_method(D_METHOD("get_datetime_dict_from_system", "utc"), &Time::get_datetime_dict_from_system, DEFVAL(false));
 	ClassDB::bind_method(D_METHOD("get_datetime_dict_from_system", "utc"), &Time::get_datetime_dict_from_system, DEFVAL(false));
 	ClassDB::bind_method(D_METHOD("get_date_dict_from_system", "utc"), &Time::get_date_dict_from_system, DEFVAL(false));
 	ClassDB::bind_method(D_METHOD("get_date_dict_from_system", "utc"), &Time::get_date_dict_from_system, DEFVAL(false));

+ 3 - 2
core/os/time.h

@@ -86,9 +86,10 @@ public:
 	String get_date_string_from_unix_time(int64_t p_unix_time_val) const;
 	String get_date_string_from_unix_time(int64_t p_unix_time_val) const;
 	String get_time_string_from_unix_time(int64_t p_unix_time_val) const;
 	String get_time_string_from_unix_time(int64_t p_unix_time_val) const;
 	Dictionary get_datetime_dict_from_string(String p_datetime, bool p_weekday = true) const;
 	Dictionary get_datetime_dict_from_string(String p_datetime, bool p_weekday = true) const;
-	String get_datetime_string_from_dict(Dictionary p_datetime, bool p_use_space = false) const;
-	int64_t get_unix_time_from_datetime_dict(Dictionary p_datetime) const;
+	String get_datetime_string_from_dict(const Dictionary p_datetime, bool p_use_space = false) const;
+	int64_t get_unix_time_from_datetime_dict(const Dictionary p_datetime) const;
 	int64_t get_unix_time_from_datetime_string(String p_datetime) const;
 	int64_t get_unix_time_from_datetime_string(String p_datetime) const;
+	String get_offset_string_from_offset_minutes(int64_t p_offset_minutes) const;
 
 
 	// Methods that get information from OS.
 	// Methods that get information from OS.
 	Dictionary get_datetime_dict_from_system(bool p_utc = false) const;
 	Dictionary get_datetime_dict_from_system(bool p_utc = false) const;

+ 7 - 0
doc/classes/Time.xml

@@ -97,6 +97,13 @@
 				If [code]use_space[/code] is true, use a space instead of the letter T in the middle.
 				If [code]use_space[/code] is true, use a space instead of the letter T in the middle.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="get_offset_string_from_offset_minutes" qualifiers="const">
+			<return type="String" />
+			<argument index="0" name="offset_minutes" type="int" />
+			<description>
+				Converts the given timezone offset in minutes to a timezone offset string. For example, -480 returns "-08:00", 345 returns "+05:45", and 0 returns "+00:00".
+			</description>
+		</method>
 		<method name="get_ticks_msec" qualifiers="const">
 		<method name="get_ticks_msec" qualifiers="const">
 			<return type="int" />
 			<return type="int" />
 			<description>
 			<description>

+ 3 - 0
tests/core/test_time.h

@@ -79,6 +79,9 @@ TEST_CASE("[Time] Unix time conversion to/from datetime string") {
 	CHECK_MESSAGE(time->get_date_string_from_unix_time(1391904000) == "2014-02-09", "Time get_date_string_from_unix_time: The date for GODOT IS OPEN SOURCE without time is as expected.");
 	CHECK_MESSAGE(time->get_date_string_from_unix_time(1391904000) == "2014-02-09", "Time get_date_string_from_unix_time: The date for GODOT IS OPEN SOURCE without time is as expected.");
 	CHECK_MESSAGE(time->get_time_string_from_unix_time(79830) == "22:10:30", "Time get_time_string_from_unix_time: The time for GODOT IS OPEN SOURCE without date is as expected.");
 	CHECK_MESSAGE(time->get_time_string_from_unix_time(79830) == "22:10:30", "Time get_time_string_from_unix_time: The time for GODOT IS OPEN SOURCE without date is as expected.");
 	CHECK_MESSAGE(time->get_datetime_string_from_unix_time(31494784780800) == "1000000-01-01T00:00:00", "Time get_datetime_string_from_unix_time: The timestamp for the year a million is as expected.");
 	CHECK_MESSAGE(time->get_datetime_string_from_unix_time(31494784780800) == "1000000-01-01T00:00:00", "Time get_datetime_string_from_unix_time: The timestamp for the year a million is as expected.");
+	CHECK_MESSAGE(time->get_offset_string_from_offset_minutes(0) == "+00:00", "Time get_offset_string_from_offset_minutes: The offset string is as expected.");
+	CHECK_MESSAGE(time->get_offset_string_from_offset_minutes(-600) == "-10:00", "Time get_offset_string_from_offset_minutes: The offset string is as expected.");
+	CHECK_MESSAGE(time->get_offset_string_from_offset_minutes(345) == "+05:45", "Time get_offset_string_from_offset_minutes: The offset string is as expected.");
 }
 }
 
 
 TEST_CASE("[Time] Datetime dictionary conversion methods") {
 TEST_CASE("[Time] Datetime dictionary conversion methods") {