Req: DateTimeToFileDate replacement lazarus / 34-Windows ---------------------------------------------------------------------- WackaMold · 2022-01-11 01:52 DateTimeToFileDate cannot handle dates after the year 2099, but I could not find any documentation about that on FPC sites. Confirmation is found at "Year must be 1980 .. 2099" Confirmation in the source is at FPC\3.2.0\Source\rtl\objpas\sysutils\dati.inc line 1249 1242. FPC needs to be able to handle more file-dates, preferably approaching the same limits/capabilities of the target platform OS. For FileDates outside the range of DateTimeToFileDate, what set of functions is recommended? I know traditional UnixTime quits around 2038. Do I need to skip this part of the RTL and just use functions provided by the OS / Windows API? Because that is a reasonable option. Conceptually the use-case needs a minimum resolution of whole seconds, and does not want to fuss with fractions of a second. In reality, NTFS stores file Last-Write / Last-Modified DateTime in resolution of two seconds. Annoying but oh well. The old way is:   FileAge   FileDateToDateTime   IncYear (or whatever)   DateTimeToFileDate   FileSetDate What is the preferred new way? ---------------------------------------------------------------------- Thaddy · 2022-01-11 08:19 Loosing portability is not a reasonable option, imho. ---------------------------------------------------------------------- wp · 2022-01-11 09:38 What is the reason why this function is restricted to be valid only before year 2100? Looking at the source code Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Function DateTimeToFileDate(DateTime : TDateTime) : Int64; Var YY,MM,DD,H,m,s,msec : Word; begin  Decodedate (DateTime,YY,MM,DD);  DecodeTime (DateTime,h,m,s,msec);{$if not defined(unix) and not defined(wasi)}  If (YY<1980) or (YY>2099) then    Result:=0  else    begin    Result:=(s shr 1) or (m shl 5) or (h shl 11);    Result:=Result or longint(DD shl 16 or (MM shl 21) or (word(YY-1980) shl 25));    end;{$else unix or wasi}  Result:=LocalToEpoch(yy,mm,dd,h,m,s);{$endif unix or wasi}end;I get the impression that the programmer simply might have thought: "I don't want to care about leap years and leap seconds after 2100 for now" ---------------------------------------------------------------------- PascalDragon · 2022-01-11 10:09 Quote from: WackaMold on January 11, 2022, 02:52:10 amWhat is the preferred new way? The development version of FPC already provides support for FileSetDate overloads that take a TDateTime. This won't become part of the 3.2.x series however. Quote from: wp on January 11, 2022, 10:38:19 amWhat is the reason why this function is restricted to be valid only before year 2100? Looking at the source code Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Function DateTimeToFileDate(DateTime : TDateTime) : Int64; Var YY,MM,DD,H,m,s,msec : Word; begin  Decodedate (DateTime,YY,MM,DD);  DecodeTime (DateTime,h,m,s,msec);{$if not defined(unix) and not defined(wasi)}  If (YY<1980) or (YY>2099) then    Result:=0  else    begin    Result:=(s shr 1) or (m shl 5) or (h shl 11);    Result:=Result or longint(DD shl 16 or (MM shl 21) or (word(YY-1980) shl 25));    end;{$else unix or wasi}  Result:=LocalToEpoch(yy,mm,dd,h,m,s);{$endif unix or wasi}end;I get the impression that the programmer simply might have thought: "I don't want to care about leap years and leap seconds after 2100 for now" While DateTimeToFileDate returns a Int64 now that wasn't always the case (and was only changed so that the Unix timestamp is handled correctly), but on Windows it is in fact a 32-bit value that can only support the range 1980 to 2099, cause that is how it was originally defined in FAT and is supported by DOS and Windows (see here). ---------------------------------------------------------------------- wp · 2022-01-11 10:20 Thanks. But still, the specs that you cite say that here are 7 bits for the years since 1980 (128 years). This means that physically the range should be extendable to 1980+128 = 2208. Not much, though... ---------------------------------------------------------------------- PascalDragon · 2022-01-11 10:55 The documentation for FileTimeToDosDateTime indeed explicitly mentions 2107, so yes, 8 more years might be possible, but in the end one should use the new overloads once they're available. ---------------------------------------------------------------------- WackaMold · 2022-01-12 00:25 Thanks, yeah, the restriction is to remain compatible with DOS/FAT16. Wishing for a compiler directive or other supported method for programs to drop such ancient compatibility and instead support more- modern minimum standards like FAT32 or NTFS. My intent is to support at least the same range for File-Dates that Windows does. Found some current overloads of FileSetDate at https://gitlab.com/free pascal.org/fpc/source/-/blob/main/rtl/objpas/sysutils/sysutils.inc lines 61 and 82. Both versions call FileSetDate( ). Where is that function? Also where can I find sources for "FileSetDate overloads that take a TDateTime"? Could not find sources in snapshot downloads ---------------------------------------------------------------------- trev · 2022-01-12 02:53 QuoteAlso where can I find sources for "FileSetDate overloads that take a TDateTime"? Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i fpc- src/rtl/win/sysutils.pp ---------------------------------------------------------------------- PascalDragon · 2022-01-12 08:16 Quote from: WackaMold on January 12, 2022, 01:25:52 amThanks, yeah, the restriction is to remain compatible with DOS/FAT16. Wishing for a compiler directive or other supported method for programs to drop such ancient compatibility and instead support more-modern minimum standards like FAT32 or NTFS. My intent is to support at least the same range for File-Dates that Windows does. That's why overloads are introduced. It's important to remain backwards compatible to old code. And a compiler switch can't change anything there, because pre-compiled units can not be affected by another unit. Sidenote: FAT32 has the same restriction. Quote from: WackaMold on January 12, 2022, 01:25:52 amFound some current overloads of FileSetDate at https://gitlab.com/freepascal.org/ fpc/source/-/blob/main/rtl/objpas/sysutils/sysutils.inc lines 61 and 82. Both versions call FileSetDate( ). Where is that function? Those are only wrappers that wrap from name-based to handle-based FileSetDate. The real FileSetDate implementations are in the SysUtils unit of each platform. Quote from: WackaMold on January 12, 2022, 01:25:52 amAlso where can I find sources for "FileSetDate overloads that take a TDateTime"? Could not find sources in snapshot downloads Easiest is to down the full source for FPC 3.3.1 (aka main) and change Lazarus' source directory to that. Then you write a program or unit that uses the SysUtils unit and you use the FileSetDate identifier somewhere. Ctrl+Click on it which will take you to the declaration and Ctrl+Shift+Down which will take you to the implementation for the setup target. ---------------------------------------------------------------------- WackaMold · 2022-01-13 01:11 Waitaminnit, do you mean "Lazarus directory" or "FPC source directory"? [screenshot] Neither one seemed to just-work. Also what would I add/change on the FPC.EXE command line or in FPC.cfg for compiling with an alternate Source folder? Because I mostly use makefiles and Cmd/Bat scripts for compile+link rather than Lazarus. I'm not here for "easy" To give an idea of the flailing - Laz complained like, 'system.ppu is for the other bitness'. This might be an opportunity to completely re- install 3.2.x then slipstream-update to 3.3.1-Dev binaries and sources, so as to build native 32-bit Win32 EXEs instead of 64-bit. Cross-compiling to 64-bit or Android is nice to have, but not necessary.