OSX(Darwin)環境下でGNU Dateを使わずにmillisecondsを含めたunixtimeを出力する方法を模索してみた
はじめに
millisesondsを含めたunixtimeを使うケースはそれほど頻繁でもないのですが、そのタイミングになった時に案外計算方法に手を焼かされます。aws-cliを使った場合だと、aws logs create-export-task
の引数(--from, --to)等があります。
Linux環境では date コマンドを使って対処できますが、同じ感覚のままMac上で使おうとすると恐らく以下の出力になるはずです。
% date -d "-30days" +%s%N | xargs -I{} expr {} / 1000000 usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format] # Linux環境では…… % date -d "-30days" +%s%N | xargs -I{} expr {} / 1000000 1581301639622
HomeBrew経由でGNU Dateを入れるという方法もありますが、環境によってまちまちになることもあり、標準で備わっているライブラリを使って実行できる前提にて確認してみました。
実行する前提
ターミナル上にて、或いはシェルスクリプトの2択とします。millisecondsを含めたunixtimeで、aws logs create-export-task
の --from と --to に渡せる形とします。
各言語での実行
Python
Python3で動かせる前提としています。Pythonが最初から入っているDockerイメージ等でも利用可能なはずです。開始対象範囲を変更したい場合はdatetime.timedelta()
に指定した 30 を求めたい値に変更します。
# from echo $(python -c "import datetime;print(int((datetime.datetime.now() - datetime.timedelta(30)).timestamp() * 1000))") # to echo $(python -c "import time;print(int(time.time() * 1000))")
Ruby
Time.now.to_i
では10桁までの出力となります。30日前の日付取得にはactivesupportを利用しています。
gem install activesupport # from echo $(ruby -e "require 'active_support/all';print 30.days.ago.strftime('%s%L').to_i") # to echo $(ruby -e "print Time.now.strftime('%s%L').to_i")
php
途中で計算と変換が面倒になり、今回はmicrotime()
に足し引きする形としました。
# from echo $(php -r 'echo ceil(microtime(true)*1000 - (60*60*24*30*1000));') # to echo $(php -r 'echo ceil(microtime(true)*1000);')
JavaScript
インタプリタ言語だけどできるのかなと思いましたが、node.jsで出来ました。
# from echo $(node -e "console.log(new Date().setDate(new Date().getDate() - 30));") # to echo $(node -e "console.log(new Date().setDate(new Date().getDate()));")
なお、Mac限定ですが以下のようなやり方もあります。以下の記事にて知りました。
# from echo $(/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc -e 'print(new Date().setDate(new Date().getDate() - 30));') # to echo $(/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc -e 'print(new Date().setDate(new Date().getDate()));')
date
gdateではない、Mac標準のものです。millisecondは取れないので0埋めしています。Linux環境下で使うスクリプトに入れる場合はuname
等で判定して分岐させる必要があります。
# from echo $(date -v-30d +%s000) # to echo $(date +%s000)
あとがき
当初はgdateを使って書いていましたが、何も入れない状態でも動くようにしたいなと思った結果、今回の記事のきっかけとなりました。個人的にはNode.jsが一番すっきりしているという感想です。
普段滅多に行わないけど、やるとなると意外に悩まされる計算でもあり、良い振り返りになりました。参考になれば幸いです。