- Offizieller Beitrag
Ich brauchte ein Script, dass einem die Jahreszeit (Frühling, Sommer, Herbst und Winter) zu einem Datum ausgibt.
Und weil ich sowas nicht gefunden habe, habe ich es halt selbst geschrieben.
Falls das noch jemand gebrauchen kann:
AutoIt
#include <Array.au3>
#include <Date.au3>
; Beispiel fuer die Rueckgabe der Jahreszeit zu einem Datum
Global $sDate = '2017/04/03 00:00:00'
MsgBox(0, 'Jahreszeit', 'Gesuchtes Datum: ' & @CRLF & $sDate & ' -> ' & _GetSeason(1, $sDate))
; Beispiel fuer die Auflistung wann die Jahreszeiten in einem Jahr beginnen
Global Const $sEPOCH = '1970/01/01 00:00:00'
Global $sDate = '2017/12/31 00:00:00' ; <- Startdatum muss der 31. Dezember des gesuchten Jahres sein
Global $aSeasonDate[4][2]
For $i = 3 To 0 Step -1
$aSeasonDate[$i][0] = _GetSeason(1, $sDate) ; die Funktion gibt den Jahreszeitnamen zurueck
$sDate = _DateAdd('s', @extended, $sEPOCH) ; @extended enthält den Anfang der Jahreszeit (in Unixzeit)
$aSeasonDate[$i][1] = $sDate
Next
_ArrayDisplay($aSeasonDate, 'Jahreszeiten ' & StringLeft($sDate, 4) + 1, '', 16 + 64, '|', 'Jahreszeit|Anfang')
;===============================================================================
; Function Name: _GetSeason([$iLanguage][, $sDate])
; Description: Gibt die Jahreszeit zurueck von einem uebergebenen Datum (nur fuer die Jahre zwischen 2000 und 3000 moeglich)
; Parameter(s): $iLanguage = 0 (Englisch) oder 1 (Deutsch)
; $sDate = Datum und Uhrzeit im Format: 'YYYY/MM/DD[ hh:mm:ss]'
; Requirement(s): ---
; Return Value(s): den Namen der Jahreszeit und als @extended den Anfang der Jahreszeit (in Unixzeit)
; Author(s): Oscar (www.autoit.de)
;===============================================================================
Func _GetSeason($iLanguage = 0, $sDate = _NowCalc())
If Not _DateIsValid($sDate) Then Return SetError(1, 0, 'error')
Local Const $aSEASONNAMES[2][4] = [ _ ; die Jahreszeiten-Namen in Englisch (0) und Deutsch (1)
['Spring', 'Summer', 'Autumn', 'Winter'], _
['Frühling', 'Sommer', 'Herbst', 'Winter']]
If $iLanguage < 0 Or $iLanguage >= UBound($aSEASONNAMES) Then $iLanguage = 0
If StringLeft($sDate, 4) < 2000 Or StringLeft($sDate, 4) > 3000 Then Return SetError(2, 0, 'error') ; die Sekunden pro Jahreszeit gelten nur fuer die Jahre zwischen 2000 und 3000
Local Const $aSEASONTICKS[4] = [8014464, 8091360, 7762176, 7688736] ; Sekunden pro Jahreszeit (Fruehling, Sommer, Herbst, Winter)
Local Const $sEPOCH = '1970/01/01 00:00:00'
Local $iStart = _DateDiff('s', $sEPOCH, '2000/03/20 08:35:00') ; Unixzeit vom Fruehlingsanfang im Jahr 2000 -> '2000/03/20 08:35:00'
Local $iSeasonCount = 0 ; Fruehlingsanfang als Start-Jahreszeit
Local $iDate = _DateDiff('s', $sEPOCH, $sDate) ; Unixzeit vom gesuchten Datum
If $iDate < $iStart Then Return SetError(3, 0, 'error') ; kein Datum vor Fruehlingsanfang 2000 erlaubt
While $iStart + $aSEASONTICKS[$iSeasonCount] < $iDate ; die Schleife solange durchlaufen bis das gesuchte Datum erreicht ist
$iStart += $aSEASONTICKS[$iSeasonCount] ; zu der Start-Unixzeit die Sekunden der Jahreszeit addieren
$iSeasonCount += 1 ; die naechste Jahreszeit
If $iSeasonCount > 3 Then $iSeasonCount = 0 ; wenn der Winter addiert wurde, dann wieder mit Fruehling fortfahren
WEnd
Return SetError(0, $iStart, $aSEASONNAMES[$iLanguage][$iSeasonCount]) ; Jahreszeit zurueckgeben
EndFunc ;==>_GetSeason
Alles anzeigen
Edit: Das obige Script ist nicht so genau, wenn es um die Uhrzeit der Jahreszeiten-Anfänge geht. Das hängt mit der einfachen Berechnung für die Jahreszeiten-Länge zusammen.
Ich habe aber noch eine andere Berechnung im Internet gefunden und diese nach AutoIt portiert. Damit liegt die Genauigkeit bei +/- 30 Sekunden.
Und das Script ("_CalcSeason.au3", im Anhang) sieht so aus:
AutoIt
#include <Array.au3>
#include <Date.au3>
Global $iYear = 2017 ; <- das Jahr, dessen Jahreszeiten berechnet werden soll
Global $UTC, $LocalTime, $aSeasons[4][3] = [['Frühling', '', ''], ['Sommer', '', ''], ['Herbst', '', ''], ['Winter', '', '']]
For $iSeason = 0 To 3 ; die 4 Jahreszeiten durchgehen
$UTC = _calcEquiSol($iSeason, $iYear) ; die Jahreszeit berechnen (UTC)
$LocalTime = _UTCtoLocalTime($UTC, False) ; ohne Formatierung in die Lokalzeit umwandeln
$aSeasons[$iSeason][1] = $LocalTime
;~ ConsoleWrite('>> ' & $LocalTime & @CR)
$LocalTime = _UTCtoLocalTime($UTC, True) ; mit Formatierung in die Lokalzeit umwandeln
$aSeasons[$iSeason][2] = $LocalTime
;~ ConsoleWrite('-> ' & $LocalTime & @CR)
Next
_ArrayDisplay($aSeasons, 'Jahreszeiten ' & $iYear, '', 16 + 64, Default, ' |ohne Format|mit Format')
; Author: Oscar (www.autoit.de)
Func _UTCtoLocalTime($UTC, $fFormat = False)
Local $aDate, $aTime
_DateTimeSplit($UTC, $aDate, $aTime) ; UTC aufsplitten
Local $tSystem = _Date_Time_EncodeSystemTime($aDate[2], $aDate[3], $aDate[1], $aTime[1], $aTime[2], $aTime[3]) ; in Systemzeit umwandeln
Local $tLocal = _Date_Time_SystemTimeToTzSpecificLocalTime($tSystem) ; Zeitzone + Sommerzeit beruecksichtigen
Local $sLocalTime = _Date_Time_SystemTimeToDateTimeStr($tLocal, 1) ; ins Format "yyyy/mm/dd hh:mm:ss"
If Not $fFormat Then Return $sLocalTime ; wenn keine formatierte Ausgabe gewuenscht, dann so zurueckgeben
_DateTimeSplit($sLocalTime, $aDate, $aTime) ; ansonsten Lokalzeit aufsplitten
Local $iWeekday = _DateToDayOfWeek($aDate[1], $aDate[2], $aDate[3]) ; Wochentag berechnen
Return _DateDayOfWeek($iWeekday, 3) & '. ' & _DateTimeFormat($sLocalTime, 0) ; und formatiert zurueckgeben
EndFunc ;==>_UTCtoLocalTime
; die folgenden Funktionen habe ich von Javascript nach AutoIt uebersetzt
; die Javascript-Funktionen stammen von "http://stellafane.org/misc/equinox.html"
;
; -----Calculate a single event for a single year (Either a Equiniox or Solstice)--------
; Meeus Astronmical Algorithms Chapter 27
Func _calcEquiSol($season, $year)
Local Const $PI = 3.14159265358979, $fDegToRad = $PI / 180
Local $JDE0 = _calcInitial($season, $year) ; Initial estimate of date of event
Local $T = ($JDE0 - 2451545) / 36525
Local $W = 35999.373 * $T - 2.47
Local $dL = 1 + 0.0334 * Cos($W * $fDegToRad) + 0.0007 * Cos((2 * $W) * $fDegToRad)
Local $S = _periodic24($T)
Local $JDE = $JDE0 + ((0.00001 * $S) / $dL) ; This is the answer in Julian Emphemeris Days
Local $TDT = _fromJDtoTDT($JDE) ; Convert Julian Days to TDT at this format "yyyy/mm/dd hh:mm:ss"
Local $UTC = _fromTDTtoUTC($TDT) ; Convert TDT to UTC at this format "yyyy/mm/dd hh:mm:ss"
Return $UTC
EndFunc ;==>_calcEquiSol
; -----Calculate an initial guess as the JD of the Equinox or Solstice of a Given Year
; Meeus Astronmical Algorithms Chapter 27
Func _calcInitial($season, $year) ; Valid for years 1000 to 3000
Local Enum $Spring, $Summer, $Autumn, $Winter
Local $JDE = 0, $Y = ($year - 2000) / 1000
Switch $season
Case $Spring
$JDE = 2451623.80984 + 365242.37404 * $Y + 0.05169 * $Y ^ 2 - 0.00411 * $Y ^ 3 - 0.00057 * $Y ^ 4
Case $Summer
$JDE = 2451716.56767 + 365241.62603 * $Y + 0.00325 * $Y ^ 2 + 0.00888 * $Y ^ 3 - 0.00030 * $Y ^ 4
Case $Autumn
$JDE = 2451810.21715 + 365242.01767 * $Y - 0.11575 * $Y ^ 2 + 0.00337 * $Y ^ 3 + 0.00078 * $Y ^ 4
Case $Winter
$JDE = 2451900.05952 + 365242.74049 * $Y - 0.06223 * $Y ^ 2 - 0.00823 * $Y ^ 3 + 0.00032 * $Y ^ 4
EndSwitch
Return $JDE
EndFunc ;==>_calcInitial
; -----Calculate 24 Periodic Terms----------------------------------------------------
; Meeus Astronmical Algorithms Chapter 27
Func _periodic24($T)
Local Const $PI = 3.14159265358979, $fDegToRad = $PI / 180
Local $A[] = [485, 203, 199, 182, 156, 136, 77, 74, 70, 58, 52, 50, 45, 44, 29, 18, 17, 16, 14, 12, 12, 12, 9, 8]
Local $B[] = [324.96, 337.23, 342.08, 27.85, 73.14, 171.52, 222.54, 296.72, 243.58, 119.81, 297.17, 21.02, 247.54, 325.15, 60.93, 155.12, 288.79, 198.04, 199.76, 95.39, 287.11, 320.81, 227.73, 15.45]
Local $C[] = [1934.136, 32964.467, 20.186, 445267.112, 45036.886, 22518.443, 65928.934, 3034.906, 9037.513, 33718.147, 150.678, 2281.226, 29929.562, 31555.956, 4443.417, 67555.328, 4562.452, 62894.029, 31436.921, 14577.848, 31931.756, 34777.259, 1222.114, 16859.074]
Local $S = 0
For $i = 0 To 23
$S += $A[$i] * Cos(($B[$i] + ($C[$i] * $T)) * $fDegToRad)
Next
Return $S
EndFunc ;==>_periodic24
; -----Julian Date to TDT----------------------------------------------------------------
; Meeus Astronmical Algorithms Chapter 7
Func _fromJDtoTDT($JD)
Local $A, $alpha
Local $Z = Int($JD + 0.5)
Local $F = ($JD + 0.5) - $Z
If $Z < 2299161 Then
$A = $Z
Else
$alpha = Int(($Z - 1867216.25) / 36524.25)
$A = $Z + 1 + $alpha - Int($alpha / 4)
EndIf
Local $B = $A + 1524
Local $C = Int(($B - 122.1) / 365.25)
Local $D = Int(365.25 * $C)
Local $E = Int(($B - $D) / 30.6001)
Local $DT = $B - $D - Int(30.6001 * $E) + $F ; Day of Month with decimals for time
Local $Mon = $E - ($E < 14 ? 1 : 13) ; Month Number
Local $Yr = $C - ($Mon > 2 ? 4716 : 4715) ; Year
Local $Day = Int($DT) ; Day of Month without decimals for time
Local $H = 24 * ($DT - $Day) ; Hours and fractional hours
Local $Hr = Int($H) ; Integer Hours
Local $M = 60 * ($H - $Hr) ; Minutes and fractional minutes
Local $Min = Int($M) ; Integer Minutes
Local $Sec = Int(60 * ($M - $Min)) ; Integer Seconds (Milliseconds discarded)
Return StringFormat('%04d/%02d/%02d %02d:%02d:%02d', $Yr, $Mon, $Day, $Hr, $Min, $Sec)
EndFunc ;==>_fromJDtoTDT
; -----Correct TDT to UTC----------------------------------------------------------------
; TDT (Terrestial Dynamical Time) was used 1984-2000
; was replaced by TT (Terrestial Time) in 2001.
Func _fromTDTtoUTC($TDT)
; from Meeus Astronmical Algroithms Chapter 10
; Correction lookup table has entry for every even year between TBLfirst and TBLlast
Local $TBLfirst = 1620, $TBLlast = 2018 ; Range of years in lookup table
Local $TBL[] = [ _ ; Corrections in Seconds
121, 112, 103, 95, 88, 82, 77, 72, 68, 63, 60, 56, 53, 51, 48, 46, 44, 42, 40, 38, _ ; 1620
35, 33, 31, 29, 26, 24, 22, 20, 18, 16, 14, 12, 11, 10, 9, 8, 7, 7, 7, 7, _ ; 1660
7, 7, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, _ ; 1700
11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 16, _ ; 1740
16, 16, 16, 16, 16, 16, 15, 15, 14, 13, _ ; 1780
13.1, 12.5, 12.2, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 11.9, 11.6, 11.0, 10.2, 9.2, 8.2, _ ; 1800
7.1, 6.2, 5.6, 5.4, 5.3, 5.4, 5.6, 5.9, 6.2, 6.5, 6.8, 7.1, 7.3, 7.5, 7.6, _ ; 1830
7.7, 7.3, 6.2, 5.2, 2.7, 1.4, -1.2, -2.8, -3.8, -4.8, -5.5, -5.3, -5.6, -5.7, -5.9, _ ; 1860
- 6.0, -6.3, -6.5, -6.2, -4.7, -2.8, -0.1, 2.6, 5.3, 7.7, 10.4, 13.3, 16.0, 18.2, 20.2, _ ; 1890
21.1, 22.4, 23.5, 23.8, 24.3, 24.0, 23.9, 23.9, 23.7, 24.0, 24.3, 25.3, 26.2, 27.3, 28.2, _ ; 1920
29.1, 30.0, 30.7, 31.4, 32.2, 33.1, 34.0, 35.0, 36.5, 38.3, 40.2, 42.2, 44.5, 46.5, 48.5, _ ; 1950
50.5, 52.5, 53.8, 54.9, 55.8, 56.9, 58.3, 60.0, 61.6, 63.0, _ ; 1980
63.8, 64.3, 64.5, 64.8, 65.4, 66.0, 66.6, 67.2, 68.1, 69.2] ; 2000 - 2018 (2018 = prediction)
Local $deltaT = 0 ; deltaT = TDT - UTC (in Seconds)
Local $year = Number(StringLeft($TDT, 4))
Local $T = ($year - 2000) / 100 ; Centuries from the epoch 2000
If $year >= $TBLfirst And $year <= $TBLlast Then ; Find correction in table
If Mod($year, 2) Then ; Odd year - Interpolate
$deltaT = ($TBL[($year - $TBLfirst - 1) / 2] + $TBL[($year - $TBLfirst + 1) / 2]) / 2
Else ; Even year - direct table lookup
$deltaT = $TBL[($year - $TBLfirst) / 2]
EndIf
ElseIf $year < 948 Then
$deltaT = 2177 + 497 * $T + 44.1 * $T ^ 2
ElseIf $year >= 948 Then
$deltaT = 102 + 102 * $T + 25.3 * $T ^ 2
If $year >= 2000 And $year <= 2100 Then
$deltaT += 0.37 * ($year - 2100) ; Special correction to avoid discontinurity in 2000
EndIf
Else
Return SetError(1, 0, 0)
EndIf
Return _DateAdd('s', -Int($deltaT), $TDT)
EndFunc ;==>_fromTDTtoUTC
Alles anzeigen