任何 Smalltalk 方言中的时间格式 (HH:MM:SS)
Time formatting (HH:MM:SS) in any Smalltalk dialect
我有三个整数值,比方说
h := 3.
m := 19.
s := 8.
我想生成字符串 '03:19:08'
。我知道如何将数字转换为字符串,甚至在必要时用零填充它。因此,作为第一步,我写了这个绝对可怕的代码:
h < 10 ifTrue: [hs := '0', (h asString)] ifFalse: [hs := h asString].
m < 10 ifTrue: [ms := '0', (m asString)] ifFalse: [ms := m asString].
s < 10 ifTrue: [ss := '0', (s asString)] ifFalse: [ss := s asString].
Transcript show: hs, ':', ms, ':', ss.
Transcript nl.
现在显然我需要清理它,所以我想知道这里最惯用的 Smalltalk 方法是什么。会不会像(显然不是合法的 Smalltalk):
aCollectionWithHMS each [c | padWithZero] join ':'
我发现了一个关于使用带有 separatedBy
参数的打印方法的流的讨论,但是难道没有更简单的方法来处理字符串吗?
或者也许有更优雅的方法来填充三个组件然后我可以 return hs, ':', ms, ':', ss
?
或者,是否有所有 Smalltalks 通用的 POSIX 时间格式(或类似的东西)接口?我知道 GNU Smalltalk 可以 link 到 C,但是对于这个简单的问题恕我直言,这太过分了。
编辑
我靠近了一点:
z := {h . m . s} collect: [:c | c < 10 ifTrue: ['0', c asString] ifFalse: [c asString]].
(Transcript show: ((z at: 1), ':', (z at: 2), ':', (z at: 3))) nl.
但是集合元素的直接访问让我很难过。我找到了 page documenting the joining method asStringWith
但该方法不受支持,它似乎在 GNU Smalltalk 中。
这是在 Pharo 中执行此操作的一种方法:
String streamContents: [:stream |
{h.m.s}
do: [:token | token printOn: stream base: 10 nDigits: 2]
separatedBy: [stream nextPut: $:]]
解释:
streamContents:
消息用正式块参数 stream
表示的 WriteStream
的内容进行应答。
do:separatedBy:
消息枚举了令牌 h
、m
和 s
为每个令牌评估 do:
块,并且在连续的标记之间插入第二个块的评估。
printOn:base:nDigits:
消息转储到 stream
基础 10
表示 token
填充到 2
数字。
如果您使用的方言没有 printOn:base:nDigits:
方法(或其任何适当的变体),您可以执行以下操作:
String streamContents: [:stream |
{h.m.s}
do: [:token |
token < 10 ifTrue: [stream nextPut: [=11=]].
stream nextPutAll: token asString]
separatedBy: [stream nextPut: $:]]
最后,如果你认为你会经常使用它,我建议将消息 hhmmss
添加到 Time
(实例端),如上所示用 self hours
实现的h
,等等。然后就是发送
的问题
(Time hour: h minute: m second: s) hhmmss
假设您拥有这三个量而不是 Time
对象,这将是不寻常的。否则,你只需要像
这样的东西
aTime hhmmss
附录
这是适用于任何方言的另一种方法:
{h.m.s}
inject: ''
into: [:r :t | | pad colon |
pad := t < 10 ifTrue: ['0'] ifFalse: [''].
colon := r isEmpty ifTrue: [''] ifFalse: [':'].
r , colon, pad, t asString]
inject:into:
方法从 inject:
参数(在本例中为空 String
)构建其结果,并不断用值替换正式块参数 r
上一次迭代的。第二个正式参数 t
替换为每次迭代的相应元素。
附录 2
time := '00:00:00' copy.
{h asString. m asString. s asString} withIndexDo: [:t :i |
time at: i - 1 * 3 + 2 put: t last.
t size = 2 ifTrue: [time at: i - 1 * 3 + 1 put: t first]].
^time
copy
是确保文字未被修改所必需的。
我有三个整数值,比方说
h := 3.
m := 19.
s := 8.
我想生成字符串 '03:19:08'
。我知道如何将数字转换为字符串,甚至在必要时用零填充它。因此,作为第一步,我写了这个绝对可怕的代码:
h < 10 ifTrue: [hs := '0', (h asString)] ifFalse: [hs := h asString].
m < 10 ifTrue: [ms := '0', (m asString)] ifFalse: [ms := m asString].
s < 10 ifTrue: [ss := '0', (s asString)] ifFalse: [ss := s asString].
Transcript show: hs, ':', ms, ':', ss.
Transcript nl.
现在显然我需要清理它,所以我想知道这里最惯用的 Smalltalk 方法是什么。会不会像(显然不是合法的 Smalltalk):
aCollectionWithHMS each [c | padWithZero] join ':'
我发现了一个关于使用带有 separatedBy
参数的打印方法的流的讨论,但是难道没有更简单的方法来处理字符串吗?
或者也许有更优雅的方法来填充三个组件然后我可以 return hs, ':', ms, ':', ss
?
或者,是否有所有 Smalltalks 通用的 POSIX 时间格式(或类似的东西)接口?我知道 GNU Smalltalk 可以 link 到 C,但是对于这个简单的问题恕我直言,这太过分了。
编辑
我靠近了一点:
z := {h . m . s} collect: [:c | c < 10 ifTrue: ['0', c asString] ifFalse: [c asString]].
(Transcript show: ((z at: 1), ':', (z at: 2), ':', (z at: 3))) nl.
但是集合元素的直接访问让我很难过。我找到了 page documenting the joining method asStringWith
但该方法不受支持,它似乎在 GNU Smalltalk 中。
这是在 Pharo 中执行此操作的一种方法:
String streamContents: [:stream |
{h.m.s}
do: [:token | token printOn: stream base: 10 nDigits: 2]
separatedBy: [stream nextPut: $:]]
解释:
streamContents:
消息用正式块参数stream
表示的WriteStream
的内容进行应答。do:separatedBy:
消息枚举了令牌h
、m
和s
为每个令牌评估do:
块,并且在连续的标记之间插入第二个块的评估。printOn:base:nDigits:
消息转储到stream
基础10
表示token
填充到2
数字。
如果您使用的方言没有 printOn:base:nDigits:
方法(或其任何适当的变体),您可以执行以下操作:
String streamContents: [:stream |
{h.m.s}
do: [:token |
token < 10 ifTrue: [stream nextPut: [=11=]].
stream nextPutAll: token asString]
separatedBy: [stream nextPut: $:]]
最后,如果你认为你会经常使用它,我建议将消息 hhmmss
添加到 Time
(实例端),如上所示用 self hours
实现的h
,等等。然后就是发送
(Time hour: h minute: m second: s) hhmmss
假设您拥有这三个量而不是 Time
对象,这将是不寻常的。否则,你只需要像
aTime hhmmss
附录
这是适用于任何方言的另一种方法:
{h.m.s}
inject: ''
into: [:r :t | | pad colon |
pad := t < 10 ifTrue: ['0'] ifFalse: [''].
colon := r isEmpty ifTrue: [''] ifFalse: [':'].
r , colon, pad, t asString]
inject:into:
方法从 inject:
参数(在本例中为空 String
)构建其结果,并不断用值替换正式块参数 r
上一次迭代的。第二个正式参数 t
替换为每次迭代的相应元素。
附录 2
time := '00:00:00' copy.
{h asString. m asString. s asString} withIndexDo: [:t :i |
time at: i - 1 * 3 + 2 put: t last.
t size = 2 ifTrue: [time at: i - 1 * 3 + 1 put: t first]].
^time
copy
是确保文字未被修改所必需的。