LoginSignup
19
9

More than 5 years have passed since last update.

(Tips)これから100年のunix時間は10桁数字。5桁の固定長文字列でも表現できる。

Last updated at Posted at 2018-03-25

Unixtimeの時刻表現

多くのエンジニアがご存知であろうUNIX時間(ユニックスじかん、UNIX time)。
wikipediaには以下のように書かれている(抜粋)。

UNIX時間(UNIX time)とはコンピューターシステム上での時刻表現の一種。UNIXエポック、すなわち協定世界時 (UTC) での1970年1月1日午前0時0分0秒から形式的な経過秒数(すなわち、実質的な経過秒数から、その間に挿入された閏秒を引き、削除された閏秒を加えたもの)として表される。

UNIX timeは、うるう年、ローカルタイム、サマータイムなどの扱いが必要ないシンプルな時刻表現だ(うるう秒の扱いはちょっと面倒なのかもしれないが)。
時系列の時刻管理が必要なツールを作る際に、とりあえずUnix timeにしておけば秒単位での順序付けが行える。

21世紀ののUnix時間はほぼ10桁で表せる

普段目にするUnix時間の桁数は大抵10桁だ。

Unix時間 対応する時刻(JST)
1017378540 2002-03-29 14:09:00+09:00
1490418540 2017-03-25 14:09:00+09:00
4107906540 2100-03-05 14:09:00+09:00

python3では以下のようなコードでUnix時間と対応する時刻を計算できる。

現在時刻.py
from datetime import datetime, timezone, timedelta

JST = timezone(timedelta(hours=+9), 'JST')

now = int(datetime.now().timestamp())
now_loc = datetime.fromtimestamp(now, JST)
print("Unix時間 対応する時刻(JST)")
print(now, now_loc)

20世紀のUnix時間は9桁以下、21世紀や22世紀のUnix時間はだいたい10桁ということはTipsとして、知っておいてもいいだろう。

上1桁が5になるのは100年ちょっとあと(カンマ区切りを入れた)。

5,022,450,540 2129-02-26 14:09:00+09:00
2001年から計算してみると30年ちょっとに一回上1桁が大きくなっていくらしい。

BASE91に変換してみる。

さて、10桁固定で比較もできて便利なUnix時間であるが、可読性は低い。
どうせ可読性が低いならば、BASEエンコードしてしまって、桁数を減らしてデータベースに格納してしまっても良いのではと思ったので実験してみた。

元にしたのは以下の文字を使うBASE91:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~"

以前のエントリー『python+redisで、Base91のキーを扱う。』 で
redisがBase91の文字列を扱えることは確認済なので、redisのキーの一部にBASE91ベースのUnix時間を突っ込むイメージ。
例えば請求を種別に管理する場合

請求種別A-XXXXX

とキーの末尾が時刻表現となるイメージ

base91ではいろんな記号が使われちゃっているけれども、マイナス(-)は使われてないので、マイナスを区切り文字に使うと良い。(base91関連の情報は以下に)
http://base91.sourceforge.net/

ということで、以下のような書捨てコードで検証してみた:

unixtime2base91.py
from datetime import datetime, timezone, timedelta

base90 ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~"
base91=base90 + '"'

LEN = len(base91)
#base91表現のUnixtimeを取得
def get91(time, LEN=91):
    if time < LEN:
        return base91[time]
    str=""
    q=time
    while (q >= LEN ):
        q, mod = divmod(q,LEN)
        str += base91[mod]
    #print(q,mod, end=':')
    return (str + base91[q])[::-1] #反転する

#base91表現のUnixtimeを数値に戻す
def melt91(str, LEN=91):
    time=0
    lst = [base91.find(char) for char in str][::-1] #反転する
    for i, L in enumerate(lst):
       power = pow(LEN,i)
       time += L*power
    return time

JST = timezone(timedelta(hours=+9), 'JST')
now = int(datetime.now().timestamp())
now_loc = datetime.fromtimestamp(now, JST)
ft = now
str ="XXXXX"

print(f"######## before {now_loc}###########")
while (len(str) > 4):
    ft -=(60*60 *24 * 365)
    loc = datetime.fromtimestamp(ft, JST)
    str=get91(ft)
    print(str,ft,melt91(str),loc) 
print(f"######## after {now_loc}###########")
ft = now
while (len(str) < 6):
    ft +=(60*60 *24 * 365)
    loc = datetime.fromtimestamp(ft, JST)
    str=get91(ft)
    print(str,ft,melt91(str),loc) 


base91表現のUnixtimeはけっこう長い期間5桁で表せる。

結果。どうやらbase91表現のUnixtimeは、1972年から2167年の間は5桁で表せる模様。
桁数を減らすことが目的で可読性は期待していなかったけど、上1桁の文字が2年ちょいは変わらないので
大体の年はひと目で分かりそうでちょっと良さげ
(例 2020年と2021年のbase91表現のUnixtimeは「X」ではじまる)。

######## before 2018-03-25 15:16:32+09:00###########
V&/"W 1490422592 1490422592 2017-03-25 15:16:32+09:00
VY|). 1458886592 1458886592 2016-03-25 15:16:32+09:00
U:Kvf 1427350592 1427350592 2015-03-26 15:16:32+09:00
UgYZ[ 1395814592 1395814592 2014-03-26 15:16:32+09:00
T[mEo 1364278592 1364278592 2013-03-26 15:16:32+09:00
(中略)
C@Bd+ 197446592 197446592 1976-04-04 15:16:32+09:00
CmPId 165910592 165910592 1975-04-05 15:16:32+09:00
B|c=? 134374592 134374592 1974-04-05 15:16:32+09:00
Btq4m 102838592 102838592 1973-04-05 15:16:32+09:00
BD4i} 71302592 71302592 1972-04-05 15:16:32+09:00
0+Nv 39766592 39766592 1971-04-06 15:16:32+09:00

######## after 2018-03-25 15:16:32+09:00###########
W7uqN 1553494592 1553494592 2019-03-25 15:16:32+09:00
XKg#2 1585030592 1585030592 2020-03-24 15:16:32+09:00
X0S`E 1616566592 1616566592 2021-03-24 15:16:32+09:00
YDFPt 1648102592 1648102592 2022-03-24 15:16:32+09:00
Ys]k{ 1679638592 1679638592 2023-03-24 15:16:32+09:00
Y{)6k 1711174592 1711174592 2024-03-23 15:16:32+09:00
Zl2?= 1742710592 1742710592 2025-03-23 15:16:32+09:00
Z?pKb 1774246592 1774246592 2026-03-23 15:16:32+09:00
aebf) 1805782592 1805782592 2027-03-23 15:16:32+09:00
a.N1S 1837318592 1837318592 2028-03-22 15:16:32+09:00
bW":7 1868854592 1868854592 2029-03-22 15:16:32+09:00
b$=FJ 1900390592 1900390592 2030-03-22 15:16:32+09:00
cP#ay 1931926592 1931926592 2031-03-22 15:16:32+09:00
c5xwA 1963462592 1963462592 2032-03-21 15:16:32+09:00
dIj*p 1994998592 1994998592 2033-03-21 15:16:32+09:00
dyV"] 2026534592 2026534592 2034-03-21 15:16:32+09:00
eBIVg 2058070592 2058070592 2035-03-21 15:16:32+09:00
eq`q/ 2089606592 2089606592 2036-03-20 15:16:32+09:00
e_,$X 2121142592 2121142592 2037-03-20 15:16:32+09:00
fj5`$ 2152678592 2152678592 2038-03-20 15:16:32+09:00
f=sQO 2184214592 2184214592 2039-03-20 15:16:32+09:00
gcel3 2215750592 2215750592 2040-03-19 15:16:32+09:00
g+Q7F 2247286592 2247286592 2041-03-19 15:16:32+09:00
hVC@u 2278822592 2278822592 2042-03-19 15:16:32+09:00
h!@K| 2310358592 2310358592 2043-03-19 15:16:32+09:00
iN&gl 2341894592 2341894592 2044-03-18 15:16:32+09:00
i301> 2373430592 2373430592 2045-03-18 15:16:32+09:00
  (中略)
}l@P0 6063142592 6063142592 2162-02-18 15:16:32+09:00
}?&lC 6094678592 6094678592 2163-02-18 15:16:32+09:00
~e06r 6126214592 6126214592 2164-02-18 15:16:32+09:00
~.m?_ 6157750592 6157750592 2165-02-17 15:16:32+09:00
"XZKi 6189286592 6189286592 2166-02-17 15:16:32+09:00
"%Lf; 6220822592 6220822592 2167-02-17 15:16:32+09:00
BAP}1Z 6252358592 6252358592 2168-02-17 15:16:32+09:00

以上、Tipsまで。

19
9
3

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
19
9