Help us understand the problem. What is going on with this article?

ツイートIDからツイート時刻をミリ秒まで算出(ついでに時刻からツイートIDを作成)

More than 3 years have passed since last update.

ツイートIDの算出

TwitterのID算出には snowflake というツールが用いられて いました (2014/5 に今後更新しない旨が GitHub のレポジトリの README に記載されています)。ただし現状もこの算出方法に基づいて ID が生成されている はず です。
twitter/snowflake
このツールの解説がありましたので、IDに付いての解説部分を引用します。

snowflakeではlong値(64bit)としてIDを表現します。実際は、unsigned long / signed long いずれの環境でも特に細工なく使用できるようにするためか、63bitの範囲で表現しているようです。
bit layoutは以下。
timestamp: 41bit / machine id: 10bit / sequence: 12bit

  • timestamp(41bit) : 現在のunixtime(milliseconds)から、ある時点のunixtimeを引いた値
  • machine id(10bit) : 生成器ごとに割り当てられたID
  • sequence(12bit) : 生成器ごとに採番するsequence番号

ざっくり言うと、全体としての一意性はtimestampとmachine idで担保し、生成器内での一意性はsequenceで担保している、という設計になってます。
(中略)
snowflakeでは以下抜粋したコードで示すように現在日時から1288834974657を引いた値を扱っています。

軽量なTime-based ID生成器”shakeflake(仮称)”について | SmartNews開発者ブログ

その他の解説

ツイートIDから時刻を算出するtweet_id2timeメソッド

ツイートIDの算出を逆に演算すれば時刻を算出できます。
手順としては

  1. IDからtimestamp部分のみを切り出す。
    下の22bitを落とします。すると、基準時刻からの現在時刻(ミリ秒)が求められます。
  2. 差っ引かれていた値を加算。
    1288834974657(ミリ秒)を足してやります。
  3. 秒に直すために1000.0で割ります。
    なお、1000で割ると整数演算になるのでミリ秒部分が落とされてしまいます。
def tweet_id2time(id)
  Time.at(((id.to_i >> 22) + 1288834974657) / 1000.0)
end

引数idのクラスをチェックするバージョン

def tweet_id2time(id)
  case id
  when Integer
    Time.at(((id >> 22) + 1288834974657) / 1000.0)
  else
    nil
  end
end

実例

次のツイートの時刻を算出してみます。



このツイートのIDは481064722297397249です。
tweet_id2time(481064722297397249).strftime("%Y-%m-%d %H:%M:%S.%L %Z")
#=> "2014-06-23 22:22:22.203 JST"

ミリ秒はTime#strftime("%L")で表示できます。

時刻から疑似ツイートIDを作成するtime2tweet_idメソッド

疑似ツイートIDであり、正確に言うと ミリ秒単位にみた同一時刻におけるツイートIDの下限値 です。

def time2tweet_id(time)
  (time.to_f * 1000 - 1288834974657).to_i << 22
end

この疑似ツイートIDはTwitter gemのメソッドの引数に使う:since_idの値の初期値として使うことが出来ます。メソッドとしては例えばTwitter::REST::Search#search, Twitter::REST::Timelines#home_timeline, Twitter::REST::Timelines#user_timelineなどが挙げられます。

疑似ツイートIDと時刻との関係

ちなみに疑似ツイートIDtime2tweet_id(time)と時刻timeとの関係は
time2tweet_id(time) $≦$ id $<$ time2tweet_id(time+0.001) $=$ time2tweet_id(time) + (1<<22)
を満たします(なお1<<222**22であり4194304)。

確認してみましょう。先ほどのツイートのID 481064722297397249 を使ってみます。tweet_id2timeメソッドを使うと、先ほどのツイートの時刻はtweet_id2time(481064722297397249)になります。

id = 481064722297397249
time2tweet_id(tweet_id2time(id)) <= id
#=> true
id < time2tweet_id(tweet_id2time(id) + 0.001)
#=> true
time2tweet_id(tweet_id2time(id) + 0.001) == (time2tweet_id(tweet_id2time(id)) + (1<<22))
#=> true

先ほどの関係式が確かに成り立っています。

関連

TwitterのステータスIDからつぶやかれた時刻を抽出する方法 - Qiita

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした