bình Minh và hoàng hôn


12

Tôi là một người lãng mạn, tôi thích đưa vợ ra ngoài để ngắm bình minh và hoàng hôn ở nơi chúng tôi tọa lạc. Vì lợi ích của bài tập này, hãy nói rằng tôi không có mã có thể cho tôi biết thời gian của hoàng hôn hay bình minh cho bất kỳ ngày nào, vĩ độ và kinh độ mà tôi sẽ xảy ra.

Nhiệm vụ của bạn, các lập trình viên, là tạo ra mã nhỏ nhất có thể có vĩ độ và kinh độ thập phân (lấy theo độ N và W, do đó độ S và E sẽ được lấy làm âm) và ngày ở định dạng YYYY-MM-DD ( từ ngày 1 tháng 1 năm 2000 trở đi) và nó sẽ phun ra hai lần ở định dạng 24 giờ cho mặt trời mọc và mặt trời lặn.

vd: Hôm nay tại Sydney, Úc

riseset -33.87 -151.2 2013-12-27

05:45 20:09

Tiền thưởng: -100 nếu bạn có thể tính đến độ cao -100 nếu bạn có thể tiết kiệm ánh sáng ban ngày

Mã PHẢI nhổ thời gian trong múi giờ có liên quan được chỉ định trong đầu vào dựa trên vĩ độ và kinh độ HOẶC trong múi giờ riêng của máy khách.


3
Đợi đã, cái gì, chúng ta phải thực hiện tra cứu [vĩ độ x kinh độ] => [múi giờ]? Chúng tôi có nhận được một tập tin dữ liệu cho điều đó? Hoặc một máy chủ chúng ta có thể truy cập? Hoặc có một ngôn ngữ có những thứ như vậy được xây dựng? Bạn có thể cho chúng tôi biết cái nào? Hoặc chúng ta phải ghi nhớ các ranh giới múi giờ? Để chính xác những gì? Chúng ta lấy dữ liệu này ở đâu? Bạn có nhận ra dữ liệu này sẽ chiếm phần lớn chiều dài mã không? Điều gì về tọa độ rơi chính xác trên ranh giới múi giờ? Nói, cực địa lý? Ngoài ra, hành vi nào được phép khi đầu vào là một vùng cực trong một đêm / ngày cực? Điều gì về tọa độ ngoài phạm vi?
John Dvorak

Tôi rất thích thử thách tính toán đường chân trời dựa trên một điểm trên một quả cầu được lý tưởng hóa, nhưng tôi ghét thử thách liên quan để tìm, nén tay, giải mã theo chương trình và sau đó tra cứu bản đồ tìm kiếm múi giờ. Tất nhiên, trừ khi chúng ta có thể sử dụng các múi giờ lý tưởng hóa (phần bù được chọn sao cho mặt trời là cao nhất vào buổi trưa, sau đó nó cũng được làm tròn đến giờ gần nhất).
John Dvorak

1
@JanDvorak Sử dụng bất cứ điều gì bạn có thể, nếu ngôn ngữ bạn sử dụng có thể khai thác múi giờ của khách hàng thì bằng mọi cách hãy làm như vậy ...
WallyWest

1
Hành vi mong muốn đối với các vùng cực khi đó là ngày / đêm vùng cực?
John Dvorak

1
Đây là một công cụ nào giống hệt nhau: weatherimages.org/latlonsun.html
Eisa Adil

Câu trả lời:


4

Tôi đã dành khá nhiều thời gian để viết này:

#!/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

Bây giờ nó vẫn chưa hoạt động (tôi đã làm hỏng một số tính toán) - Tôi sẽ quay lại sau (nếu tôi vẫn còn can đảm) để hoàn thành nó / nhận xét nó .

Ngoài ra, một số tài nguyên thú vị mà tôi tìm thấy khi nghiên cứu đề tài:


3
Tôi vừa thấy bình luận của bạn về # It's late, I'm tired, and OP is a prick for asking me to do this. Không có nghĩa vụ phải thực hiện nhiệm vụ này ... Xin đừng đặt những bình luận như thế này vào mã của bạn ... Nó không phù hợp với các lập trình viên khác ... kể cả tôi. Tôi ngưỡng mộ thực tế là bạn đã khiến nó nóng lên và các liên kết khác bạn đã cung cấp, nhưng vui lòng không sử dụng các nhận xét như thế này một lần nữa ...
WallyWest

@ Eliseod'Annunzio Bạn có lời xin lỗi của tôi.
Deneb

@ Eliseod'Annunzio Tôi không có ý định xúc phạm bạn. Tôi cũng muốn cảm ơn bạn đã cho tôi một ý tưởng hoàn toàn tuyệt vời để nghiên cứu và viết mã. Bây giờ tôi muốn biến điều này thành một mô-đun python tự đứng (với các đối số sys và như vậy). Hóa ra nó phức tạp hơn một chút so với tôi nghĩ trước đây, nhưng tôi dự định sẽ thực hiện điều này. Cám ơn bạn một lần nữa.
Deneb

@Alex, bạn có nhận ra thử thách này là một năm tuổi? Tôi khá chắc chắn anh ấy đã thắng.
mbomb007

@ mbomb007: Không nhận ra.
Alex A.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.