Solved LocalDateTime and UniversalDateTime questions

Hi,

I am still trying to wrap my head around LocalDateTime and UniversalDateTime.

LocalDateTime -> UniversalDateTime : time zone offset

I have this test code:

	// Format string for date parsing
	const Char* dateFormatString = "%Y%m%d";

	// Date string to parse
	String activationDateString("20191105"); // November 5th, 2019

	// Parse date from string
	maxon::LocalDateTime activationDateLocal = maxon::LocalDateTime::FromString(activationDateString, dateFormatString) iferr_ignore();

	// Zero out time values, as the parser gives me obscure times otherwise
	activationDateLocal._hour = activationDateLocal._minute = activationDateLocal._second = 0;

	// Convert activation date to UTC
	maxon::UniversalDateTime activationDate = activationDateLocal.ConvertToUniversalDateTime();

	// DEBUG: Print times
	DiagnosticOutput("DEBUG: @", maxon::String("Activation date LOCAL: ") + activationDateLocal.ToString(nullptr));
	DiagnosticOutput("DEBUG: @", maxon::String("Activation date UTC (converted from local): ") + activationDate.ToString(nullptr));

This is the readout:

DEBUG: Activation date LOCAL: 2019-11-05 00:00:00
DEBUG: Activation date UTC (converted from local): 2019-11-04 22:00:00

So far so good. I'm in Germany, so my time zone is +2 hours. But WAIT a second... we're on winter time currently, so shouldn't it rather be 1 hour difference? Let's see what the time zone difference is:

	DiagnosticOutput("DEBUG: @", maxon::String("Activation date LOCAL: ") + activationDateLocal.ToString(nullptr));
	DiagnosticOutput("DEBUG: @", maxon::String("Local time zone offset: ") + maxon::String::FloatToString(activationDateLocal.GetTimezoneOffset().GetHours()));
	DiagnosticOutput("DEBUG: @", maxon::String("Activation date UTC (converted from local): ") + activationDate.ToString(nullptr));

And here comes a surprise:

DEBUG: Activation date LOCAL: 2019-11-05 00:00:00
DEBUG: Local time zone offset: 1
DEBUG: Activation date UTC (converted from local): 2019-11-04 23:00:00

My time zone difference is in deed 1 hour, as I expected. But suddenly, the converted UTC is different from before (was: 22:00; is: 23:00)! Keep in mind, the only thing I changed in the code is that I added the second DiagnosticOutput() line.

Does LocalDateTime::GetTimezoneOffset() change values in the LocalDateTime object?? Is that why it's not const? Why do the SDK docs not mention this?

The only thing I want is:

  1. Get the current date
  2. Parse another date from a string
  3. Comparing both dates to get their difference in days (I know how to do that already). Exact times are to be neglected, but of course time zones still play a role to get the correct date.

FromString() default result values

Also, on a general note: If I use LocalDateTime::FromString() to parse a date from string, why are the time values not at all initialized?

	// Format string for date parsing
	const Char* dateFormatString = "%Y%m%d";

	// Date string to parse
	String activationDateString("20191105"); // November 5th, 2019

	// Parse date from string
	maxon::LocalDateTime activationDateLocal = maxon::LocalDateTime::FromString(activationDateString, dateFormatString) iferr_ignore();

	// DEBUG: Print times
	DiagnosticOutput("DEBUG: @", maxon::String("Activation date LOCAL: ") + activationDateLocal.ToString(nullptr));

The readout is:

DEBUG: Activation date LOCAL: 2019-11-05 128:254:144

Why are the time values not zero'ed, or set to the current time, or anything that would make sense?

Greetings,
Frank

www.frankwilleke.de
Only asking personal code questions here.

Hi,

I cannot say much about your second problem (the weird initialisation of hours, minutes, and seconds), but I have a suspicion about your first problem. UTC does not account for daylight saving time (DST) in its ISO specification if I remember correctly. The reason being, that DST is very much not a worldwide practice (in the sense that really everyone is doing it). So if some local DST is being applied, it usually just modifies the time offset.

Depending on how you implement a UTC model, this could mean, that local_time -> global_time (meaning UTC +0) -> local_time is not a lossless conversion as UTC +0 should not include any DST by default.

While I do understand the whole spirit of the inquiry, I would also like to point out, that it is probably unnecessary to account for DST in license management. Assuming that this is still the background.

Cheers
zipit

MAXON SDK Specialist
developers.maxon.net

That is, in deed, the background, and I would love to ignore the DST ;-)

But at least time zones I have to take care of, otherwise licenses of customers in e.g. China will expire a day early.

www.frankwilleke.de
Only asking personal code questions here.

Or, to put it differently:

I would like to have all times in UTC, without and time zone offsets being considered.

The current date I want to get in UTC (I already am). And I want to parse a date from a string, and that date should also be considered UTC without any time zone difference.

If only UniversalDateTime had a FromString() function...

www.frankwilleke.de
Only asking personal code questions here.

Hi,

well, aside from the "at least I am done with it"-approach of just adding 24 hours to each license, there is the static method UniversalDateTime::FromValues() which should be close enough to a FromString().

There is also UniversalDateTime::GetNow(). But the description on that is a bit ambiguous. It says "Return[s] the current date-time object of the current time zone.", while the UniversalDateTime class description says "Class that represents the Universal date-time (UTC+0000)". Unless I am overlooking something here, I would say both cannot be true at the same time, and would expect UniversalDateTime::GetNow() to actually return the current time in UTC +0 (as a UniversalDateTime).

The problem with DST is, that it is not anything truly predictable. While your problem could be rooted in a bug, there is a rich history of big organisations struggling with DST (Microsoft, Apple, etc.) and using DST makes you dependent on them maintaining their OS/services properly.

On a more light-hearted note: When dealing with standardisation of human conventions I always have to think of this XKCD ;)

alt text

Cheers
zipit

MAXON SDK Specialist
developers.maxon.net