Qiitaにログインして、便利な機能を使ってみませんか?

あなたにマッチした記事をお届けします

便利な情報をあとから読み返せます

3
2

記事を削除する

一度削除した記事は復旧できません。

この記事の編集中の下書きも削除されます。

削除してよろしいですか?

この記事は最終更新日から3年以上が経過しています。

MixJuiceで現在の日時を取得する

3
投稿日

何をするか?

MixJuice経由でWeb APIを利用し、IchigoJamから現在の日時を取得します。

現在の日時を取得するWeb API

現在の日時を取得するWeb APIを探したところ、以下のものが見つかりました。

日本標準時プロジェクト

日本標準時プロジェクト https/http を介してアクセスされる場合

現在時刻を時分秒形式で返すAPIが定義されています。

https://ntp-a1.nict.go.jp/cgi-bin/time

以下のような形式で現在時刻が取得できる仕様です。

Sat Jun  5 03:53:33 2021 JST

月が数字ではなく英字列なのが気になりますが、余計なデータが無く扱いやすそうな仕様!

さらに、ヘッダはAccess-Control-Allow-Origin:*を含み、HTTPSにも対応する仕様となっています。
IchigoJam webのバーチャルMixJuice対応もバッチリな仕様!

…しかし、毎月6日~月末はサービス停止、
2022年3月31日をもって完全にサービス終了となっており、使い物になりません。
入出力の仕様が素晴らしいだけに、非常に残念!!

IchigoJam + MixJuice用 日付&時間データ

IchigoJam + MixJuice用 日付&時間データ

以下のURLで日本の現在時刻を取得できます。

http://www.openspc2.org/data/date/full.txt

以下のような形式の結果が返ります。

2021
12
14
2
0
23

秒の情報は取得できないようですが、「MixJuice用」と銘打っているだけあって形式のシンプルさは最高です。
しかし、ヘッダにAccess-Control-Allow-Originが含まれておらず、
HTTPSにも対応していない(接続できない)ので、IchigoJam webのバーチャルMixJuiceからのアクセスは難しそうです。

World Time API

World Time API: Simple JSON/plain-text API to obtain the current time in, and related data about, a timezone.

以下のURLで日本の現在時刻を取得できます。

https://worldtimeapi.org/api/timezone/Asia/Tokyo

また、アクセス元のIPアドレスに基づくタイムゾーンの自動選択もできます。

https://worldtimeapi.org/api/ip

以下のような形式の結果が返ります。

{"abbreviation":"JST","client_ip":"35.199.178.127","datetime":"2021-12-14T00:12:43.579568+09:00","day_of_week":2,"day_of_year":348,"dst":false,"dst_from":null,"dst_offset":0,"dst_until":null,"raw_offset":32400,"timezone":"Asia/Tokyo","unixtime":1639408363,"utc_datetime":"2021-12-13T15:12:43.579568+00:00","utc_offset":"+09:00","week_number":50}

見やすく整形すると、以下のようになります。

{
	"abbreviation": "JST",
	"client_ip": "35.199.178.127",
	"datetime": "2021-12-14T00:12:43.579568+09:00",
	"day_of_week": 2,
	"day_of_year": 348,
	"dst": false,
	"dst_from": null,
	"dst_offset": 0,
	"dst_until": null,
	"raw_offset": 32400,
	"timezone": "Asia/Tokyo",
	"unixtime": 1639408363,
	"utc_datetime": "2021-12-13T15:12:43.579568+00:00",
	"utc_offset": "+09:00",
	"week_number": 50
}

HTTPSでのアクセスに対応しており、ヘッダにaccess-control-allow-origin: *が含まれるため、
IchigoJam webのバーチャルMixJuiceからのアクセスもしやすいです。

ただし、単純に時刻を取得するためだけに使うには結果が長いです。
結果をJSONではなくプレーンテキストで返すモードもありますが、結果の長さはあまり変わりませんでした。

TimeAPI

Simple and Free Time API | TimeAPI

以下のURLで日本の現在時刻を取得できます。

https://www.timeapi.io/api/Time/current/zone?timeZone=Asia/Tokyo

以下のような形式の結果が返ります。

{"year":2021,"month":12,"day":13,"hour":23,"minute":51,"seconds":12,"milliSeconds":388,"dateTime":"2021-12-13T23:51:12.3888497","date":"12/13/2021","time":"23:51","timeZone":"Asia/Tokyo","dayOfWeek":"Monday","dstActive":false}

見やすく整形すると、以下のようになります。

{
	"year": 2021,
	"month": 12,
	"day": 13,
	"hour": 23,
	"minute": 51,
	"seconds": 12,
	"milliSeconds": 388,
	"dateTime": "2021-12-13T23:51:12.3888497",
	"date": "12/13/2021",
	"time": "23:51",
	"timeZone": "Asia/Tokyo",
	"dayOfWeek": "Monday",
	"dstActive": false
}

HTTPSには対応していますが、Access-Control-Allow-Originヘッダは入っておらず、
IchigoJam webのバーチャルMixJuiceでの利用は若干面倒かもしれません。
(CORS Everywhereなどの拡張機能を用いればアクセスは可能です)

World Clock API

Home Page

以下のURLでUTCの現在時刻(日本時間の9時間前)が取得できます。

http://worldclockapi.com/api/json/utc/now

以下のような形式の結果が返ります。

{"$id":"1","currentDateTime":"2021-12-13T15:30Z","utcOffset":"00:00:00","isDayLightSavingsTime":false,"dayOfTheWeek":"Monday","timeZoneName":"UTC","currentFileTime":132838830284824919,"ordinalDate":"2021-347","serviceResponse":null}

見やすく整形すると、以下のようになります。

{
	"$id": "1",
	"currentDateTime": "2021-12-13T15:30Z",
	"utcOffset": "00:00:00",
	"isDayLightSavingsTime": false,
	"dayOfTheWeek": "Monday",
	"timeZoneName": "UTC",
	"currentFileTime": 132838830284824910,
	"ordinalDate": "2021-347",
	"serviceResponse": null
}

ただし、日本時間の直接取得には対応していないようです。
(utcの代わりにjstすべてのタイムゾーンでの現在の時間に載っている他のUTC+9のタイムゾーンの名前を入れると、無効なタイムゾーン(not a valid Time Zone)としてエラーになりました)
また、秒単位の時刻の取得も簡単にはできないようです。
(CyberChefを用いるcurrentFileTimeから秒単位の時刻を取り出せるので、不可能ではないと思われます)

さらに、HTTPSへの対応が不完全(接続は出来るが証明書の名前が無効)であり、
ヘッダにAccess-Control-Allow-Originが含まれないため、
IchigoJam webのバーチャルMixJuiceからのアクセスは難しそうです。

まとめ

API HTTPS対応 CORS対応 結果のシンプルさ 日本時間対応 秒単位対応 時間の制約無くアクセス可能
日本標準時プロジェクト ×
IchigoJam + MixJuice用 日付&時間データ × × ×
World Time API ×
TimeAPI × ×
World Clock API × × × ×

(ヘッダがAccess-Control-Allow-Origin:*を含むことを「CORS対応」としています)

現在の日時を取得する

方針

今回は、IchigoJam webのバーチャルMixJuiceからのアクセスがしやすく、
利用時間の制限も無い World Time API を用いて現在の日時を取得することにしました。
取得する形式は、データの終わりが}で明示されるためわかりやすいJSONを用いることにしました。

返されるデータのうち、"datetime":"2021-12-14T00:12:43.579568+09:00",の部分に日時の情報が、
"day_of_week":2,の部分に曜日の情報が入っているので、これらから情報を抜き出します。

今回扱うJSONのデータでは、オブジェクトのネストが無く、
データの文字列にカンマやエスケープ、閉じカッコは含まれていないようです。
そこで、この性質を利用し、以下のようなロジックで情報を抜き出します。

  • ,があったら、名前モードにする。
  • :があったら、データモードにする。
  • "があったら、文字列モードかどうかを切り替える。(名前/データモードとは別に管理するモード)
  • }があったら、読み取りを終了する。
  • 名前モードの文字列モードでは、名前の識別のため、名前の文字の文字コードの和を計算する。
  • データモードでは、十進数値を読み取り、数字の後数字以外が来たら読み取った数値を記録する。
    • "datetime"の後では、日時を表す数値をそれぞれ配列に格納する。
    • "day_of_week"の後では、曜日を表す数値を変数に格納する。
    • それ以外では、無視する。

実装

コード全体

10 ' ジコク シュトク
20 ?"MJ GETS worldtimeapi.org/api/timezone/Asia/Tokyo"
30 W=0:LET[0],0,0,0,0,0,0:N=1:H=0:S=0:P=0:V=0:E=0
40 C=INKEY():IF C=0 GOTO 40 ELSE GOTO 70
50 CLT
60 C=INKEY():IF TICK()>=30 GOTO 160 ELSE IF C=0 GOTO 60
70 IF C=#22 S=!S:IF S AND N H=-#22
80 IF S AND N H=H+C
90 IF C=#3A:N=0
100 IF C=#2C:N=1
110 IF #30 <= C AND C <= #39 V=V*10+C-#30:E=1 ELSE IF E GOTO 130
120 IF C=#7D GOTO 160 ELSE GOTO 50
130 IF H=845 AND P<6 [P]=V:P=P+1
140 IF H=1149 W=V
150 V=0:E=0:GOTO 120
160 ?[0];"/";[1];"/";[2];" (";
170 IF W=0 ?"Sun";
180 IF W=1 ?"Mon";
190 IF W=2 ?"Tue";
200 IF W=3 ?"Wed";
210 IF W=4 ?"Thu";
220 IF W=5 ?"Fri";
230 IF W=6 ?"Sat";
240 ?") ";[3];":";[4];":";[5]

解説

タイトルを置きます。

10 ' ジコク シュトク

クエリを送ります。

20 ?"MJ GETS worldtimeapi.org/api/timezone/Asia/Tokyo"

以下の変数を初期化します。

  • W:曜日
  • 配列:日時
  • N:名前モードか
  • H:名前の文字の文字コードの和
  • S:文字列モードか
  • P:次に読み取った数値を格納する配列の要素
  • V:読み取り中の数値
  • E:数値を読み取り中か
30 W=0:LET[0],0,0,0,0,0,0:N=1:H=0:S=0:P=0:V=0:E=0

結果の最初の文字を時間無制限で待ち、読み取ります。

40 C=INKEY():IF C=0 GOTO 40 ELSE GOTO 70

結果の2文字目以降を読み取ります。0.5秒文字が来なかったら、読み取りを打ち切ります。

50 CLT
60 C=INKEY():IF TICK()>=30 GOTO 160 ELSE IF C=0 GOTO 60

読み取った文字が"なら、文字列モードかどうかを切り替えます。
名前モードで文字列モードに入るなら、名前の文字の文字コードの和Hを初期化します。
(この"の文字コードも足されるため、その分マイナスにしておきます)

70 IF C=#22 S=!S:IF S AND N H=-#22

名前モードの文字列モードなら、今の文字の文字コードを足します。

80 IF S AND N H=H+C

読み取った文字が:であれば、データモードに切り替えます。

90 IF C=#3A:N=0

読み取った文字が,であれば、名前モードに切り替えます。

100 IF C=#2C:N=1

読み取った文字が数字であれば、数値の読み取り状態を更新します。
数値を読み取った状態で数字以外の文字を読み取った時は、読み取った数値を記録する処理に行きます。

110 IF #30 <= C AND C <= #39 V=V*10+C-#30:E=1 ELSE IF E GOTO 130

読み取った文字が}であれば、読み取りを終了します。
そうでなければ、次の文字の読み取りに行きます。

120 IF C=#7D GOTO 160 ELSE GOTO 50

読み取った名前が"datetime"であれば、読み取った日時を表す数値を配列に格納します。

130 IF H=845 AND P<6 [P]=V:P=P+1

読み取った名前が"day_of_week"であれば、読み取った数値を曜日を表す変数に格納します。

140 IF H=1149 W=V

数値の読み取り状態を初期化し、次の文字の読み取りに行きます。

150 V=0:E=0:GOTO 120

読み取った日時と曜日を出力します。

160 ?[0];"/";[1];"/";[2];" (";
170 IF W=0 ?"Sun";
180 IF W=1 ?"Mon";
190 IF W=2 ?"Tue";
200 IF W=3 ?"Wed";
210 IF W=4 ?"Thu";
220 IF W=5 ?"Fri";
230 IF W=6 ?"Sat";
240 ?") ";[3];":";[4];":";[5]

実験結果

MixJuiceを接続した状態でプログラムを実行し、しばらく待つと、

2021/12/14 (Tue) 3:41:5

のような形式で現在の日時が出力されました。
(取得を開始したタイミングの日時なので、出力されるタイミングからは遅れています)

MixJuice実機では、MJ SPW (送信間隔[ms])コマンドでデータをIchigoJamに転送する速度を調整できるようです。
また、今回のプログラムでは、

75 ?CHR$(C);

という行を追加することで、受信したデータを出力して確認できるようになります。

IchigoJam webでは日時の取得に成功し、実行を開始してから約50秒後に日時が出力されました。
(現在の)バーチャルMixJuiceではMJ SPWコマンドは効かないようで、データは欠けていました。

IchigoJam実機 (1.0.0) では、送信間隔を40msに設定すると、データが欠けて曜日の取得に失敗しました。
送信間隔を45msに設定すると、データが欠けずに日時の取得に成功し、
実行を開始してから約16秒で日時が出力されました。

IchigoJam実機 (1.3.1) では、送信間隔を15msに設定してもデータは欠けず、
実行を開始してから約7秒で日時が出力されました。
また、送信間隔を0msに設定しても最初の128バイト程度は受信できるようで、
データは欠けたものの日時の取得には成功し、実行を開始してから約3秒で日時が出力されました。

おわりに

Web APIを利用してIchigoJamからMixJuice経由で現在の日時を取得し、出力することができました。

ちなみに、執筆時においてMixJuiceのページもHTTPSには対応していないようです。
(接続はできるが証明書の名前が無効で、無視して続行すると404 Not Foundになりました)

IchigoJamはjig.jpの登録商標です。

3
2
0

新規登録して、もっと便利にQiitaを使ってみよう

  1. あなたにマッチした記事をお届けします
  2. 便利な情報をあとで効率的に読み返せます
  3. ダークテーマを利用できます
ログインすると使える機能について

この記事は以下の記事からリンクされています

コメント

この記事にコメントはありません。

いいね以上の気持ちはコメントで

記事投稿キャンペーン開催中

3
2

記事を削除する

一度削除した記事は復旧できません。

この記事の編集中の下書きも削除されます。

削除してよろしいですか?

ログインして続ける

ソーシャルアカウントでログイン・新規登録

メールアドレスでログイン・新規登録