任何Smalltalk方言中的时间格式(HH:MM:SS)

时间:2017-05-23 22:10:02

标签: string time smalltalk

我有三个整数值,比如说

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参数,但是没有一种更简单的方法可以用字符串做事吗?

或许有一种更优雅的方式来填充三个组件然后我可以返回hs, ':', ms, ':', ss

或者,是否存在所有Smalltalks共有的POSIX时间格式(或类似内容)的接口?我知道GNU Smalltalk可以链接到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中。

1 个答案:

答案 0 :(得分:3)

以下是在Pharo中执行此操作的方法:

String streamContents: [:stream |
  {h.m.s}
    do: [:token | token printOn: stream base: 10 nDigits: 2]
    separatedBy: [stream nextPut: $:]]

说明:

  1. streamContents:消息回答正式阻止参数WriteStream所代表的stream的内容。

  2. do:separatedBy:消息列举了令牌hms,为每个令牌评估do:块并插入评估连续令牌之间的第二个区块。

  3. printOn:base:nDigits:消息转储stream基础10表示token填充为2位数。

    < / LI>

    如果您使用的方言没有printOn:base:nDigits:方法(或其任何适当的变体),您可以执行以下操作:

    String streamContents: [:stream |
      {h.m.s}
        do: [:token |
          token < 10 ifTrue: [stream nextPut: $0].
          stream nextPutAll: token asString]
        separatedBy: [stream nextPut: $:]]
    

    最后,如果您认为自己会经常使用此功能,我建议您将hhmmss消息添加到Time(实例方),如上所述,使用self hours代替{ {1}}等等然后发送

    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将替换为每次迭代的相应元素。

    ADDENDUM 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是确保文字未被修改所必需的。