LoginSignup
2
3

More than 3 years have passed since last update.

UTCが欲しい

Last updated at Posted at 2019-12-07

小ネタ

UTC

協定世界時@wikipedia

そもそもSplunkの_timeは UNIX時間なので気楽にだせるはず。

今の時刻を確認してみる

SPL
| makeresults 
| eval time=strftime(_time,"%F %T %Z")
_time time
2019/12/07 09:23:48 2019-12-07 09:23:48 JST

日本標準時@wikipediaになっていますね。

UTCに変更してみる

SPL
| makeresults 
| eval time_suffix=strftime(_time,"%:::z") 
| eval time_suffix_mod=time_suffix * -1
| eval unix_time=relative_time(_time,(time_suffix_mod."h"))
| eval unix_time=strftime(utc_time, "%F %T.%3N")
_time time_suffix time_suffix_mod utc_time
2019/12/07 09:40:26 +09 -9 2019-12-07 00:40:26.000

%zをつけるとバレてしまうので、この形。
プラスマイナス変換に-1を掛けるのも、知ってしまえば当然だけど、最初はcaseで作ってた・・・・

追記(R2.7.24)

Splunk>Answersで、昔やったよな〜と思いつつ回答した。。

このページを見返したところ、上記クエリーは"-01"のように、アメリカあたりの時刻帯だと上手く動かないことが判明

GMT.spl
| makeresults
| eval time=strftime(_time,"%FT%T %:::z")
| eval offset = substr(time,21,23)
| eval time_args = if( -1 * offset >= 0, "+".substr(offset,2,3), printf("%03d",-1 * offset))
| eval GMT = ceil(relative_time(_time,time_args."h"))
| convert ctime(GMT)

やっぱり、±判定が必要らしい。
printf()"-01"といった文字列を作っている。%03なのに注目。

relative_time()はミリセコンド以下を切りすてるので、必要な場合は別途くっつける必要がある。今回はじゃまな.000000を削除するためceil()している。

time format

Common Time Format Variables@Splunk>Docs
覚え切らないので、基本は %F %T%c

props.confで変える

I want to set a different time zone from the time@Splunk Answer
ふと見てたらこんなやつを見つけた。

TZ(Time Formatだと%z)の値を上書きするオプションがTZ_ALIAS
TZ_ALIAS= 00:00=JSTが回答。なので
TZ_ALIAS= 00:00=UTCにしてしまえば、多分UTC

1970年より前でも欲しい

before1970.spl
| makeresults 
| eval time=-31553280 
| appendpipe
    [eval time=0]
    | makecontinuous time span=-31553280
| eval date=strftime(time,"%F %T")
| head 1970
| rex field=date "(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) (?<hour>\d{2}):(?<min>\d{2}):(?<sec>\d{2})"

| eval leap_year=if(year % 400 =0 OR (year % 4 =0 AND year % 100 !=0),"Leap", "NOTLeap") 
| eval mod_day=sec + 60 * min + pow(60,2) * hour + 24 * pow(60,2) * (tonumber(day)-1)
| eval date=strftime(time-mod_day,"%F %T")
| eval mod_3month=if(leap_year=="NOTLeap",mod_day+24*pow(60,2)*59,mod_day+24*pow(60,2)*60)
| eval mod_2month=mod_day+24*pow(60,2)*31
| eval date=case(month="03",strftime(time-mod_3month,"%F %T"),month="02",strftime(time-mod_2month,"%F %T"),true(),date)

| appendpipe
    [eval time=0, date=strftime(time,"%F %T")
    | head 1]
    | table date time
    | sort 0 - time

2020年問題もあるなか、今回1970年より前の年を出してみたくなり作ってみた。
strptimeが使えないのでこんな感じ。
Microsoftの閏年判定も組み込んでいろいろ調整をして作ってみた。
JSTは一回修正して-9時間してはみたもののバグが多すぎるので、この形にした。

UNIX data represents different points in time as signed integers, traditionally of 32 bits, by encoding the UNIX timestamp. Because it uses 32 bits, UNIX time can only cover approximately 136 years in total. In other words, the maximum representable time for UNIX time is 19 January 2038 and the minimum representable time is 13 December 1901.

Date & timeTimes that occurred before 1970 (the epoch time) have a negative value. When the counter passes the maximum date, the counter will ‘run out’ and time will ‘wrap around’ and be stored as a negative number (13 December 1901). This is referred to as the UNIX millennium bug.

splunk answerでなんとかならないのかと質問したら、このコメントが帰ってきた。でも負けない。

epochの限界

limit.spl
| makeresults
| eval time=-62167252739
| eval _time=time
| eval time_text=strftime(_time,"%c %::z")

-62167252739がepochの限界っぽい。
ターミナルでdate -r -62167252739で確認したら 0000年 1月 1日 土曜日 00時00分00秒 LMTが帰ってきた。

Splunkの時間について

until1887-01-01.spl
| makeresults 
| eval time=-62167252739
| appendpipe
    [eval time=0]
| eval date=strftime(time,"%F %T")
| makecontinuous span=31536000 time
| eval date=strftime(time,"%F %T")
| rex field=date "(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) (?<hour>\d{2}):(?<min>\d{2}):(?<sec>\d{2})"
| dedup year
| eval mod_date=strftime(time,"%j")
| eval time=if(day="01",time,time - (mod_date -1)  * 24 * 60 * 60)
| eval date=strftime(time,"%F %T")

strftime()は使えるから始めの時間から逆算で作ってみた。
1887-01-01 00:00:00 -2619249539までは普通に動いていたけどそこからがおかしくなった。

1970前でもUTCが欲しいver2

before1970v2.spl
| makeresults count=2
| streamstats count
| eval time=if(count=1,0,-62167252739)
| makecontinuous time span=31536000
| eval time = time - (time % (24 * 60 * 60))- (9 * 60 * 60)
| sort 100 - time
| eval date=strftime(time,"%F %T")
| rex field=date "(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) (?<hour>\d{2}):(?<min>\d{2}):(?<sec>\d{2})"
| dedup year
| eval mod_date=strftime(time,"%j")
| eval time=if(day="01",time,time - (mod_date -1)  * 24 * 60 * 60)
| eval date=strftime(time,"%F %T")
| sort 83 - date
| table date    day hour    min mod_date    month   sec time    year
| append [| makeresults count=2
| streamstats count
| eval time=if(count=1,0,-62167252739)
| makecontinuous span=31536000 time
| eval date=strftime(time,"%F %T")
| rex field=date "(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) (?<hour>\d{2}):(?<min>\d{2}):(?<sec>\d{2})"
| dedup year
| eval mod_date=strftime(time,"%j")
| eval time=if(day="01",time,time - (mod_date -1)  * 24 * 60 * 60)
| eval date=strftime(time,"%F %T")]
| sort date
| where sec="00"
| table date time

結論ありきで作ってみたらこんな感じ。内部的にはめちゃくちゃだと思う。

まとめ

一応動的に現在の環境の変数から導きだしているので、たまたまSplunk環境が日本時間じゃなかったとしても使えるはず。


12/9 props.confで変える を追加
12/26 1970年より前でも欲しい を追加
2/8 epochの限界、1970前でもUTCが欲しいver2 を追加
7/24/2020 追記 を追加

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3