Script to run everyday at sunset Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
Drugwash
Posts: 850
Joined: 29 May 2014, 21:07
Location: Ploieşti, Romania
Contact:

Re: Script to run everyday at sunset

Post by Drugwash » 24 Jan 2022, 00:59

amateur+ wrote:
22 Jan 2022, 18:36
Maybe we should use time property too instead of start/end?
obj.civil.time, obj.civil.duration, obj.sunset.time
Sounds logical and intuitive to me. :thumbup:
Part of my AHK work can be found here.

amateur+
Posts: 655
Joined: 09 Oct 2021, 15:43

Re: Script to run everyday at sunset

Post by amateur+ » 24 Jan 2022, 03:20

Btw, I forgot that it would be obj.sunrise.civil.time, obj.sunrise.civil.duration, obj.sunset.time
Have found any drawback in my code or approach? Please, point it out. /The moderator ordered to remove the rest of the signature, I had obeyed.
And I really apologize for our russian president. Being a citizen of an aggressor country is very shameful. Personally I tried to avoid this trying to defend elections from fraud being a member of the election commission of one of the precincts but only was subjected to a hooligan attack and right before the vote count was illegally escorted from the polling station and spent the night behind bars (in jail) in a result of illegal actions of corrupt policemen.

amateur+
Posts: 655
Joined: 09 Oct 2021, 15:43

Re: Script to run everyday at sunset

Post by amateur+ » 29 Jan 2022, 03:09

Ok, gentlemen, here is a new named SunTime() function that returns an object with the following structure:
Spoiler
And the function itself:

Code: Select all

;-------------------------------------------------------------
;	Function	SunTime()
;		MIT license.
;		https://www.autohotkey.com/boards/viewtopic.php?p=442010#p442010
;		https://gml.noaa.gov/grad/solcalc/solareqns.pdf
; 	
;	Parameters:
;		latitude		in degrees. 0 (equator) by default.
;		longitude		in degrees. 0-meridian (London, England) by default.
;		timezone		in hours from UTC. You will get local times for chosen timezone. By default (if omitted), 
;					the user's local timezone will be used.
;		date			The date (in the YYYYMMDDHH24MISS format) of the day you need to know sunset/sunrise time. 
;					Today (A_NowUTC) by default if omitted.
; 	
;	Description:
;  		The function calculates offline and for a chosen geo location and a date returns an object of suntime data such as
;		sunset or sunrise "time" in hh:mm format (always within 24 hours) and in minutes from midnight "mins" (can be 
;		negative or >24 hours depending on timezone), twilights stages (civil, nautical and astronomical with "time", "mins" 
;		and "duration"), "day" length and a length of the darkest part of a night: time period between evening and morning 
;		astronomical twilights ("night"). Returned time is local for the chosen timezone (see timezone parameter above).
;	
;	Returned object structure ("m" - in minutes):
;		suntime_obj = {	sunrise:	{time: "hh:mm", mins: m,  civil: t_obj, nautical: t_obj, astronomical: t_obj}
;					  , sunset:		{time: "hh:mm", mins: m,  civil: t_obj, nautical: t_obj, astronomical: t_obj}
;					  , day:		m
;					  , night:		m}
;		
;		t_obj = {time: "hh:mm", mins: m, duration: m}
;		E.g. suntime_obj.sunset.civil.time is a time of the end of an evening civil twilight and
;			 suntime_obj.sunrise.civil.time is a time of the beginning of a morning civil twilight. So it is always
;		the darkest edge of a current twilight stage.
;		Also note that day+night < 24 hours	
;
;	Examples:
;	1).
;		obj := SunTime(40.689259, -74.044420, New_York_Timezone := -5)
;		MsgBox, % obj.sunset.time
; 			; It is local time of today's sunset near the Statue of Liberty, New York (local for New York, UTC-5 timezone).
;	2).
;		obj := SunTime(47.37, 8.54, 1, 20220214112)
;		MsgBox, % obj.sunset.time " - " obj.sunset.civil.time
;			; It will show local for Zurich, Switzerland of civil twilight period in Zurich on St. Valentine's day.
;	3).
;		obj := SunTime(47.37, 8.54, -5)
;		MsgBox, % obj.sunset.civil.time " - " obj.sunset.nautical.time "`n" obj.sunset.nautical.duration
;			; It will show local for New York today's nautical evening twilight period and its duration in Zurich.
;			; https://www.timeanddate.com/sun/switzerland/zurich
;	4). 
;		obj := SunTime(51.507351, , , A_YYYY)
;		MsgBox, % obj.sunrise.time
; 			; It is the user's local time of January, 1st this year's sunrise in London, England (local for the user since timezone
;			; parameter was omitted).
;	5). 
;		obj := SunTime(47.37, 8.54)
;		MsgBox, % 1440 - obj.day
;			; It will show today's duration of the time from sunset till sunrise in Zurich in minutes. (1440 = 24*60)
;	6). NewYorkObj	:= SunTime(40.689259, -74.044420)
;		ZurichObj	:= SunTime(47.37, 8.54)
;		MsgBox, % NewYorkObj.sunrise.mins - ZurichObj.sunrise.mins 
;			; It will show today's time difference in minutes between sunrises in these two cities.
;
;	Thanks to @garry, @mikeyww, @boiler, @flyingDman and @Drugwash at AutoHotkey.com
;-------------------------------------------------------------

SunTime(latitude := 0, longitude := 0, timezone := "", date := "") {
	if (date = "")
		date := A_NowUTC
	if date is not time
	{	throw "Error. date parameter " . date . " is not time."
		return
	}
	if (timezone = "")	; Lets calculate the user's timezone.
	{	timezone := A_Now
		timezone -= A_NowUTC, Hours	; In hours
	}
	if timezone is not number
	{	throw "Error. timezone parameter " . timezone . " is invalid. Should be a number (of hours)."
		return
	}
	year := SubStr(date, 1, 4), yhours := date
	yhours -= year, Hours
	daysInYear := Mod(year, 4) || !Mod(year, 100) && Mod(year, 400) ? 365 : 366
	pi := 4*ATan(1)	; 3.1415926...
	gamma := 2*pi/daysInYear*(yhours - 12)/24 ; The fractional year in radians
	eqtime := 229.18*(0.000075+0.001868*Cos(gamma)-0.032077*Sin(gamma)-0.014615*Cos(2*gamma)-0.040849*Sin(2*gamma))	; In minutes
	decl := 0.006918-0.399912*Cos(gamma)+0.070257*Sin(gamma)-0.006758*Cos(2*gamma)+0.000907*Sin(2*gamma)-0.002697*Cos(3*gamma)+0.00148*Sin(3*gamma)	; Solar declination angle (in radians).
	degree_to_rad := 2*pi/360	; Coefficient of convertion from degrees to radians.
	lat := degree_to_rad*latitude	; The latitude in radians
	time_offset := eqtime + 4*longitude - 60*timezone	; In minutes
	a := Cos(lat)*Cos(decl), b := Tan(lat)*Tan(decl)
	SunTime := {sunrise:	{horizon: {}, civil: {}, nautical: {}, astronomical: {}}
			  , sunset:		{horizon: {}, civil: {}, nautical: {}, astronomical: {}}}
	angle_at_sunset := 0.8525	; The angle under horizon of the center of the Sun at sunset/sunrise in degrees.
	; It is the approximate correction for atmospheric refraction at sunrise and sunset, and the size of the solar disk. 
	; 35.4' for refraction and 31.5'/2 is a visible angle of a half of the solar disk. 35.4' + 31.5'/2 = 0.8525 degrees.
	twilight_degrees := {horizon: angle_at_sunset, civil: 6, nautical: 12, astronomical: 18} ; angles under horizon in degrees.
	for sun, obj in SunTime {	; sun is sunrise/sunset
		sunrise_coeff := (sun = "sunrise") ? 1 : -1
		for tw, deg in twilight_degrees {
			ha := sunrise_coeff/degree_to_rad*ACos(Sin(-degree_to_rad*deg)/a - b)	; The hour angle (in degrees) positive for sunrise twilights
			; and negative for sunset twilights.
			; We've used the formula: cos(ha) = sin(angle_to_horizon)/cos(Lat)/cos(decl) - tan(Lat)*tan(decl) , where ha is in radians.
			obj[tw].mins := mins := Round(720 - time_offset - 4*ha)	; The end (if sunset and start if sunrise) of current twilight stage 
			; or just sunrise/sunset time, in minutes from midnight. It can be negative or >24 hours depending on timezone.
			while (mins < 0 )
				mins += 1440	; 1440 minutes = 24 hours. We want to make the value positive.
			obj[tw].time := Format("{:02}:{:02}", Mod(mins//60, 24), Mod(mins,  60))	; In "hh:mm" format
		}
		for each, tw in order := ["horizon", "civil", "nautical", "astronomical"] {
			if (each = 1)
				continue
			obj[tw].duration := Abs(obj[tw].mins - obj[order[each-1]].mins)
		}
		obj.time := obj.horizon.time,  obj.mins := obj.horizon.mins, obj.Delete("horizon")
	}
	SunTime.day := SunTime.sunset.mins - SunTime.sunrise.mins
	SunTime.night := 1440 + SunTime.sunrise.astronomical.mins - SunTime.sunset.astronomical.mins ; The darkest part of the night
	return SunTime ; an object
}
Have found any drawback in my code or approach? Please, point it out. /The moderator ordered to remove the rest of the signature, I had obeyed.
And I really apologize for our russian president. Being a citizen of an aggressor country is very shameful. Personally I tried to avoid this trying to defend elections from fraud being a member of the election commission of one of the precincts but only was subjected to a hooligan attack and right before the vote count was illegally escorted from the polling station and spent the night behind bars (in jail) in a result of illegal actions of corrupt policemen.

User avatar
Drugwash
Posts: 850
Joined: 29 May 2014, 21:07
Location: Ploieşti, Romania
Contact:

Re: Script to run everyday at sunset

Post by Drugwash » 29 Jan 2022, 04:14

Shouldn't they all be beginnings regardless of sunrise/sunset according to the circular pattern? :?
Part of my AHK work can be found here.

amateur+
Posts: 655
Joined: 09 Oct 2021, 15:43

Re: Script to run everyday at sunset

Post by amateur+ » 29 Jan 2022, 04:23

I hardly imagine sunset.time = sunset.civil.time and day=sunrise.time.
Have found any drawback in my code or approach? Please, point it out. /The moderator ordered to remove the rest of the signature, I had obeyed.
And I really apologize for our russian president. Being a citizen of an aggressor country is very shameful. Personally I tried to avoid this trying to defend elections from fraud being a member of the election commission of one of the precincts but only was subjected to a hooligan attack and right before the vote count was illegally escorted from the polling station and spent the night behind bars (in jail) in a result of illegal actions of corrupt policemen.

User avatar
Drugwash
Posts: 850
Joined: 29 May 2014, 21:07
Location: Ploieşti, Romania
Contact:

Re: Script to run everyday at sunset

Post by Drugwash » 29 Jan 2022, 04:35

As time goes isn't it as follows?
sunrise > sunset > night civil twilight > night nautical twilight > night astronomical twilight > day astronomical twilight > day nautical twilight > day civil twilight > sunrise

My line of thinking is that each of the markers is chronologically the beginning of the respective time slice. Maybe the names are still not perfect. Maybe I'm too tired right now.
Do you have a different point of view on this? :?
Part of my AHK work can be found here.

amateur+
Posts: 655
Joined: 09 Oct 2021, 15:43

Re: Script to run everyday at sunset

Post by amateur+ » 29 Jan 2022, 04:57

Drugwash wrote:
29 Jan 2022, 04:35
As time goes isn't it as follows?
sunrise > sunset > night civil twilight > night nautical twilight > night astronomical twilight > day astronomical twilight > day nautical twilight > day civil twilight > sunrise
Yes, but if we want they all be beginnings then sunset = night civil twilight (more precisely sunset.time = <night civil twilight>.time).
Night civil twilight is a time period when the Sun is from 0.85° to 6° under the horizon. The beginning of that stage is sunset. What moment of time are we going to call <Night civil twilight>.time? 0.85° or 6°?
Have found any drawback in my code or approach? Please, point it out. /The moderator ordered to remove the rest of the signature, I had obeyed.
And I really apologize for our russian president. Being a citizen of an aggressor country is very shameful. Personally I tried to avoid this trying to defend elections from fraud being a member of the election commission of one of the precincts but only was subjected to a hooligan attack and right before the vote count was illegally escorted from the polling station and spent the night behind bars (in jail) in a result of illegal actions of corrupt policemen.

User avatar
Drugwash
Posts: 850
Joined: 29 May 2014, 21:07
Location: Ploieşti, Romania
Contact:

Re: Script to run everyday at sunset

Post by Drugwash » 29 Jan 2022, 05:07

Have you checked with the time markers here and the API examples here?
(I'm definitely too tired now, maybe got it all wrong from the very beginning :? )
Yes, sunset is the same as night civil twilight beginning so either parameter should return the same value, which is sunset.time.
Part of my AHK work can be found here.

amateur+
Posts: 655
Joined: 09 Oct 2021, 15:43

Re: Script to run everyday at sunset

Post by amateur+ » 29 Jan 2022, 05:28

Btw, maybe we indeed should call it "day_length" instead of "day"? And also "night_length"?
As for time markers yes, the function determines sunrise moment as the center of the Sun being 0.8525° under horizon (its upper edge becomes already visible because of refraction) and sunset moment as the center of the Sun being the same 0.8525° under horizon (its upper edge becomes invisible).
Have found any drawback in my code or approach? Please, point it out. /The moderator ordered to remove the rest of the signature, I had obeyed.
And I really apologize for our russian president. Being a citizen of an aggressor country is very shameful. Personally I tried to avoid this trying to defend elections from fraud being a member of the election commission of one of the precincts but only was subjected to a hooligan attack and right before the vote count was illegally escorted from the polling station and spent the night behind bars (in jail) in a result of illegal actions of corrupt policemen.

User avatar
Drugwash
Posts: 850
Joined: 29 May 2014, 21:07
Location: Ploieşti, Romania
Contact:

Re: Script to run everyday at sunset

Post by Drugwash » 29 Jan 2022, 05:48

amateur+ wrote:
29 Jan 2022, 05:28
Btw, maybe we indeed should call it "day_length" instead of "day"? And also "night_length"?
The more straightforward the better. User shouldn't struggle to discern between parameter names and their function, it could lead to confusion.

I might have made a mistake in my applet JS code in regard to civil twilight time markers. Not sure, will have to check the respective code thoroughly on a clear and fresh mind.
Part of my AHK work can be found here.

User avatar
smrt1
Posts: 30
Joined: 27 Mar 2022, 04:47

Re: Script to run everyday at sunset

Post by smrt1 » 29 Sep 2023, 23:35

SKAN wrote:
19 Jan 2022, 11:23
Hi @Drugwash
Overkill : Try Swiss Ephemeris
Spoiler
Hi,

Would you mind sharing that so we can have a working example of Swiss Ephemeris use ?

Post Reply

Return to “Ask for Help (v1)”