Date Format Exception again

And those should not silently fail, you should fix them before storing.

I would expect an exception like “Invalid Date Range” and a companion error number <> 0 documented.

But this works:

Var d as DateTime = DateTime.FromString("2024-03-10 02:00", Nil, New TimeZone("America/New_York"))
// Works and end as 2024-03-10 00:00:00
break

Wrong behavior without complete set of parameters?

Doesn’t work here:


Duh for me, sure. I was on Windows, I forgot it is a Mac only bug.

1 Like

One question, why does it end as 2024-03-10 00:00:00 if you are using 02:00?

Weird, the behavior was:

Var d as DateTime

Const sd = "2024-03-10 "
Var s, st() As String
st = Array("00:00", "00:30", "01:00", "01:30", "02:00", "02:30", "03:00")

For each t As String in st
  
  s = sd + t
  d = DateTime.FromString(s, Nil, New TimeZone("America/New_York"))
  system.DebugLog s+" -> "+d.SQLDateTime
  
Next

break

Oh, on Windows non existing Date/Times converts to Date and 00:00 Time instead of throwing an exception. Thanks.

I wonder what will happen on TimeZones where 00:00 does not exist.

Nope. It throws an exception.

The example is showing the offset conversion due to DST for existing places in time. But the results seems weird and incorrect. If the date/time is like day 32 in a month ending at 31 it raises an exception for example.

I was talking only for non existing Dare Times due to clock forward DST. Sorry for not be specific before.

Makes sense to exception for a dare for 32 of month X.

I still wonder what happens with a Time zone that clocks forward at 00:00 making it not valid like the New York 02:00 test

The Xojo time zone does not change, still America/NY -14400 all the time, DST or not.

DST ends at 02:00, so in real life, your “smart clock” should show 01:58, 01:59, 01:00, 01:01…

Seems like the DateTime.FromString() silently nulled the conflicting period 02:00 to 02:59 at the end of DST, and translates as is before 02:00:00 after 02:59:59.

A better way to handle this is storing current real time as GMT+00:00, and just taking care of DST for presentation.

The example (for March) is “spring forward”, so 01:58, 01:59, 03:00, 03:01…

On Mac time of 02:00 creates an exception.
On Windows time goes down to 0:00 for any minute between 02:00 and 02:59 (for what I saw in your example).

There are other countries with “spring forward” at 00:00 to 01:00, so 00:00-00:59 doesn’t exists. I wonder what will happen on Windows if such a TZ is set for let’s say 00:30 and Windows tries to go down to 00:00 (the same as it happens with your New York test) if 00:00 does not exist for that country/TZ. That’s all.

1 Like

A not “writable” date/time representation should be as is, “not writable”. So in a spring forward that creates a non-representable period of time in such time zone, trying so should raise an exception, and at the same time provide a “nearest conversion” as possible, so people opting to ignore the exception could end with a kind of valid value with a small error they opted having it. The behavior should be consistent amongst all platforms, and documented, including examples.
The current behavior is not consistent in all platforms, and results are random and not well documented.

ho boy, you guys wrote a lot here and from > 1979-05-27 I see that the chat jumped to totally different dates and even non existing ones , why in the world someone would write 32 March Rick ?

The idea was to be able to keep the dates as they are and maybe to have back the format of Simple Date and DateTime as the new one, as honestly most of the times in our case on the birth date you need the date not the time, and that time wastes space on the db side just because it Is added there. Now with the modern pcs is less likely to care someone for few bits but this could lead to some mess in case we need tot alter data and add hours on dates

As for my case, it seems that both Belgium and Romania had DST at that date so what do I do ? I just setup the timezone for my area where do I process the data and it should be solved @AlbertoD ? or do I still need to add the time as well, and now have the headache to map and search for the dates when DST was applied or not and start messing with dates ?

Thanks

If you can work with Date and not DateTime, please try:

var bDate as new date
bDate.SQLDate = birthDate

if you need DateTime, then try:

Var bDate As DateTime
bDate = DateTime.FromString(birthDate + " 03:30")

I don’t know what you are doing with bDate, that’s why my recommendation is limited and could be wrong for your case.

Not only write as also calculate it. As someone that processed lots of contents sent by 3rd parties, many as CSV files, I’ve got things as “”, NULL, 0000-00-00, 2017-00-01, 2018-13-13, 2019-02-31, etc

Why? Zod knows.

As Sascha S already mentioned: check the string recovered from XML, if there are any hidden chars.

Documentation says everything should work as expected - and so it does on my Mac Studio (macOS Sonoma 14.3.1, Xojo 2023R4)

DateTime.FormString()

Var SQLDate As String = "2019-08-01"
Var myDate2 As DateTime = DateTime.FromString(SQLDate)

Well encoding says UTF8, but I guess something is fishy there as even the content on some is messed up so that might be the case on my side , I will have to check .

Thanks

No, that is not the problem.

DateTime requires the Time component even if you are only providing the Date. On your example “2019-08-01” converts to a DateTime that really is “2019-08-01 00:00” and some TimeZone. As DateTime is DST aware if your TimeZone/Country “spring forward” at 00:00:00 of that day then that DateTime does not exist and you get an Exception.

As the USA “spring forward” at 02:00 hrs there are no Dates at 00:00 hrs that do not exist in the USA but in other countries there are dates that do not exist at 00:00.


That means that Romania “spring forward” on “1979-05-27 00:00” to “1979-05-27 01:00” making “1979-05-27 00:00” not existing and causing OP’s exception.

It should not cause a Exception if your TimeZone is, for example, USA Central time as there is no “spring forward” in the USA at 00:00 hrs on May 27, 1979. The same as most countries for that date.

You can test this code in your computer, preferable using Mac but I guess Windows will also show an exception:

//Bucharest is in Romania
Var d as DateTime = DateTime.FromString("1979-05-27", Nil, New TimeZone("Europe/Bucharest"))

I hope it is clear now and this helps find a way to avoid this Exception.

Sorry, its not mentioned in the documentation that DateTime is aware of DST and in my opinion throwing an exception is the wrong way to handle this situation, as no-one can know each day and time worldwide when a DST has or can occur.
So this looks like a bug for me - a better way to handle this is to use a correct value for the DST - so “1979-05-27” will be translated into “1979-05-27 01:00:00” if your timezone is set to Romania…

1 Like

Issues reported:
https://tracker.xojo.com/xojoinc/xojo/-/issues/71555
https://tracker.xojo.com/xojoinc/xojo/-/issues/72471
even one from Aurelian (automatically closed)
https://tracker.xojo.com/xojoinc/xojo/-/issues/73456


Is a good idea that Xojo should set the DateTime to …01:00 if 00:00 is invalid due to DST.
Can you add that comment to any of the open Issues?

Function to convert string to nearest valid value, also convert time from one zone to another:

Public Function DateTimeZoned(dateTimeStr As String, toZone As TimeZone = Nil, fromZone As TimeZone = Nil) As DateTime

  If toZone = Nil Then toZone = TimeZone.Current
  If fromZone = Nil Then fromZone = TimeZone.Current
  
  // Convert date/time from origin zone to a DateTime UTC
  Var d As DateTime = DateTime.FromString(dateTimeStr , Nil, _
  New TimeZone(fromZone.SecondsFromGMT))
  
  // Convert the GMT date/time in secs to the target TZ
  Return New DateTime(d.SecondsFrom1970, toZone)
  
End Function

// example:

Var zRO As New TimeZone("Europe/Bucharest")
Var d1, d2, d3 As DateTime
d1 = DateTimeZoned("1979-05-27 00:00") // Local zone
d2 = DateTimeZoned("1979-05-27 00:00", zRO) // Local to Bucharest
d3 = DateTimeZoned("1979-05-27 00:00", zRO, zRO) // Bucharest to Bucharest = The same as d1 if you're there


MessageBox d1.SQLDateTime + EndofLine + d1.Timezone.Abbreviation + "->" + d1.Timezone.Abbreviation + _
" / " + d1.SecondsFrom1970.ToString("#0.0000####") + EndOfLine + EndOfLine  + _
d2.SQLDateTime + EndofLine + d1.Timezone.Abbreviation + "->" + zRO.Abbreviation + _
" / " + d2.SecondsFrom1970.ToString("#0.0000####") + EndOfLine + EndOfLine + _
d3.SQLDateTime + EndofLine + zRO.Abbreviation + "->" + zRO.Abbreviation + _
" / " + d3.SecondsFrom1970.ToString("#0.0000####") +  EndOfLine

Quit

image

2 Likes