日の出と日の入り


12

私は少しロマンチックです。私たちがいる場所で日の出と日の入りを見るために妻を連れ出すのが大好きです。この演習のために、私がたまたま日付や緯度、経度に関係なく、日没または日の出の時間を教えてくれるコードは持っていないとしましょう。

あなたのタスク、コーダーは、10進数の緯度と経度(N度とW度で取得されるため、SとE度は負と見なされます)とYYYY-MM-DD形式の日付( 2000年1月1日以降)、日の出と日の入りのために24時間形式で2回吐き出します。

例:オーストラリアのシドニーでの今日

riseset -33.87 -151.2 2013-12-27

05:45 20:09

ボーナス:高度を考慮できる場合は-100、夏時間を考慮できる場合は-100

コードは、緯度と経度に基づいて入力で指定された関連するタイムゾーン、またはクライアントマシンのタイムゾーンで時間を吐き出さなければなりません。


3
ちょっと待って、[緯度x経度] => [タイムゾーン]ルックアップを行う必要がありますか?そのためのデータファイルを取得しますか?または私たちがアクセスできるサーバー?または、そのようなものが組み込まれている言語はありますか?どちらを教えてもらえますか?または、タイムゾーンの境界を記憶する必要がありますか?どんな精度で?このデータはどこで入手できますか?このデータがコード長の大部分を占めることを理解していますか?タイムゾーンの境界に正確に一致する座標はどうですか?地理的な極と言うのですか?また、極夜/日中に入力が極地域である場合、どのような動作が許可されますか?範囲外の座標はどうですか?
ジョンドボラック

理想的な球体の上の点に基づいて地平線を計算するという挑戦が大好きですが、タイムゾーンのルックアップマップを見つけ、手で圧縮し、プログラムで解読してから調べるという関連した挑戦が嫌いです。もちろん、理想的なタイムゾーンを使用できない限り(正午に太陽が最も高くなるようにオフセットが選択され、次に最も近い時間に丸められます)。
ジョンドヴォルザーク

1
@JanDvorak使用する言語がクライアントのタイムゾーンを悪用する可能性がある場合は、できる限り使用します。その場合はどうしてもそうします。
WallyWest

1
極地の昼/夜の場合、極地で望ましい動作は何ですか?
ジョンドボラック

1
これはまったく同じことを行うツールです
。weatherimages.org

回答:


4

私はこれを書くのにかなりの時間を費やしました:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from math import *


class RiseSet(object):

    __ZENITH = {'official': 90.833,
                'civil': '96',
                'nautical': '102',
                'astronomical': '108'}

    def __init__(self, day, month, year, latitude, longitude, daylight=False,
                 elevation=840, zenith='official'):
        ''' elevation is set to 840 (m) because that is the mean height of land above the sea level '''

        if abs(latitude) > 63.572375290155:
            raise ValueError('Invalid latitude: {0}.'.format(latitude))

        if zenith not in self.__ZENITH:
            raise ValueError('Invalid zenith value, must be one of {0}.'.format
                            (self.__ZENITH.keys()))

        self.day = day
        self.month = month
        self.year = year
        self.latitude = latitude
        self.longitude = longitude
        self.daylight = daylight
        self.elevation = elevation
        self.zenith = zenith

    def getZenith(self):
        return cos(radians(self.__ZENITH[self.zenith]))

    def dayOfTheYear(self):
        n0 = floor(275*self.month/9)
        n1 = floor((self.month + 9) / 12)
        n2 = (1 + floor((self.year - 4*floor(self.year/4) + 2) / 3))
        return n0 - (n1*n2) + self.day - 30

    def approxTime(self):
        sunrise = self.dayOfTheYear() + ((6 - (self.longitude/15.0)) / 24)
        sunset = self.dayOfTheYear() + ((18 - (self.longitude/15.0)) / 24)
        return (sunrise, sunset)

    def sunMeanAnomaly(self):
        sunrise = (0.9856 * self.approxTime()[0]) - 3.289
        sunset = (0.9856 * self.approxTime()[1]) - 3.289
        return (sunrise, sunset)

    def sunTrueLongitude(self):
        sma = self.sunMeanAnomaly()
        sunrise = sma[0] + (1.916*sin(radians(sma[0]))) + \
                  (0.020*sin(radians(2*sma[0]))) + 282.634

        if sunrise < 0:
            sunrise += 360
        if sunrise > 360:
            sunrise -= 360

        sunset = sma[1] + (1.916*sin(radians(sma[1]))) + \
                 (0.020*sin(radians(2*sma[1]))) + 282.634

        if sunset <= 0:
            sunset += 360
        if sunset > 360:
            sunset -= 360

        return (sunrise, sunset)

    def sunRightAscension(self):
        stl = self.sunTrueLongitude()
        sunrise = atan(radians(0.91764*tan(radians(stl[0]))))

        if sunrise <= 0:
            sunrise += 360
        if sunrise > 360:
            sunrise -= 360

        sunset = atan(radians(0.91764*tan(radians(stl[1]))))

        if sunset <= 0:
            sunset += 360
        if sunset > 360:
            sunset -= 360

        sunrise_stl_q = (floor(stl[0]/90)) * 90
        sunrise_ra_q = (floor(sunrise/90)) * 90
        sunrise = sunrise + (sunrise_stl_q - sunrise_ra_q)
        sunrise = sunrise/15.0

        sunset_stl_q = (floor(stl[1]/90)) * 90
        sunset_ra_q = (floor(sunset/90)) * 90
        sunset = sunrise + (sunset_stl_q - sunset_ra_q)
        sunset /= 15.0

        return (sunrise, sunset)

    def sunDeclination(self):
        sunrise_sin_dec = 0.39782 * sin(radians(self.sunTrueLongitude()[0]))
        sunrise_cos_dec = cos(radians(asin(radians(sunrise_sin_dec))))

        sunset_sin_dec = 0.39782 * sin(radians(self.sunTrueLongitude()[1]))
        sunset_cos_dec = cos(radians(asin(radians(sunrise_sin_dec))))

        return (sunrise_sin_dec, sunrise_cos_dec,
                sunset_sin_dec, sunset_cos_dec)

    def sunHourAngle(self):
        sd = self.sunDeclination()
        sunrise_cos_h = (cos(radians(self.getZenith())) - (sd[0]* \
                         sin(radians(self.latitude))) / (sd[1]* \
                         cos(radians(self.latitude))))
        if sunrise_cos_h > 1:
            raise Exception('The sun never rises on this location.')

        sunset_cos_h = (cos(radians(self.getZenith())) - (sd[2]* \
                         sin(radians(self.latitude))) / (sd[3]* \
                         cos(radians(self.latitude))))
        if sunset_cos_h < -1:
            raise Exception('The sun never sets on this location.')

        sunrise = 360 - acos(radians(sunrise_cos_h))
        sunrise /= 15.0

        sunset = acos(radians(sunrise_cos_h))
        sunset /= 15.0

        return (sunrise, sunset)

    def localMeanTime(self):
        sunrise = self.sunHourAngle()[0] + self.sunRightAscension()[0] - \
                 (0.06571*self.approxTime()[0]) - 6.622
        sunset = self.sunHourAngle()[1] + self.sunRightAscension()[1] - \
                 (0.06571*self.approxTime()[1]) - 6.622
        return (sunrise, sunset)

    def convertToUTC(self):
        sunrise = self.localMeanTime()[0] - (self.longitude/15.0)

        if sunrise <= 0:
            sunrise += 24
        if sunrise > 24:
            sunrise -= 24

        sunset = self.localMeanTime()[1] - (self.longitude/15.0)

        if sunset <= 0:
            sunset += 24
        if sunset > 24:
            sunset -= 24

        return (sunrise, sunset)

    def __str__(self):
        return None

今はまだ機能していません(いくつかの計算を台無しにしました)-後でそれ完成/コメントするために(私はまだ勇気があれば)戻ってきます。

また、主題を調査しているときに見つけた興味深いリソース:


3
私はあなたのコメントを見ました。# It's late, I'm tired, and OP is a prick for asking me to do this. このタスクを行う義務はありませんでした...あなたのコードにこのようなコメントを入れないでください...私を含む他のコーダーと好意的に座っていません... 私は...あなたはそれを赤の熱い行くを与えたという事実を賞賛し、あなたが提供してきた他のリンクが、二度とこのようなコメントを使用しないでください
WallyWest

@ Eliseod'Annunzioおmyび申し上げます。
デネブ14年

@ Eliseod'Annunzio私はあなたを怒らせるつもりはなかった。また、研究とコーディングに関して非常に素晴らしいアイデアを与えてくれたことにも感謝します。次に、これを(sys引数などを使用した)自立型のPythonモジュールに変換したいと思います。以前考えていたよりも少し複雑であることが判明しましたが、これをやめるつもりです。ありがとうございました。
デネブ14年

@アレックス、あなたはこの挑戦が1年前であることを知っていますか?彼が勝ったと確信しています。
mbomb007

@ mbomb007:気付かなかった。
アレックスA.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.