From 76203f1e400a1808759739b53a238a9ac777ef3c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 6 Apr 2025 08:09:45 +0000 Subject: [PATCH 1/2] Add global weather feature for multiple countries --- main.go | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index b503518..65319a8 100644 --- a/main.go +++ b/main.go @@ -2,10 +2,60 @@ package main import ( "fmt" + "math/rand" "time" ) -// 時間を表示する簡単なgo言語のプログラム +// 世界各国の時計と天気を表示するgo言語のプログラム func main() { - fmt.Println("The time is", time.Now()) + fmt.Println("=== 世界各国の時計と天気 ===") + + // 各国の時間帯と都市名 + locations := map[string]string{ + "Asia/Tokyo": "東京 (日本)", + "America/New_York": "ニューヨーク (アメリカ)", + "Europe/London": "ロンドン (イギリス)", + "Europe/Paris": "パリ (フランス)", + "Australia/Sydney": "シドニー (オーストラリア)", + "Asia/Shanghai": "上海 (中国)", + "Asia/Singapore": "シンガポール", + "Europe/Moscow": "モスクワ (ロシア)", + "Asia/Dubai": "ドバイ (UAE)", + "America/Sao_Paulo": "サンパウロ (ブラジル)", + } + + // 天気の種類 + weatherTypes := []string{"晴れ", "曇り", "雨", "雪", "霧", "強風", "嵐"} + + // 気温の範囲(摂氏) + minTemp := -10 + maxTemp := 40 + + // Go 1.20以降ではrand.Seedは不要 + // 古いバージョンの場合のみこれを使用 + // rand.Seed(time.Now().UnixNano()) + + // 各場所の時間と天気を表示 + for location, cityName := range locations { + // 時間帯を取得 + loc, err := time.LoadLocation(location) + if err != nil { + fmt.Printf("時間帯の読み込みエラー %s: %v\n", location, err) + continue + } + + // 現地時間 + localTime := time.Now().In(loc) + + // ランダムな天気と気温を生成 + weather := weatherTypes[rand.Intn(len(weatherTypes))] + temperature := rand.Intn(maxTemp-minTemp+1) + minTemp + + // 表示 + fmt.Printf("%s: %s, 天気: %s, 気温: %d°C\n", + cityName, + localTime.Format("2006-01-02 15:04:05"), + weather, + temperature) + } } From 580fffca42a90724c5ca574211a8a1548ea1a8c7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 6 Apr 2025 12:15:20 +0000 Subject: [PATCH 2/2] Fix random data to fetch actual API data --- main.go | 151 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 122 insertions(+), 29 deletions(-) diff --git a/main.go b/main.go index 65319a8..c512402 100644 --- a/main.go +++ b/main.go @@ -1,42 +1,86 @@ package main import ( + "encoding/json" "fmt" - "math/rand" + "io" + "net/http" + "os" + "strings" "time" ) +// 天気情報を格納する構造体 +type WeatherResponse struct { + Weather []struct { + Main string `json:"main"` + Description string `json:"description"` + } `json:"weather"` + Main struct { + Temp float64 `json:"temp"` + FeelsLike float64 `json:"feels_like"` + TempMin float64 `json:"temp_min"` + TempMax float64 `json:"temp_max"` + Humidity int `json:"humidity"` + } `json:"main"` + Name string `json:"name"` +} + +// 天気の状態を日本語に変換 +func translateWeather(condition string) string { + weatherMap := map[string]string{ + "Clear": "晴れ", + "Clouds": "曇り", + "Rain": "雨", + "Drizzle": "小雨", + "Thunderstorm": "雷雨", + "Snow": "雪", + "Mist": "霧", + "Fog": "霧", + "Haze": "もや", + "Smoke": "煙霧", + "Dust": "砂塵", + "Sand": "砂", + "Ash": "火山灰", + "Squall": "暴風", + "Tornado": "竜巻", + } + + if japaneseWeather, ok := weatherMap[condition]; ok { + return japaneseWeather + } + return condition +} + // 世界各国の時計と天気を表示するgo言語のプログラム func main() { fmt.Println("=== 世界各国の時計と天気 ===") - // 各国の時間帯と都市名 - locations := map[string]string{ - "Asia/Tokyo": "東京 (日本)", - "America/New_York": "ニューヨーク (アメリカ)", - "Europe/London": "ロンドン (イギリス)", - "Europe/Paris": "パリ (フランス)", - "Australia/Sydney": "シドニー (オーストラリア)", - "Asia/Shanghai": "上海 (中国)", - "Asia/Singapore": "シンガポール", - "Europe/Moscow": "モスクワ (ロシア)", - "Asia/Dubai": "ドバイ (UAE)", - "America/Sao_Paulo": "サンパウロ (ブラジル)", + // 環境変数からAPIキーを取得 + apiKey := os.Getenv("OPENWEATHER_API_KEY") + if apiKey == "" { + fmt.Println("警告: OPENWEATHER_API_KEY環境変数が設定されていません。天気情報は取得できません。") } - - // 天気の種類 - weatherTypes := []string{"晴れ", "曇り", "雨", "雪", "霧", "強風", "嵐"} - - // 気温の範囲(摂氏) - minTemp := -10 - maxTemp := 40 - // Go 1.20以降ではrand.Seedは不要 - // 古いバージョンの場合のみこれを使用 - // rand.Seed(time.Now().UnixNano()) + // 各国の時間帯、都市名、OpenWeatherMapで使用する都市名 + locations := map[string]struct { + DisplayName string + CityForAPI string + }{ + "Asia/Tokyo": {"東京 (日本)", "Tokyo"}, + "America/New_York": {"ニューヨーク (アメリカ)", "New York"}, + "Europe/London": {"ロンドン (イギリス)", "London"}, + "Europe/Paris": {"パリ (フランス)", "Paris"}, + "Australia/Sydney": {"シドニー (オーストラリア)", "Sydney"}, + "Asia/Shanghai": {"上海 (中国)", "Shanghai"}, + "Asia/Singapore": {"シンガポール", "Singapore"}, + "Europe/Moscow": {"モスクワ (ロシア)", "Moscow"}, + "Asia/Dubai": {"ドバイ (UAE)", "Dubai"}, + "America/Sao_Paulo": {"サンパウロ (ブラジル)", "Sao Paulo"}, + } // 各場所の時間と天気を表示 - for location, cityName := range locations { + for location, info := range locations { // 時間帯を取得 loc, err := time.LoadLocation(location) if err != nil { @@ -47,15 +91,64 @@ func main() { // 現地時間 localTime := time.Now().In(loc) - // ランダムな天気と気温を生成 - weather := weatherTypes[rand.Intn(len(weatherTypes))] - temperature := rand.Intn(maxTemp-minTemp+1) + minTemp + // 天気情報を取得 + weather := "情報なし" + temperature := 0.0 + + if apiKey != "" { + weatherInfo, err := getWeather(info.CityForAPI, apiKey) + if err != nil { + fmt.Printf("天気情報の取得エラー %s: %v\n", info.CityForAPI, err) + } else { + if len(weatherInfo.Weather) > 0 { + weather = translateWeather(weatherInfo.Weather[0].Main) + } + temperature = weatherInfo.Main.Temp + } + } // 表示 - fmt.Printf("%s: %s, 天気: %s, 気温: %d°C\n", - cityName, + fmt.Printf("%s: %s, 天気: %s, 気温: %.1f°C\n", + info.DisplayName, localTime.Format("2006-01-02 15:04:05"), weather, temperature) } } + +// OpenWeatherMap APIから天気情報を取得 +func getWeather(city, apiKey string) (WeatherResponse, error) { + var weatherData WeatherResponse + + // スペースをURL用に変換 + city = strings.ReplaceAll(city, " ", "%20") + + // APIリクエストURL + url := fmt.Sprintf("https://api.openweathermap.org/data/2.5/weather?q=%s&appid=%s&units=metric", city, apiKey) + + // HTTPリクエスト + resp, err := http.Get(url) + if err != nil { + return weatherData, err + } + defer resp.Body.Close() + + // レスポンスボディを読み取り + body, err := io.ReadAll(resp.Body) + if err != nil { + return weatherData, err + } + + // ステータスコードチェック + if resp.StatusCode != http.StatusOK { + return weatherData, fmt.Errorf("API error: %s", string(body)) + } + + // JSONをデコード + err = json.Unmarshal(body, &weatherData) + if err != nil { + return weatherData, err + } + + return weatherData, nil +}