質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

解決済

2回答

2285閲覧

日時情報(年月日時分秒)をできるだけ少ない文字数で表現したい

marururu

総合スコア23

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

1グッド

2クリップ

投稿2021/09/30 08:04

編集2022/03/30 02:33

前提・実現したいこと

タイムスタンプを持つとあるデータに対する「時刻情報+その他情報」による複合キーを、「できるだけ少ない文字数」かつ「どのデータでも同じ文字数」でも表現したいと考えています。
ここで、特に「時刻情報」に関して、何某かの知恵をお借りしたいと思い投稿しました。

つまり、よくある「yyyy-mm-dd HH:MM:SS」というタイムスタンプから得られる情報をを、できるだけ少ない文字数で表現したいです。

例:「yyyy-mm-dd HH:MM:SS(19文字)」→「yyyymmddHHMMSS(14文字)」

ただ、検索してもあまり情報がなく、自分だけの考察では手一杯な感触を得ています。
そこで、なにか方法がないかお聞きしたく、投稿させていただきました。

※検索しても出てこない=そもそもそんなこと考えずに別の方法を考えるべきだという啓示な気もしますが…

試したこと

日時情報を、UNIX秒に変換する方法と、変換したUNIX秒をn進数に変換する方法を思いつきました。
※n進数の変換は、一般に用意されるようなアルゴリズムではないと思っているため、別途何某か変換用のスクリプトを組む必要があると思っています。
※36進数=0~9,A~Zまでの36文字、62進数=0~9、a~z、A~Zの62文字、94進数=ASCII文字33番(0x21)[!]~126番(0x7e)[~]までの94文字と想定しています
※「データの圧縮」というキーワードから連想し、「可逆圧縮アルゴリズム(ランレングス符号、ハフマン符号、LZ77、LZSS、LZW、Deflateなど)」が使えないかと調べたこともあるのですが、たかだか14文字の数字データを圧縮するような話とは別では…?と思ってしまい、深くは調査しませんでした。

概要桁数表示データ範囲
そのまま表記14桁2021/09/30 05:16:049999年以上
UNIX秒10桁16329789649,999,999,999(10進数10桁)→'2286-11-21 02:46:39'
UNIX秒を16進数変換8桁615548140xFFFFFFFF(16進数8桁)→4,294,967,295(UNIX秒)→2106-02-07 15:28:15
UNIX秒を36進数変換6桁R08EMSzzzzzz(36進数)→2038-12-24 05:45:35
UNIX秒を62進数変換6桁1MvOqoZZZZZZ(62進数)→56,800,235,583(10進数)→3769-12-05 03:13:03
UNIX秒を94進数変換5桁7o1RY~~~~~~(94進数)→7,339,040,223(10進数)→2202-07-26 14:17:03

お聞きしたいこと

以下の2点についてお聞きしたいです。

  1. 上記アプローチが、あまりにも突拍子のない、変な方法なのかどうか?
  2. 他に考えられる方法はないか?

おかしな質問かもしれませんが、、何卒よろしくおねがいします。

追加検討した結果

UNIX秒をオフセットする

UNIX秒は1970/1/1からの経過秒数なので、固定値でオフセットし、2020/1/1からの経過秒数にしてみる。
→表示できる範囲が50年分だけ後ろにオフセットされる。ただし、"桁数"の観点からからいうと、表示できる範囲が変わるわけではないので、長いスパンで考えると大差なく、桁数を削減できるほどの効果は得られないと思われる。

0秒='1970/1/1'を基準にした場合(通常) → 0秒='2020/1/1'を基準にし直した場合(工夫あり)

桁数unix秒(開始)unix秒(終了)表現できる範囲(開始)表現できる範囲(終了)50年分オフセットした場合(終了)
1091970/01/01 00:00:001970/01/01 00:00:092020/01/01 00:00:09
20991970/01/01 00:00:001970/01/01 00:01:392020/01/01 00:01:39
309991970/01/01 00:00:001970/01/01 00:16:392020/01/01 00:16:39
4099991970/01/01 00:00:001970/01/01 02:46:392020/01/01 02:46:39
50999991970/01/01 00:00:001970/01/02 03:46:392020/01/02 03:46:39
609999991970/01/01 00:00:001970/01/12 13:46:392020/01/12 13:46:39
7099999991970/01/01 00:00:001970/04/26 17:46:392020/04/25 17:46:39
80999999991970/01/01 00:00:001973/03/03 09:46:392023/03/03 09:46:39
909999999991970/01/01 00:00:002001/09/09 01:46:392051/09/09 01:46:39
10099999999991970/01/01 00:00:002286/11/20 17:46:392336/11/20 17:46:39

base64で変換する

元のバイナリデータを、アルファベットの小文字(a~zの26文字)とアルファベットの大文字(A~Zの26文字)と数字0~9(の10文字)と「+」と「/」の計64文字を用いた文字列でエンコードするものです。上述で投稿者が勝手に考えた基数変換とは微妙に異なるものだと思っています。
使い方としては、「UNIX秒」を「整数型」としていったん「バイナリ」に変換し、base64のルールに則って、「6bitずつ文字列にエンコード」する感じです。
エンコード結果は4文字区切りでないといけないので、4文字or8文字or12文字…となります。
「64文字x8桁」の表現ができれば、281,474,976,710,656(281兆通り)の情報量を持つことができるので、もしミリ秒UNIX秒にしても事足りそうな気がします。

退会済みユーザー👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ppaul

2021/09/30 16:39

ASCII文字33番(0x21)[!]~126番(0x7e)[~]までは94文字なのではないでしょうか。
marururu

2021/10/01 02:14

ごめんなさい数え間違えてました、、修正しておきます
guest

回答2

0

ベストアンサー

できるだけ短くしたいという意図の背景が分からないので
あまり凝った意見はできませんが、自分なりの見解を回答いたします。

単純に時刻を短い文字列で表すのであれば、UNIX秒の基数変換が最も妥当だと考えます。
これ以上は文字列表現が厳しいバイナリ化しないと無理かと。
ですが、短くしたい目的としてユニークキーの一部に使うためとなると、
そもそも短くする必要があるのか?と思ってしまいます。

想像ですが、データを検索する際にそのユニークキーの時刻部分だけに焦点を当てて絞り込む必要があったりするのでしょうか?
もしそうだとしたら、ユニークキーに取り込んでしまうのは処理的に非効率な方法だと思いますので、
時刻部分は独立した検索可能な値としてデータに付随させるのが定石であると考えます。

やはりユニーク値というと、一般的にはハッシュ値(ダイジェスト値)が良く用いられるかと思います。
それに、ハッシュ値の計算に使う入力値の一部に時刻情報などを組み込んでユニークにする方法もよく見かけます。
この方法であればユニーク値全体での文字数が固定できます。

投稿2021/09/30 11:04

surface_0

総合スコア497

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

marururu

2021/09/30 11:52

ご回答ありがとうございます。 質問の意図について言葉足らずで申し訳ありません…。 「ユニークキーとして使いたい」というよりは、「日時情報を含む複合キーを、短い文字列でも表現したい」というほうが正しいかも知れません。 そのため、時刻情報は時刻情報できちんとデータとして持っておく形を想像しています。 というのも、この変換したデータを「QRコードかDataMatrixにしてこのデータを打ち込みたい」と思っています。 文字数が少なければ、セルの数を減らせるので、同じシンボルサイズで印刷したときに、スキャナで読み込んだときの認識率を上げることができると考えています。 と、いったところで考えていたところ「unix秒の基数変換」という思考に落ち着いてしまい、いやいやまてまて他に方法ないのか…と思い投稿した次第です。
surface_0

2021/09/30 15:48

なるほど、てっきりデータベースの事かと思いました。 であればユニークかどうかは論点にあまり関係無い感じですね。 そう考えると固定長だとやはり基数変換かなとは思います。 可逆圧縮の類は時刻だけを圧縮しようとすると、オーバーヘッドの方が大きくなってしまうので逆効果だと思います。 とはいえ、セルのサイズを気にするほどとなると、時刻など全体に対して大したデータ量では無いのでは?と思うのですが。 もしかして一つのシンボルに時刻をたくさん詰め込む感じですか?
marururu

2021/10/01 02:32

シンボルに含めるデータとして、多くても全体で20文字程度を想定しており、埋め込む時刻データは1つです(時刻+その他の情報)。 今回シンボルを印刷および読取りする条件に制約があり(きれいなインクジェット紙にレーザープリンターでバッチシ印刷してオフィスで読み取る、とかではない)、できるだけシンプルなシンボルにしなければならないというニーズがありました。ご参考までに。。
surface_0

2021/10/01 03:49

かなり厳しい条件ですね。 一応思いつくアイディアを追加で挙げておきます。 内容をパターン化できるのであれば、それを辞書化してシンボルのパターンで表現したり、あるいは番号を充てたりということができると思います。 あとは、もしシンボルの情報だけで完結する必要が無く、別途のデータベースと連携ができるのであれば、 シンボルには適当なユニークキーだけを入れておき、そのキーを使ってデータベースから内容を参照するというのが、いわゆるバーコードのPOSレジとかと同じような仕組みですね。
guest

0

UNIX秒は1970年の通算秒なので、これを2020年(あたり?)からの通算秒に換算してしまえば文字数やデータ量は削減できますよ

投稿2021/09/30 08:07

y_waiwai

総合スコア87800

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

marururu

2021/09/30 08:49 編集

ご回答ありがとうございます。確かに適当に数値をオフセットしてやれば削減できそうだ、と思い、さらに考察してみました。が、「文字数」の観点から検討すると、あまり効果は無いように思いました。。 ※回答部分ではMarkdownにならないので、質問文側に追加検討の内容を追記させていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問