I'm trying to get timestamp for filename. I use procedure (time) which gives current timestamp:
(120 11 29 17 32 25)
year-1900 month-1 day hour minute second
(+ 1900 (car (time)) )(+ 1 (cadr (time)))(caddr(time))(cadddr(time))(cadr(cdddr(time)))(caddr(cdddr(time)))
this is almost good but... if any of element is lesser then 10 (e.g. first of january about 1 a.m.:
(121 0 1 1 2 3)
it gaves incorrect timestamp, because I need leading zeroes
202111123
should be 20210101010203
I wonder if there's a simplier method than checking the length of element and adding "0"
Script-Fu is based on Tiny Scheme, which is itself a subset of R5RS Scheme. There is no built-in functionality in R5RS Scheme to format numbers or strings like this, and none added to Script-Fu as far as I know, so you will need to create your own functions for this.
It would be easiest to work with strings, and you probably want strings anyway for adding a timestamp to a filename.
Here is a function that left-pads a string with zeroes. Note that the result is at least width
characters in length, but the input str
is not trimmed if it is already longer than width
:
(define (left-pad str width pad)
(let add-padding ((s str))
(if (< (- width (string-length s)) 1)
s
(add-padding (string-append pad s)))))
You can use this function in a time-stamp
function that returns a string in the desired format:
(define (time-stamp)
(let* ((curr (time))
(year (number->string (+ 1900 (list-ref curr 0))))
(month (left-pad (number->string (+ 1 (list-ref curr 1))) 2 "0"))
(day (left-pad (number->string (list-ref curr 2)) 2 "0"))
(hour (left-pad (number->string (list-ref curr 3)) 2 "0"))
(minute (left-pad (number->string (list-ref curr 4)) 2 "0"))
(second (left-pad (number->string (list-ref curr 5)) 2 "0")))
(string-append year month day hour minute second)))
Here, list-ref
is used instead of cadr
, caddr
, cadddr
, etc.; this is easier to read and less error-prone. Note that list-ref
uses zero-based indices into a list.
Then just call time-stamp
to get a string containing the current time-stamp information. You can use string->number
if you really want a number from this, either calling on the result of time-stamp
, or calling string->number
in the definition of time-stamp
before the result is returned:
> (time-stamp)
"20201229133118"
> (string->number (time-stamp))
20201229133150
I ran the above test in GIMP, so it is showing my system time at that moment. Here is an example using your mock test:
> (define (time) '(121 0 1 1 2 3))
> (time-stamp)
"20210101010203"
> (string->number (time-stamp))
20210101010203
There is a lot of code duplication in the first version of time-stamp
above. That version may look more obvious to someone not familiar with Scheme programming idioms, but here is a version in a more functional style that removes a lot of that code duplication:
(define (time-stamp)
(let* ((curr (time))
(y (+ 1900 (car curr)))
(m (+ 1 (cadr curr)))
(tstamp-nums (apply list y m (cddr curr))))
(apply string-append
(map (lambda (x) (left-pad (number->string x) 2 "0"))
tstamp-nums))))