%Y-%m-%s %H:%M:%S %z目標是使用 POSIX 工具將日期格式轉換為自 EPOCH 以來的秒數。
我目前對 POSIX's Seconds since the Epoch的公式有疑問:我得到的結果與 GNU/BSD 不同date。
這是我的代碼,為測驗目的而簡化:
#!/bin/bash
TZ=UTC date $' date: %Y-%m-%d %T %z \nexpect: %s \n %Y %j %H %M %S %z' |
awk '
NR <= 2 { print; next }
{
# $0: "YYYY jjj HH MM SS zzzzz"
$1 -= 1900
epoch = $5 $4*60 $3*3600 int($2 ($1-70)*365 ($1-69)/4 - ($1-1)/100 ($1 299)/400)*86400
print "result:", epoch
}
'
date: 2022-10-21 22:02:56 0000
expect: 1666389776
result: 1666476176
我究竟做錯了什么?
uj5u.com熱心網友回復:
@Fravadona:您不需要在月末累積的朱利安天數中進行硬編碼:
function ____(__,___,_)
{
# __| mm:
# ___| yyyy:
# |--> cumulative julian days by month-end
return \
((__=int(__))<(_ =_^=_<_) ? !_ : -_ (___=="" ||
(___=int(___)) % (_ _) ? !_ : \
! (___%((_ _)*((_ _*_*_)^_)^!(___%(_ _*_*_)^_)))))\
\
( _ _^_--)*__\
\
substr((_=((--_ ( _ _*_*_)^_)^_ _)*(_^ _ _)) \
(_ (((_ =_^=!_)* _)^ _* _*(_- - _ _* _)- --_)),__,_^(_<_))
}
假設公歷之前的年份遵循相同的閏年規則,并假設月份輸入為[1, 12]且年份輸入為,則僅[1, 2^53)此函式應回傳精確累積的儒略天數,直到月底,包括在內,對于任何年月組合
(缺少年份輸入默認被視為非閏年):
1900 1 31 2000 1 31 2002 1 31 2023 1 31 2024 1 31
1900 2 59 2000 2 60 2002 2 59 2023 2 59 2024 2 60
1900 3 90 2000 3 91 2002 3 90 2023 3 90 2024 3 91
1900 4 120 2000 4 121 2002 4 120 2023 4 120 2024 4 121
1900 5 151 2000 5 152 2002 5 151 2023 5 151 2024 5 152
1900 6 181 2000 6 182 2002 6 181 2023 6 181 2024 6 182
1900 7 212 2000 7 213 2002 7 212 2023 7 212 2024 7 213
1900 8 243 2000 8 244 2002 8 243 2023 8 243 2024 8 244
1900 9 273 2000 9 274 2002 9 273 2023 9 273 2024 9 274
1900 10 304 2000 10 305 2002 10 304 2023 10 304 2024 10 305
1900 11 334 2000 11 335 2002 11 334 2023 11 334 2024 11 335
1900 12 365 2000 12 366 2002 12 365 2023 12 365 2024 12 366
uj5u.com熱心網友回復:
通過仔細閱讀規范,我發現了兩個問題:
tm_yday值應該是date ' %j'負一:
自當年 1 月 1 日以來的天數 (tm_year)
- 需要整數運算:
公式中的除法是整數除法
下面的代碼現在可以作業了;我還添加了對時區%z格式的支持:
#!/bin/bash
date $' date: %Y-%m-%d %T %z \nexpect: %s \n %Y %j %H %M %S %z' |
awk '
NR <= 2 { print; next }
{
# $0: "YYYY jjj HH MM SS zzzzz"
tm_year = $1 - 1900
tm_yday = $2 - 1
tm_hour = $3
tm_min = $4
tm_sec = $5
zoffset = \
int(substr($6,1,1) "1") * \
(substr($6,2,2)*3600 substr($6,4,2)*60)
epoch = \
tm_sec tm_min*60 tm_hour*3600 tm_yday*86400 \
(tm_year-70)*31536000 int((tm_year-69)/4)*86400 - \
int((tm_year-1)/100)*86400 int((tm_year 299)/400)*86400 - \
zoffset
print "result:", epoch
}
'
date: 2022-10-22 01:19:23 0200
expect: 1666394363
result: 1666394363
在旁邊
mktime這是POSIX的 GNU 函式的示例實作awk。它將格式%Y %m %d %H %M %S %z中的日期轉換為自 EPOCH 以來的秒數:
function mktime(datespec, a) {
if ( !_mktime_init ) {
_mktime_init = 1
split("0 31 59 90 120 151 181 212 243 273 304 334",_mktime_moff," ")
}
# datespec: "YYYY mm dd HH MM SS zzzzz"
split(datespec,a," ")
a[7] = \
int(substr(a[7],1,1) "1") * \
(substr(a[7],2,2)*3600 substr(a[7],4,2)*60)
a[3] = \
-1 _mktime_moff[a[2] 0] \
(a[2] > 2 && ((a[1]%4 == 0 && a[1]%100 != 0) || a[1]%400 == 0))
a[1] -= 1900
return \
a[6] a[5]*60 a[4]*3600 a[3]*86400 \
(a[1]-70)*31536000 int((a[1]-69)/4)*86400 - \
int((a[1]-1)/100)*86400 int((a[1] 299)/400)*86400 - \
a[7]
}
抱歉,我知道使用有意義的變數名可以更輕松地閱讀代碼,但我將其緊湊以方便復制/粘貼和集成到我的腳本中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/520159.html
標籤:壳awk正则表达式时代
下一篇:CMD C不會殺死行程
