【问题标题】:From unix time in seconds to datetime in ISO-8601从以秒为单位的 unix 时间到 ISO-8601 中的日期时间
【发布时间】:2020-02-02 07:22:18
【问题描述】:

TL;博士。如何从以秒为单位的 unix 时间到 ISO-8601 格式的日期时间?这看起来更像是一个图书馆问题而不是语言问题。

我希望能够将 ping 时间戳(unix 时间 + 微秒)解释为日期时间,以便能够对其进行可视化或执行日期和时间操作。我有一个很长的 ping 跟踪(数千行),其中每一行都表示 ping 的成功或失败。

我已经设法使用正则表达式制作了一个玩具示例来获取 unix 时间(没有微秒),但我没有找到如何在 APL 中使用日期时间。我在 Github 上找到了 APLteam 的 APLtree 项目及其名为 DateAndTime 的子项目,但我无法安装它。我不知道如何继续。

请注意,我知道我已经在 ping 时间戳前面以 ISO-8601 格式明确编写了日期时间,但为了学习 APL 的基础知识,我想操纵日期时间。我还可以对 unix 时间执行操作,然后尝试(但如何)将它们转换为 ISO-8601 格式的日期时间。

在 Linux 上使用以下命令生成跟踪:

ping -n -i 30 -O -D my.domain.name | while read pong; do echo "[WAN] $(date --iso-8601=seconds): $pong"; done

输出轨迹是:

[WAN] 2020-01-31T18:02:35+0100: [1580490155.323878] 64 bytes from 8.8.8.8: icmp_seq=1037 ttl=234 time=720 ms
[WAN] 2020-01-31T18:03:34+0100: [1580490214.630890] no answer yet for icmp_seq=1038

APL 计划:

      v←('\[(\d+)\.'⎕S'\1')⊃⎕NGET'/Users/ludo/Desktop/so/ping.txt' 1
      v
 1580490155  1580490214
      ⍴v
2
      DISPLAY v
┌→──────────────────────────┐
│ ┌→─────────┐ ┌→─────────┐ │
│ │1580490155│ │1580490214│ │
│ └──────────┘ └──────────┘ │
└∊──────────────────────────┘

我还有一个问题:为什么 [] 的使用之间的排名差异?我们是否在一种情况下有一个向量,在另一种情况下有一个简单的字符串(标量)?为什么⍴⍴v[1] 为零?请参阅下面的示例。

      v←⎕NGET'/Users/ludo/Desktop/so/ping.txt' 1
      v
  [WAN] 2020-01-31T18:02:35+0100: [1580490155.323878] 64 bytes from 8.8.8.8: ic
      mp_seq=1037 ttl=234 time=720 ms  [WAN] 2020-01-31T18:03:34+0100: [1580490
      214.630890] no answer yet for icmp_seq=1038   UTF-8-NOBOM  13 10
      DISPLAY v
┌→───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ┌→─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ ┌→──────────┐ ┌→────┐ │
│ │ ┌→───────────────────────────────────────────────────────────────────────────────────────────────────────────┐ ┌→──────────────────────────────────────────────────────────────────────────────────┐ │ │UTF-8-NOBOM│ │13 10│ │
│ │ │[WAN] 2020-01-31T18:02:35+0100: [1580490155.323878] 64 bytes from 8.8.8.8: icmp_seq=1037 ttl=234 time=720 ms│ │[WAN] 2020-01-31T18:03:34+0100: [1580490214.630890] no answer yet for icmp_seq=1038│ │ └───────────┘ └~────┘ │
│ │ └────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ └───────────────────────────────────────────────────────────────────────────────────┘ │                       │
│ └∊─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘                       │
└∊───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
      ⍴v
3
      v[1]
  [WAN] 2020-01-31T18:02:35+0100: [1580490155.323878] 64 bytes from 8.8.8.8: ic
      mp_seq=1037 ttl=234 time=720 ms  [WAN] 2020-01-31T18:03:34+0100: [1580490
      214.630890] no answer yet for icmp_seq=1038
      ⊃v
 [WAN] 2020-01-31T18:02:35+0100: [1580490155.323878] 64 bytes from 8.8.8.8: icm
      p_seq=1037 ttl=234 time=720 ms  [WAN] 2020-01-31T18:03:34+0100: [15804902
      14.630890] no answer yet for icmp_seq=1038
      ⍴v[1]

      ⍴⊃v
2
      ⍴⍴v[1]
0
      ⍴⍴⊃v
1

【问题讨论】:

  • 也许 https://stackoverflow.com/q/58300764/452614 使用 dfns 可能是要走的路。我会检查这个。
  • 这样的事情可能会起作用:date¨ (days 1970 1 1)+seconds÷86400 其中seconds2⊃¨⎕VFI¨ ('\[(\d+)\.'⎕S'\1')⊃⎕NGET'/Users/ludo/Desktop/so/ping.txt' 1⎕VFI 用于将字符串转换为数字。日期时间为 UTC。
  • 我应该提到 Dyalog 18.0 将有一个内置的 ⎕C 来进行 date/days 转换,并且可能还有一个工具来进行 ISO 格式化。

标签: apl dyalog


【解决方案1】:

如何从以秒为单位的 unix 时间转换为 ISO-8601 格式的日期时间?

      'date' 'days'⎕CY'dfns'
      unix0←days 1970 1 1
      sPerDay←24×60×60
      UnixToTs←date unix0+÷∘sPerDay
      TsToIso←{'--T::'@(2+3×⍳5)∊⍕¨(⊃,100+1∘↓)6↑⍵}   ⍝ modified from aplcart.info?q=iso8601
      UnixToIso←TsToIso UnixToTs
      UnixToIso 1580490155
2020-01-31T17:02:35

Try it online!

为了您的方便,下面是相反的:

      IsoToTs←⍎¨∊∘⎕D⊆⊢
      TsToUnix←sPerDay×unix0-⍨days
      IsoToUnix←TsToUnix IsoToTs
      IsoToUnix '2020-01-31T17:02:35'
1580490155

Try it online!


使用正则表达式获取 unix 时间

如果您的文件是一致的,我建议使用 APL 来提取数据,因为它可以产生巨大的速度差异。例如,如果所有行都使用这种精确格式:

      v←(⍎¯10↑43∘↑)¨⊃⎕NGET'/Users/ludo/Desktop/so/ping.txt' 1
      DISPLAY v
┌→────────────────────┐
│1580490155 1580490214│
└~────────────────────┘

为什么 [] 和 ⊃ 的使用有排名差异?

[] 从不公开(“打开”)它从数组中提取的元素,因此嵌套数组的元素保持封闭。

我们是否在一种情况下有一个向量,在另一种情况下有一个简单的字符串(标量)?

是的,尽管在一种情况下最好将其表述为向量,在另一种情况下将其表述为 封闭 向量。

为什么⍴⍴v[1]为零?

因为标量的秩(即使它包含更高秩的数组)为零。

【讨论】:

  • 感谢您的快速回答。它包含许多有用的信息,这些信息将为未来的思想提供食物。对于速度,我确实注意到使用正则表达式处理 5500 行会延迟 1 或 2 秒。
猜你喜欢
  • 1970-01-01
  • 2016-09-06
  • 2013-11-11
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 2015-01-30
  • 2010-10-23
相关资源
最近更新 更多