Page 1 of 2

Update FormatDate() and ParseDate() to the new date range

Posted: Mon Dec 25, 2023 12:47 pm
by Sicro
PureBasic 6.10 beta 1 - Xmas Release - is out ! wrote:Updated: Date library for full 64bit support (new range is year 1601 to 30827)

Code: Select all

Define.q date = Date(12345, 1, 2, 3, 4, 5)

; Outputs:  02.01.1234 03:04:05
; Expected: 02.01.2345 03:04:05
Debug FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss", date)

; Outputs:  02.01.1234y 03:04:05
; Expected: 02.01.12345 03:04:05
Debug FormatDate("%dd.%mm.%yyyyy %hh:%ii:%ss", date)

; Outputs:  -1
; Expected: -1
Debug ParseDate("%dd.%mm.%yyyy %hh:%ii:%ss", "02.01.12345 03:04:05")

; Outputs:  -1
; Expected: Positive number
Debug ParseDate("%dd.%mm.%yyyyy %hh:%ii:%ss", "02.01.12345 03:04:05")

Re: Update FormatDate() and ParseDate() to the new date range

Posted: Mon Dec 25, 2023 1:41 pm
by Little John
It would be OK for me if "%yy" corresponds to the last two digits of the respective year, and "%yyyy" corresponds to the full year number (as it is with PB < 6.10) - regardless whether the year has four or five digits.
Note that ""%yyy"" also is not a valid token in this context.

Re: Update FormatDate() and ParseDate() to the new date range

Posted: Mon Dec 25, 2023 2:00 pm
by Sicro
Yes, makes more sense.

Re: Update FormatDate() and ParseDate() to the new date range

Posted: Mon Dec 25, 2023 2:26 pm
by Little John
Well, this is also a bug report, since the above results of FormatDate() and ParseDate() are wrong anyway:

Code: Select all

Define.q date = Date(12345, 1, 2, 3, 4, 5)

Debug FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss", date)
; output        : 02.01.1234 03:04:05
; expected by me: 02.01.12345 03:04:05

Debug ParseDate("%dd.%mm.%yyyy %hh:%ii:%ss", "02.01.12345 03:04:05")
; output        : -1
; expected by me: 327403479845

Re: Update FormatDate() and ParseDate() to the new date range

Posted: Mon Dec 25, 2023 2:40 pm
by User_Russian
You think that in 12345 year, current applications and PB will be relevant?
With 9999 year works correctly.

Code: Select all

Define.q date = Date(9999, 1, 2, 3, 4, 5)
Debug date
Debug FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss", date)
Debug ParseDate("%dd.%mm.%yyyy %hh:%ii:%ss", "02.01.9999 03:04:05")

Re: Update FormatDate() and ParseDate() to the new date range

Posted: Mon Dec 25, 2023 2:51 pm
by Little John
User_Russian wrote: You think that in 12345 year, current applications and PB will be relevant?
I think, just like most other users, that PureBasic should work in accordance with its documentation.
Fred wrote:Updated: Date library for full 64bit support (new range is year 1601 to 30827)

[BUG]Re: Update FormatDate() and ParseDate() to the new date range

Posted: Mon Dec 25, 2023 3:03 pm
by juergenkulow

Code: Select all

; FormatDate and ParseDate overlow year 10000
; The last second of the year 1969 does not exist for FormatDate.
date=Date(9999, 12,31,23 , 59, 59)
Debug date 
Debug FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss",date)
date+1 
Debug FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss",date)
Debug Str(Day(date))+"."+Str(Month(date))+"."+Str(Year(date))+" "+Str(Hour(date))+":"+Str(Minute(date))+":"+Str(Second(date))
Debug ParseDate("%dd.%mm.%yyyy %hh:%ii:%ss", "1.1.1601 0:0:0")
Debug ParseDate("%dd.%mm.%yyyy %hh:%ii:%ss", "31.12.9999 23:59:59")
Debug ParseDate("%dd.%mm.%yyyy %hh:%ii:%ss", "1.1.10000 0:0:0")
Debug FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss", 
                 ParseDate("%dd.%mm.%yyyy %hh:%ii:%ss", "31.12.1969 23:59:59"))
Debug FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss", -2)
; 253402300799
; 31.12.9999 23:59:59
; 01.01.1000 00:00:00
; 1.1.10000 0:0:0
; -11644473600
; 253402300799
; -1
; 
; 31.12.1969 23:59:58

Re: [BUG]Re: Update FormatDate() and ParseDate() to the new date range

Posted: Mon Dec 25, 2023 4:06 pm
by freak
juergenkulow wrote: Mon Dec 25, 2023 3:03 pm

Code: Select all

; The last second of the year 1969 does not exist for FormatDate.
That is on purpose. The value -1 has always meant "invalid date" in the PB date library so we have to keep that for backward compatibility. Changing that would break a lot of code so having this one specific second be non-representable is the lesser of two evils here.

Re: Update FormatDate() and ParseDate() to the new date range

Posted: Mon Dec 25, 2023 4:31 pm
by User_Russian
Little John wrote: Mon Dec 25, 2023 2:51 pmshould work in accordance with its documentation.
The documentation has not yet been updated for 6.10.
The others functions are working correctly.

Code: Select all

Define.q date = Date(12345, 1, 2, 3, 4, 5)
Debug Year(date)
Debug Month(date)
Debug Day(date)
Debug Hour(date)
Debug Minute(date)
Debug Second(Date)

Re: Update FormatDate() and ParseDate() to the new date range

Posted: Mon Dec 25, 2023 4:45 pm
by Little John
User_Russian wrote: Mon Dec 25, 2023 4:31 pm
Little John wrote: Mon Dec 25, 2023 2:51 pmshould work in accordance with its documentation.
The documentation has not yet been updated for 6.10.
Try to read and understand my complete previous message, and stop trolling here!

Re: Update FormatDate() and ParseDate() to the new date range

Posted: Mon Dec 25, 2023 11:22 pm
by Andre
Sicro wrote: Mon Dec 25, 2023 12:47 pm
PureBasic 6.10 beta 1 - Xmas Release - is out ! wrote:Updated: Date library for full 64bit support (new range is year 1601 to 30827)
...
I hadn't the time to test PB 6.10 yet, but what I don't understand is the purpose of the new date range.... I would have expected that a greater supported range of around 29,000 years will go from history (let's say 20,000 BC) till future (e.g. year 9,000) to be usable for such purposes. Or do I see the goal of this new range not... :?:

Re: Update FormatDate() and ParseDate() to the new date range

Posted: Tue Dec 26, 2023 12:28 am
by freak
Andre wrote: Mon Dec 25, 2023 11:22 pm
Sicro wrote: Mon Dec 25, 2023 12:47 pm
PureBasic 6.10 beta 1 - Xmas Release - is out ! wrote:Updated: Date library for full 64bit support (new range is year 1601 to 30827)
...
I hadn't the time to test PB 6.10 yet, but what I don't understand is the purpose of the new date range.... I would have expected that a greater supported range of around 29,000 years will go from history (let's say 20,000 BC) till future (e.g. year 9,000) to be usable for such purposes. Or do I see the goal of this new range not... :?:
The range is a Windows API limitation. It comes from limits in the SYSTEMTIME and FILETIME structures (see here: https://learn.microsoft.com/en-us/windo ... systemtime)
We apply the same limit to the other OS to have a portable library with common limits.

It should be enough for all practical purposes. Dates like 20000BC make no sense to represent this way since the calendar we use did not exist then and it makes no sense to represent date and time that far back with a precision of seconds.

Re: Update FormatDate() and ParseDate() to the new date range

Posted: Tue Dec 26, 2023 4:26 pm
by Sicro
Little John wrote: Mon Dec 25, 2023 2:26 pm Well, this is also a bug report, since the above results of FormatDate() and ParseDate() are wrong anyway:

Code: Select all

Define.q date = Date(12345, 1, 2, 3, 4, 5)

Debug FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss", date)
; output        : 02.01.1234 03:04:05
; expected by me: 02.01.12345 03:04:05

Debug ParseDate("%dd.%mm.%yyyy %hh:%ii:%ss", "02.01.12345 03:04:05")
; output        : -1
; expected by me: 327403479845
You expect FormatDate() to replace the token %yyyy with 5 digits, although the documentation says that it replaces with 4 digits.

You expect ParseDate() to read 5 digits with the token %yyyy, although the documentation says that it only reads 4 digits.

It is not documented that %yyyy is the full year, although it was assumed before version 6.10 because the year could not be greater than 4 digits.

Ok, the documentation is a bit imprecise because e.g. %dd also accepts one digit, not just two digits.

Taking the current documentation into account, I don't see it as a bug, which is why I didn't want to report it as such. But yes, many would probably assume that %yyyy in version 6.10 now corresponds to 4 up to 5 digits of the year.

In my initial post, I thought it would make sense to keep %yyyy as is for backwards compatibility reasons, except that it then takes the last 4 digits of the year into account if the year has 5 digits. A new token %yyyyy (5 times "y" — or 6 times "y" for better visual differentiation) would then correspond to 4 or 5 digits of the year. The reason I thought of, for example, that %yyyy in ParseDate() should continue to match only 4 digits is, that someone uses ParseDate() for a simple plausibility check of the user input, where the year must have 4 digits and a year with more or less than 4 digits is evaluated as a typing error. Of course, a RegEx check would be better here.
freak wrote: Mon Dec 25, 2023 4:06 pm
juergenkulow wrote: Mon Dec 25, 2023 3:03 pm

Code: Select all

; The last second of the year 1969 does not exist for FormatDate.
That is on purpose. The value -1 has always meant "invalid date" in the PB date library so we have to keep that for backward compatibility. Changing that would break a lot of code so having this one specific second be non-representable is the lesser of two evils here.
It would be good if this were mentioned in the documentation of FormatDate().

Re: Update FormatDate() and ParseDate() to the new date range

Posted: Tue Dec 26, 2023 4:57 pm
by Little John
@Sicro:
In your original example, FormatDate() does not work correctly with a year >= 10000 when using the token "%yyyyy".
After I changed the example so that it uses the token "%yyyy", it doesn't work correctly either. That's why I see a bug here.
Or what other token should we use instead :?:

And yes, there is a big general problem when beta versions are released without complete documentation of the new functions.
I've been asking for it for years.

Re: Update FormatDate() and ParseDate() to the new date range

Posted: Wed Dec 27, 2023 12:54 am
by freak
Introduced a new "%yyyyy" format token to handle 5 digit years. If used on a 4 digit year it will force a leading 0 in FormatDate() to ensure proper parsing in ParseDate().

The "%yyyy" format token is restricted to 4 digits output even if the year has 5 digits.

Update: https://www.purebasic.fr/english/viewto ... 94#p613494