日出和日落


12

我有点浪漫,我喜欢带我的妻子出去看看我们所在地的日出和日落。出于这个练习的原因,假设我没有代码可以告诉我恰好处于的日期,纬度和经度的日落或日出时间。

编码员的任务是生成最小的代码,该代码可能采用的是十进制的纬度和经度(以N和W为度,所以S和E为负数)和采用YYYY-MM-DD格式的日期(从2000年1月1日开始),它将以24小时格式吐出两次,用于日出和日落。

例如今天在澳大利亚悉尼

riseset -33.87 -151.2 2013-12-27

05:45 20:09

奖励:-100如果可以考虑高程-100如果可以考虑日光节约

代码必须根据客户机器自身时区中的纬度或经度或在输入中指定的相关时区中吐出时间。


3
等待,什么,我们必须进行[纬度x经度] => [时区]查找?我们是否为此获得了数据文件?还是我们可以访问的服务器?还是有内置这种语言的语言?能告诉我们哪一个吗?还是我们必须记住时区边界?达到什么精度?我们从哪里得到这些数据?您是否知道此数据将占用大部分代码长度?完全落在时区边界上的坐标呢?说,地理两极?此外,当输入是极地夜晚/白天期间的极地区域时,允许什么行为?超出范围的坐标呢?
约翰·德沃夏克

我很乐意根据理想球体上方的一个点来计算地平线,但我讨厌相关的挑战,即查找,手动压缩,以编程方式脱木棉,然后在时区查找图中查找。当然,除非我们可以使用理想的时区(选择偏移量,以便使太阳在中午时分最高,然后将其舍入到最接近的小时数)。
John Dvorak 2013年

1
@JanDvorak竭尽所能,如果您使用的语言可以利用客户所在的时区,那么一定要这样做……
WallyWest 2013年

1
白天/晚上是极地时,极地地区的期望行为是什么?
John Dvorak 2013年

1
这是一个功能完全相同的工具:weatherimages.org/latlonsun.html
Eisa Adil 2013年

Answers:


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. 没有义务执行此任务”的评论……请不要在您的代码中添加这样的评论……它在其他编码人员中的位置也不理想……包括我在内。我很佩服您为它
付出了巨大的努力

@ Eliseod'Annunzio您对我表示歉意。
Deneb 2014年

@ Eliseod'Annunzio我无意冒犯您。我还要感谢您给了我一个绝对绝妙的想法来进行研究和编码。现在,我想把它变成一个独立的python模块(带有sys参数等等)。事实证明,这比我以前认为的要复杂一些,但是我打算实现这一目标。再次感谢你。
Deneb 2014年

@Alex,您知道这个挑战已经一岁了吗?我很确定他赢了。
mbomb007

@ mbomb007:没意识到。
Alex A.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.