SyntaxHighlighter

---SyntaxHighlighter ウィジェット---

2015年12月6日日曜日

FlashAirのLuaスクリプトで得たファイル更新時間を文字列に直す

FlashAirデベロッパーフォーラムで「ファイルの更新日時を取得したい」という話があった。
どうせUNIX時間か何かだろう、と思ったが、試してみるとハマったので書いておく。

FlashAirに搭載されたLuaFileSystemライブラリからファイルの更新時間を
取得する(
lfs.attributes→modification)謎の数値が帰ってくる。例えば、1199991528など。

UNIX時間かな?と思い、変換してみると、今さっき作ったファイルなのに
2008/01/11 03:58:48とかになってしまう。

日付がおかしいのならともかく、時間単位でも合わない。

UNIX時間との差をとっても、次のファイルはまたおかしな値になる。

さっき作ったファイルと、今作ったファイルの値を比較してみても、秒単位ではないなにかで

数値が増えていることがわかる。単純に二倍や1\2でもない。

そう、これは秒数ではない。

では正体は何かというと、FATの時間情報そのものだ。
形式は以下。

01000111100001100110101011101000
YYYYYYYMMMMDDDDDHHHHHMMMMMMSSSSS

FATファイル システムのしくみと操作法 - ELM
http://elm-chan.org/docs/fat.html
こちらのサイトで言うところの、

DIR_WrtDateとDIR_WrtTimeの各16bitを結合した32bitのバイナリ情報だ。

ということで、これらを変換して、人間に読める形式に変換するスクリプトを書いた。

Lua5.2にビット演算機能が実装されていて本当に良かったと思った。

ライセンスはWTFPLなので、自由に使って欲しい。


--FAT形式のファイルアクセス時間を分解する
function GetFileModificationTime(Fat_binary_time)
   Year = bit32.band (bit32.rshift(Fat_binary_time, 9+16),0x7F) + 1980
   Month = bit32.band (bit32.rshift(Fat_binary_time, 5+16),0x0F)
   Day = bit32.band (bit32.rshift(Fat_binary_time,0+16),0x1F)

   Hour = bit32.band (bit32.rshift(Fat_binary_time, 11),0x1F)

   min = bit32.band (bit32.rshift(Fat_binary_time, 5),0x3F)
   sec = bit32.band (Fat_binary_time,0x1F)*2; --FAT時間は秒数が2秒刻み

   return Year,Month,Day,Hour,min,sec

end

--yyyymmdd_hhmmss.jpgを生成する

function TimeToFileName(Year,Month,Day,Hour,min,sec)
   return string.format("%04d%02d%02d_%02d%02d%02d.jpg",Year,Month,Day,Hour,min,sec)
end

-------------------サンプル----------------------

--Hello.txtの更新時間を取得する
a = lfs.attributes("Hello.txt")

--文字列で得る

Year,Month,Day,Hour,min,sec = GetFileModificationTime(a.modification)
print(Year.."年"..Month.."月"..Day.."日"..Hour.."時"..min.."分"..sec.."秒")

--文字列で得たものをファイル名形式にする

print(TimeToFileName(GetFileModificationTime(a.modification)))

2 件のコメント:

  1. はじめまして、相模原市に住んでいる中学生の母親です。大変ぶしつけな質問とはおもいますが、教えていただきたいことがあります。
    テクノロジあでセンサーを購入したら NXTでは作動するのにEV3のレスキューにとりつけると 動作しません。
    中距離センサー DIST-Nx=Medium-V3 8208円のセンサーです。
    テクノロジあさんは マインドセンサーなどのHPを見るかメールで問い合わせたら?というのですが、わたくしも息子も 知識が乏しくて
    なにを質問してもいいかわからないし、
    なにか お知恵を拝借できたらと、コメント欄にかかせていただきました。
    ・・・どうかヒントだけでも教えていただけたら・・・・お願いいたします!!お詳しそうだったので!!

    返信削除
    返信
    1. 本来この記事で扱うコメントではないのですが、お困りのようなので対応します。

      私は持っていませんが、DIST-Nx=Medium-V3は、NXTで動く距離センサーのようですね。
      TechnologiaではNXT専用のセンサーとして販売されているため、EV3は対応外なのでしょう。
      ...と言いたいところなのですが、mindsensorsの公式サイトではNXTとEV3の両対応となっているようです。

      http://www.mindsensors.com/ev3-and-nxt/112-high-precision-medium-range-infrared-distance-sensor-for-nxt-or-ev3
      こちらのサイトの
      MORE INFO
      REVIEWS
      RELATED INFORMATION
      VIDEO
      DOWNLOAD
      と並んでいる「DOWNLOAD」のボタンを押すと、色々とダウンロードボタンが出てきますので、

      まず「DIST-Nx-v3 EV3 Block」をダウンロードし、ブロックのインポートを行ってください。
      (EV3ソフトを起動して「ツール」→「ブロック インポートウィザード」
      英語ですがやり方はここにあります。http://www.mindsensors.com/content/13-how-to-install-blocks-in-ev3 )

      その後、「DIST-Nx-v3 EV3 Sample」をダウンロードし、EV3のソフトで読み込んでみてください。
      センサーから一定範囲内に物があるかどうかを調べるサンプルが読み込まれます。
      また、サンプルではスイッチ動作ですが、センサータブに追加されたブロックを確認すると、
      距離を数値で得るブロックなども追加されているはずです。

      センサーについての詳細説明は、「DISTNx - User Guide Sharp Sensor」をダウンロードした中身に入っています。

      私が答えられるのは以上です。
      参考になりましたでしょうか。

      削除