이 페이지는 코딩도장 데이터의 읽기 전용 정적 보관본입니다.

일출,일몰 시각 계산하기-1)밤시간 낮시간 계산

사무실에 가로등 타이머가 고장나업체를 불러 수리 하였습니다. 그때 문득 일몰일출 시간계산 알고리즘이 궁굼해 지더군요. 그래서 일차적으로 만든 밤 길이 비율 수식은

(acos(tanθ₁×tanθ₂)×2)/360

θ₁:지구 자전축의 북쪽이 태양쪽으로 기울어진 각도
θ₂:위도(북위, 남위는 -)
acos:코싸인의 역함수

제 블로그에 자세한 유도 과정이 있습니다.
https://blog.naver.com/i_jeju/221506869006

지구 기울기와 위도를 입력하여 낮시간, 밤시간 길이를 출력해 보도록 합니다.

지구가 기울어진 각도 :23.5
위도 입력 :38
밤길이 9 : 21 : 8
낮길이 14 : 38 : 52

아~ 그리고 이런것도 추가하면 좋겠죠.

지구가 기울어진 각도 :23.5
위도 입력 :80
계속 낮 입니다


지구가 기울어진 각도 :-23.5
위도 입력 :80
계속 밤 입니다

기울어진 각도가 23.5 ->하지 기울어진 각도가 -23.5 ->동지

지구과학 삼각함수

2019/04/08 10:35

이이충학

6개의 풀이가 있습니다.

#지구 기울기와 위도 입력으로 밤시간과 낮시간 계산 
import math

def NightR(Q1,Q2):
    if  abs(Q2) > 90-abs(Q1):
        if Q1*Q2 > 0:
            return 0
        if Q1*Q2 < 0:
            return 1
    #밤 비율 계산
    rat1=math.acos(math.tan(math.radians(Q1))*math.tan(math.radians(Q2)))
    rat2=2*math.degrees(rat1)
    return rat2/360

se1=float(input('지구가 기울어진 각도 :')) #북극이 태양쪽으로 기울어진 것이 +
se2=float(input('위도 입력 :')) #북위 +, 남위 -
nrat=NightR(se1,se2)

if  nrat == 0:
    print('계속 낮 입니다')
else:
    if nrat == 1:
        print('계속 밤 입니다')
    else :
        #밤 길이 비율을 시간으로 계산
        nti=int(nrat*24)
        ims=nrat*24 - nti
        nmi=int(ims*60)
        ims=ims*60 - nmi
        nse=int(ims*60+0.5)
        #낮 길이 비율을 시간으로 계산
        ati=int((1-nrat)*24)
        ims=(1-nrat)*24 - ati
        ami=int(ims*60)
        ims=ims*60 - ami
        ase=int(ims*60+0.5)
        #인쇄
        print('밤길이',nti,':',nmi,':',nse)
        print('낮길이',ati,':',ami,':',ase)

밤 비율이기 대문에 1은 하루-24시간 입니다.
시스템에서는 레디안을 사용하고 경도 위도 등은 디그리를 사용 하기 때문에 변환이 필요 합니다.
math.degrees() 는 레디안을 디그리로 바꾸는 함수 입니다. math.radians()는 디그리를 레디안으로 바꾸는 함수구요.

2019/04/08 15:06

이이충학

0.5는 왜 추가로 더해주는건가요?? - kimgy, 2019/05/14 11:16

C#

using System;
using System.Text;

namespace CD220
{
    internal class Program
    {
        private static void Main()
        {
            Console.Write("지구가 기울어진 각도(degree): ");
            double axialTile = double.Parse(Console.ReadLine());
            Console.Write("위도(degree): ");
            double latitude = double.Parse(Console.ReadLine());

            DayNightRatio testCase = new DayNightRatio(axialTile, latitude);
            Console.WriteLine(testCase.ToString());
        }
    }

    public class DayNightRatio
    {
        private readonly double AxialTilt;

        private readonly double Latitude;

        public DayNightRatio(double axialTilt, double latitude) // 각도(Degree) 단위 입력
        {
            AxialTilt = axialTilt;
            Latitude = latitude;
        }

        private double NightRatio()
        {
            if (Math.Abs(AxialTilt) > 90 - Math.Abs(Latitude))
            {
                return AxialTilt * Latitude >= 0 ? 0 : 1;
            }
            double theta3Rad =
                Math.Acos(Math.Tan(ToRad(AxialTilt)) * Math.Tan(ToRad(Latitude)));
            return 2 * ToDeg(theta3Rad) / 360;
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            double ratio = NightRatio();
            if (ratio == 0)
            {
                sb.AppendLine("계속 낮입니다.");
            }
            else if (ratio == 1)
            {
                sb.AppendLine("계속 밤입니다.");
            }
            else
            {
                TimeSpan nightTime = TimeSpan.FromSeconds(60 * 60 * 24 * ratio);
                TimeSpan dayTime = TimeSpan.FromSeconds(60 * 60 * 24 * (1 - ratio));
                sb.AppendLine($"낮의 길이 {dayTime.ToString()}");
                sb.AppendLine($"밤의 길이 {nightTime.ToString()}");
            }
            return sb.ToString();
        }

        private static double ToRad(double degree) => 2 * Math.PI / 360 * degree;

        private static double ToDeg(double rad) => 360 / (2 * Math.PI) * rad;
    }
}

2019/04/30 18:01

mohenjo

import math
import time

def nightT(ax, lat):
    th1 = math.radians(ax)
    th2 = math.radians(lat)
    nt = math.acos(math.tan(th1)*math.tan(th2))
    ntR = (2*math.degrees(nt))/360

    print('밤길이: {}'.format(time.strftime('%H:%M:%S', time.gmtime(ntR * 24 * 3600 + 0.5))))
    print('낮길이: {}'.format(time.strftime('%H:%M:%S', time.gmtime((1-ntR) * 24 * 3600 + 0.5))))

if __name__ == '__main__':
    ax = 23.5
    lat = 38
    nightT(ax, lat)

2020/05/19 10:35

Hwaseong Nam

시간 비율을 초(sec)로 환산하여 time 모듈로 시간 처리 - Hwaseong Nam, 2020/05/19 10:36
datetime을 사용하여 str(datetime.timedelta(hours=시간비율값))으로 처리해도 됨 - Hwaseong Nam, 2020/05/19 10:38

Go 1.14.4

package main

import (
    "fmt"
    "math"
)

func deg(rad float64) (y float64) {
    y = rad * 180 / math.Pi
    return
}

func rad(deg float64) (y float64) {
    y = deg * math.Pi / 180
    return
}

func night(theta1, theta2 float64) {
    if math.Abs(theta2) > 90-math.Abs(theta1) {
        if theta1*theta2 > 0 {
            fmt.Println("계속 낮입니다.")
        } else {
            fmt.Println("계속 밤입니다.")
        }
    } else {
        rat1 := deg(math.Acos(math.Tan(rad(theta1))*math.Tan(rad(theta2)))) / 180

        nti := int(rat1 * 24)
        ims := rat1*24 - float64(nti)
        nmi := int(ims * 60)
        ims = ims*60 - float64(nmi)
        nse := int(ims*60 + 0.5)

        ati := int((1 - rat1) * 24)
        ims = (1-rat1)*24 - float64(ati)
        ami := int(ims * 60)
        ims = ims*60 - float64(ami)
        ase := int(ims*60 + 0.5)

        fmt.Printf("밤길이 %d:%d:%d\n낮길이 %d:%d:%d\n", nti, nmi, nse, ati, ami, ase)
    }
}

func main() {
    var theta1, theta2 float64
    var n1, n2 int

    fmt.Printf("지구가 기울어진 각도: ")
    n1, _ = fmt.Scanf("%f\n", &theta1)

    fmt.Printf("위도 입력: ")
    n2, _ = fmt.Scanf("%f\n", &theta2)

    if n1 != 1 && n2 != 1 {
        fmt.Println("잘못된 값이 입력되었습니다.")
    } else {
        night(theta1, theta2)
    }
}

2020/07/16 12:31

구루마

import math


def sunRiseNSet(a, l):
    nightRatio = math.degrees(math.acos(math.tan(math.radians(a)) * math.tan(math.radians(l)))) * 2 / 360
    nh = str(round(nightRatio * 86400 / (60 * 60))).zfill(2)
    nm = str(round(nightRatio * 86400 % (60 * 60) / 60)).zfill(2)
    ns = str(round(nightRatio * 86400 % (60 * 60) % 60)).zfill(2)
    dh = str(23 - int(nh)).zfill(2)
    dm = str(59 - int(nm)).zfill(2)
    ds = str(60 - int(ns)).zfill(2)

    print("낮시간 - " + dh + ":" + dm + ":" + ds)
    print("밤시간 - " + nh + ":" + nm + ":" + ns)


sunRiseNSet(23.5, 38)

2020/12/03 14:38

김우석


from math import *

ang = float(input("지구와의 기울기 입력"))
lat = float(input("위도를 입력 하시오"))

def ratio (a,l):
    if abs(l) > 90-abs(a):
        if a*l >0:
            print("계속 밤입니다")
        elif a*l < 0 :
            print("계속 낮입니다")
    else:
        a = radians(ang)
        l = radians(lat)
        night_ratio = degrees(acos(tan(a)*tan(l)))*2/360
        day = 60*60*24 #하루 초
        n=int(day*night_ratio)
        d=int(day*(1-night_ratio))

        print("밤길이 {0}:{1}:{2}".format(n//3600,n%3600//60,n%3600%60))
        print("낮길이 {0}:{1}:{2}".format(d//3600,d%3600//60,d%3600%60))

ratio(ang,lat)

2022/01/21 01:24

양캠부부

목록으로