ChatGPTとやり取りして作ってみよう!
世界向けのウェブアプリを作っている中でその地域の人が何かイベントを考えた時とかに表示する時間、その地域が時差何時間でそしてその地域は夏時間かどうかをPHPのみでどうやって手に入れようか試行錯誤した半日を公開します。最近はChatGPT4が重たいのでそんなに直近の情報が必要なければ3.5を使っりまた4を使ったり。
長いですが最後まで読んでいただくと、AIとのやりとりをどのようにすると正解に辿り着けるのか、AIとの距離感などがお分かりいただけると思います。
まずChatGPTに投げてみよう
クライアントの時間がずれていたら計算に誤差が生じるのは困るし、人によってはJavaScriptを切っている人もいる可能性を考えて次の一手を考えます。
ipアドレスからアクセスしてきた人の国を推定
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;
$databaseFile = 'path/to/GeoLite2-City.mmdb';
$reader = new Reader($databaseFile);
$ipAddress = $_SERVER['REMOTE_ADDR'];
$record = $reader->city($ipAddress);
$country = $record->country->name;
$city = $record->city->name;
$latitude = $record->location->latitude;
$longitude = $record->location->longitude;
echo "Country: $country\n";
echo "City: $city\n";
echo "Latitude: $latitude\n";
echo "Longitude: $longitude\n";
なるほど、ipアドレスで簡単にここまで取得できてしまうのですね。では、それを手に入れていきましょう。
composer require geoip2/geoip2
require_once 'vendor/autoload.php';
再度インストールしてみても見当たらないし、ちゃんとインストールはできている感じもする。。。
誤解じゃなくて嘘情報だったんじゃん。。。30分近くロスしたと思う。。。
ま、それでもMaxMindのGeoIP2が使える環境が整いました。さっそく自分の使っている場所からアクセスしてみて状態確認。4kmくらい離れた地点でしたが国と地域を知るには十分です。
取得した国名をもとにいけるのか?
各国の時差の配列を手動で書けと!?!?いやいや無理無理
$countryName = "Japan";
$timezoneOffsets = array(
"Japan" => 9,
);
if (array_key_exists($countryName, $timezoneOffsets)) {
$timeDifference = $timezoneOffsets[$countryName];
echo "標準時とUTCの時差は {$timeDifference} 時間です。";
} else {
echo "その国の時差情報が見つかりません。";
}
絶対データベースあるよね?
$japanTimeZone = new DateTimeZone('Asia/Tokyo');
$timeDifference = $japanTimeZone->getOffset(new DateTime('now'));
$timeDifferenceHours = $timeDifference / 3600;
echo "日本の標準時とUTCの時差は {$timeDifferenceHours} 時間です。";
TimeZoneはまだ取れていないと思う
なかなか元の会話から繋がらずいきなり違う提案をされている感じもするけれど、できるのかもしれないと思って次の質問を投げてみた。
TimeZoneの配列を手動で書けと!?!?いやいや無理無理
$countryName = "Japan";
$timezoneMap = array(
"Japan" => "Asia/Tokyo",
);
if (array_key_exists($countryName, $timezoneMap)) {
$timezoneIdentifier = $timezoneMap[$countryName];
$timezone = new DateTimeZone($timezoneIdentifier);
$timeDifference = $timezone->getOffset(new DateTime('now'));
$timeDifferenceHours = $timeDifference / 3600;
echo "標準時とUTCの時差は {$timeDifferenceHours} 時間です。";
} else {
echo "その国のタイムゾーン情報が見つかりません。";
}
絶対データベースあるよね?(デジャヴ)
$countryName = "Japan";
$apiKey = "YOUR_API_KEY";
$url = "http://api.timezonedb.com/v2.1/get-time-zone?key={$apiKey}&format=json&by=zone&zone={$countryName}";
$response = file_get_contents($url);
$data = json_decode($response, true);
if (isset($data['gmtOffset'])) {
$timeDifference = $data['gmtOffset'] / 3600;
echo "{$countryName}の標準時とUTCの時差は {$timeDifference} 時間です。";
} else {
echo "時差情報が見つかりませんでした。";
}
イギリスが協定世界時と12時間の時差はおかしい
$countryName = "United Kingdom";
$apiKey = "YOUR_API_KEY";
$url = "http://api.timezonedb.com/v2.1/get-time-zone?key={$apiKey}&format=json&by=zone&zone=Europe/London";
$response = file_get_contents($url);
$data = json_decode($response, true);
if (isset($data['gmtOffset'])) {
$timeDifference = $data['gmtOffset'] / 3600;
echo "{$countryName}の標準時とUTCの時差は {$timeDifference} 時間です。";
} else {
echo "時差情報が見つかりませんでした。";
}
TimeZoneを取得するためにTimeZoneが必要?
何だかぐるぐるしてきた。TimeZoneを取得するためにデータベースに繋いでいるはずなのに、それを取得するためにTimeZoneを使おうとしているまるで卵が先かニワトリが先かみたいな状態。
一度TimeZoneから離れてみよう
なるほど、確かにアメリカ、とだけ取得したって西海岸と東海岸じゃ3時間違うし、ハワイまで入れたら5時間違う。
配列を手動で書けt。。。以下略
$countryName = "United Kingdom";
$cityName = "London";
$timeZoneOffsets = array(
"United Kingdom|London" => 0,
);
$key = "{$countryName}|{$cityName}";
if (array_key_exists($key, $timeZoneOffsets)) {
$timeDifference = $timeZoneOffsets[$key];
echo "{$countryName}の{$cityName}の標準時とUTCの時差は {$timeDifference} 時間です。";
} else {
echo "時差情報が見つかりませんでした。";
}
絶対データベーs。。。てか、使ってないじゃん
$countryName = "United Kingdom";
$cityName = "London";
$apiKey = "YOUR_API_KEY";
$url = "http://api.timezonedb.com/v2.1/get-time-zone?key={$apiKey}&format=json&by=position&lat=51.5074&lng=-0.1278";
$response = file_get_contents($url);
$data = json_decode($response, true);
if (isset($data['gmtOffset'])) {
$timeDifference = $data['gmtOffset'] / 3600;
echo "{$countryName}の{$cityName}の標準時とUTCの時差は {$timeDifference} 時間です。";
} else {
echo "時差情報が見つかりませんでした。";
}
国名と都市名APIで使ってないじゃん!?!?
ChatGPT3.5も最後に断ってきたけれど$urlに書いてある内容をみたらいきなり緯度経度が指定してあって、国名と都市名からという部分は思いっきりフルスイングでスルー。TimeZoneデータベースから何が得られるのかわからなくなってきてしまったので、せっかくなのでちゃんとTimeZoneを取得してみましょう。
$response = '{"status":"OK","message":"","countryCode":"GB","countryName":"United Kingdom","zoneName":"Europe/London","abbreviation":"GMT","gmtOffset":0,"dst":"0","zoneStart":0,"zoneEnd":0,"nextAbbreviation":"","timestamp":1644940841,"formatted":"2022-02-15 19:54:01"}';
$data = json_decode($response, true);
$timeZone = $data['timezone'];
echo "Time Zone: " . $timeZone;
ChatGPTも基本を間違えることがまぁまぁある
$responseの中にtimezoneという表記は無いけれど?
$response = '{"status":"OK","message":"","countryCode":"GB","countryName":"United Kingdom","zoneName":"Europe/London","abbreviation":"GMT","gmtOffset":0,"dst":"0","zoneStart":0,"zoneEnd":0,"nextAbbreviation":"","timestamp":1644940841,"formatted":"2022-02-15 19:54:01"}';
$data = json_decode($response, true);
$timeZone = $data['zoneName'];
echo "Time Zone: " . $timeZone;
TimeZoneは取れた、でそれをどうする?
だめだ、このままでは答えに行き着く感じがしない。
そして、ふと思い出したのです。
MaxMindのGeoIP2で緯度経度取れてたよね?
ということはここまでのやりとり全て無駄で、国名都市名タイムゾーンうんぬんじゃなくて当初取れていた緯度経度で最初に解決してしまっていた話?
ChatGPT4に切り替えて先に進めてみよう。
Geoapifyのウェブを見てみるとひと月で使える無料ポイントもけっこうあるし、いろいろと細かい情報も得られそう。
なんとPHPに夏時間かどうか調べる関数標準装備
$timezoneName = 'Europe/London';
$timezone = new DateTimeZone($timezoneName);
$datetime = new DateTime('now', $timezone);
$isDST = $datetime->format('I') == 1 ? 'Yes' : 'No';
echo "Is it currently DST in $timezoneName? $isDST\n";
整理しよう整理しよう、ちょっと混乱してしまっている感じがする。
今までの話だと、ipアドレスからMaxmindのGeoIP2で国名、都市名、緯度経度を取得→緯度経度からGeoapifyを使ってTimeZoneと時差セットを取得→PHPで解析!
できそうな感じがしてきました!
ふと最初にインストールしたGeoLite2-Cityでどんなデータが取れるのかな、と思い立って以下の質問を投げかけてみました。
ちょっ!?TimeZoneそこにある!?!?
ちょっと待て、衝撃の事実! 位置情報の中にしれっとタイムゾーンと書いてある。目次の「取得した国名をもとにいけるのか?」からここまで全て無駄!?!?
うーん、納得いかないけれど、事実だから仕方ない。Geoapifyからは別な情報も得られるし時差のオフセットも必要だからまぁ良いとしてもなんか遠回りしたようななんだかかんだか。
では、ここまでの情報で組み立てみよう
おそらくプログラミング好きの方ならここまでの情報で完成形を作れてしまうとは思いますが、この先はコピペができる完成形です。ぜひご利用ください。その他、こうすればお得にいけるだろう、という案も入っています。
ということで私の半日を100円で売ります!!ぜひっっっ!!!買って!!!!
いや、しかしそもそもこの内容、需要あるのか??必要な方みえるだろうか。