带有前导零的 gimp 方案格式化结果
gimp scheme formatting result with leading zeroes
我正在尝试获取文件名的时间戳。
我使用给出当前时间戳的过程(时间):
(120 11 29 17 32 25)
年-1900月-1日时分秒
(+ 1900 (car (time)) )(+ 1 (cadr (time)))(caddr(time))(cadddr(time))(cadr(cdddr(time)))(caddr(cdddr(time)))
这几乎不错,但是...如果任何元素小于 10(例如,1 月 1 日大约 1 a.m.:
(121 0 1 1 2 3)
它给出了错误的时间戳,因为我需要前导零
202111123
应该是 20210101010203
我想知道是否有比检查元素长度并添加“0”更简单的方法
Script-Fu 基于 Tiny Scheme, which is itself a subset of R5RS Scheme。 R5RS Scheme 中没有像这样格式化数字或字符串的内置功能,据我所知 none 添加到 Script-Fu,因此您需要为此创建自己的函数。
使用字符串最简单,而且您可能仍然需要字符串来为文件名添加时间戳。
这是一个用零填充字符串左侧的函数。请注意,结果的长度至少为 width
个字符,但如果输入 str
已经长于 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)))))
您可以在 time-stamp
函数中使用此函数,该函数 returns 所需格式的字符串:
(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)))
这里用list-ref
代替cadr
、caddr
、cadddr
等;这更易于阅读且不易出错。请注意,list-ref
在列表中使用从零开始的索引。
然后只需调用time-stamp
即可获取包含当前时间戳信息的字符串。如果你真的想要一个数字,你可以使用 string->number
,要么调用 time-stamp
的结果,要么在返回结果之前调用 time-stamp
的定义中的 string->number
:
> (time-stamp)
"20201229133118"
> (string->number (time-stamp))
20201229133150
我在 GIMP 中 运行 以上测试,所以它显示的是我当时的系统时间。这是使用您的模拟测试的示例:
> (define (time) '(121 0 1 1 2 3))
> (time-stamp)
"20210101010203"
> (string->number (time-stamp))
20210101010203
上面time-stamp
的第一个版本有很多代码重复。对于不熟悉 Scheme 编程习惯用法的人来说,该版本可能看起来更明显,但这里是一个更实用的版本,它删除了很多代码重复:
(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))))
最后我这样做了:
(define year (+ 1900 (car (time))))
(define month (+ 1 (cadr (time))))
(define day (caddr(time)))
(define hour (cadddr(time)))
(define minute (cadr(cdddr(time))))
(define second (caddr(cdddr(time))))
(set! newFileName (string-append inDir pathchar inFileName
(number->string year)
(if (< month 10) (string-append "0" (number->string month)) (number->string month))
(if (< day 10) (string-append "0" (number->string day)) (number->string day))
(if (< hour 10) (string-append "0" (number->string hour)) (number->string hour))
(if (< minute 10) (string-append "0" (number->string minute)) (number->string minute))
(if (< second 10) (string-append "0" (number->string second)) (number->string second))
saveString))
但我认为@ad absurdum 的回答要好得多。
我正在尝试获取文件名的时间戳。 我使用给出当前时间戳的过程(时间):
(120 11 29 17 32 25)
年-1900月-1日时分秒
(+ 1900 (car (time)) )(+ 1 (cadr (time)))(caddr(time))(cadddr(time))(cadr(cdddr(time)))(caddr(cdddr(time)))
这几乎不错,但是...如果任何元素小于 10(例如,1 月 1 日大约 1 a.m.:
(121 0 1 1 2 3)
它给出了错误的时间戳,因为我需要前导零
202111123
应该是 20210101010203
我想知道是否有比检查元素长度并添加“0”更简单的方法
Script-Fu 基于 Tiny Scheme, which is itself a subset of R5RS Scheme。 R5RS Scheme 中没有像这样格式化数字或字符串的内置功能,据我所知 none 添加到 Script-Fu,因此您需要为此创建自己的函数。
使用字符串最简单,而且您可能仍然需要字符串来为文件名添加时间戳。
这是一个用零填充字符串左侧的函数。请注意,结果的长度至少为 width
个字符,但如果输入 str
已经长于 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)))))
您可以在 time-stamp
函数中使用此函数,该函数 returns 所需格式的字符串:
(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)))
这里用list-ref
代替cadr
、caddr
、cadddr
等;这更易于阅读且不易出错。请注意,list-ref
在列表中使用从零开始的索引。
然后只需调用time-stamp
即可获取包含当前时间戳信息的字符串。如果你真的想要一个数字,你可以使用 string->number
,要么调用 time-stamp
的结果,要么在返回结果之前调用 time-stamp
的定义中的 string->number
:
> (time-stamp)
"20201229133118"
> (string->number (time-stamp))
20201229133150
我在 GIMP 中 运行 以上测试,所以它显示的是我当时的系统时间。这是使用您的模拟测试的示例:
> (define (time) '(121 0 1 1 2 3))
> (time-stamp)
"20210101010203"
> (string->number (time-stamp))
20210101010203
上面time-stamp
的第一个版本有很多代码重复。对于不熟悉 Scheme 编程习惯用法的人来说,该版本可能看起来更明显,但这里是一个更实用的版本,它删除了很多代码重复:
(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))))
最后我这样做了:
(define year (+ 1900 (car (time))))
(define month (+ 1 (cadr (time))))
(define day (caddr(time)))
(define hour (cadddr(time)))
(define minute (cadr(cdddr(time))))
(define second (caddr(cdddr(time))))
(set! newFileName (string-append inDir pathchar inFileName
(number->string year)
(if (< month 10) (string-append "0" (number->string month)) (number->string month))
(if (< day 10) (string-append "0" (number->string day)) (number->string day))
(if (< hour 10) (string-append "0" (number->string hour)) (number->string hour))
(if (< minute 10) (string-append "0" (number->string minute)) (number->string minute))
(if (< second 10) (string-append "0" (number->string second)) (number->string second))
saveString))
但我认为@ad absurdum 的回答要好得多。