For the longest time I have been using DOS_LIB's dos_fileex function to deal with vl-file-systime flakiness.
Odd timing: Today I needed to make a DOS_LIB free variant so I penned the code below. For what it's worth ...
(defun _Try ( try_statement / try_catch try_result )
;; General purpose error trapper.
(if
(vl-catch-all-error-p
(setq try_catch
(vl-catch-all-apply
(function
(lambda ( )
(setq try_result (eval try_statement))
)
)
)
)
)
(setq *try_errors* ;; lexical global
(cons
(list
try_statement
(vl-catch-all-error-message try_catch)
)
*try_errors*
)
)
)
try_result
)
(defun _JulianToDateStr ( julian_date / @floor @itoa a b c d e f y z year month day hours mins secs )
;; Renamed, reformatted and generally abused version of Jon
;; Fleming's classic JUL_CAL function written around 1991-09-09.
;; This version is coded to return the resulting value as a string,
;; e.g. "20121104_082248". I need this for file creation utilities
;; so often this is the default date format I use. Apologies if this
;; insults your sensibilities. MP.
;; ~ ~ ~
;; Calculate date. It's magic, don't even ask. Some things we
;; weren't meant to know. Jon Fleming.
(defun @floor ( number )
(fix
(if (> number 0)
number
(- number 1)
)
)
)
(defun @itoa ( i / result )
(setq result (itoa i))
(while (< (strlen result) 2)
(setq result (strcat "0" result))
)
result
)
(setq
z (fix julian_date)
a (fix (/ (- z 1867216.25) 36524.25))
a (+ z 1 a (- (fix (/ a 4))))
b (+ a 1524)
c (fix (/ (- b 122.1) 365.25))
d (@floor (* 365.25 c))
e (fix (/ (- b d) 30.6001))
day (fix (- b d (@floor (* 30.6001 e))))
e (- e (if (< e 14) 2 14))
month (1+ e)
year (if (> e 1) (- c 4716) (- c 4715))
year (if (zerop year) (1- year) year)
;; Calculate time. First strip the time portion
;; from the input.
y (- julian_date (fix julian_date))
;; Number of hours since midnight.
hours (fix (* y 24))
;; A temporary variable we'll use a couple of times.
f (- y (/ hours 24.0))
;; Number of minutes since midnight (1440 minutes per
;; day).
mins (fix (* f 1440))
;; Number of seconds since midnight (86400 seconds per
;; day). MP added (+ 0.5 ...) to match values returned by
;; the vl-file-systime function.
secs (fix (+ 0.5 (* (- f (/ mins 1440.0)) 86400)))
)
(strcat
(itoa year) (@itoa month) (@itoa day)
"_"
(@itoa hours) (@itoa mins) (@itoa secs)
)
)
(defun _GetFileDateVL ( filename / path temp result )
;; Return the file's date (last modified) as a string,
;; e.g. "20120911_073435". I need this for file creation
;; utilities so often this is the default date format I
;; use. Apologies if it insults your sensibilities. MP.
(if (setq path (findfile (findfile filename)))
(if (_Try '(setq temp (vl-file-systime path)))
(strcat
(substr
(setq result
(apply 'strcat
(mapcar
(function
(lambda ( n / s )
(if (eq 1 (strlen (setq s (itoa (nth n temp)))))
(strcat "0" s)
s
)
)
)
'(0 1 3 4 5 6)
)
)
)
1 ;; 2014 11 03
8
)
"_"
(substr result 9)
)
)
)
)
(defun _FSO ( )
;; cache it (I call it repeatedly)
(setq *fso* (vlax-create-object "scripting.filesystemobject"))
(defun _FSO ( ) *fso*)
*fso*
)
(defun _GetFileDateFSO ( filename / file result )
;; Return the file's date (last modified) as a string,
;; e.g. "20120911_073435". I need this for file creation
;; utilities so often this is the default date format I
;; use. Apologies if it insults your sensibilities. MP.
;;
;; Nods to Lee Mac, Black Box, Irneb and Jon Fleming for
;; respective tips, tricks, resources or sample code that
;; contributed to this variant.
(_Try
'(setq result
(_JulianToDateStr
(+ 2415019
(vlax-get
(setq file
(vlax-invoke
(_FSO)
'GetFile
(findfile filename)
)
)
'DateLastModified
)
)
)
)
)
(if file (_Try '(vlax-release-object file)))
result
)
(defun _GetFileDate ( filename / result )
;; Wrapper function for _GetFileDateVL and _GetFileDateFSO
;; functions, visual lisp and file system object methods
;; respectively.
;;
;; Return the file's date (last modified) as a string,
;; e.g. "20120911_073435". I need this for file creation
;; utilities so often this is the default date format I
;; use. Apologies if it insults your sensibilities. MP.
(or
;; try visual lisp first
(setq result (_GetFileDateVL filename))
;; vl-file-systime failed, call the fso sledge hammer
(setq result (_GetFileDateFSO filename))
)
result
)
tl;dr: _GetFileDate is a wrapper function, will use vl-file-systime based function if it can, otherwise exploiting the file system object based variant. Nods to Lee Mac, Black Box, Irneb and Jon Fleming for respective tips, tricks, resources or sample code that contributed to the variants above.