|
| 1 | +# example.py |
| 2 | + |
| 3 | +import datetime, suntime, time |
| 4 | + |
| 5 | +class Cet(datetime.timezone): |
| 6 | + def __init__(self): |
| 7 | + super().__init__(datetime.timedelta(hours=1), "CET") |
| 8 | + |
| 9 | + def dst(self, dt): |
| 10 | + return datetime.timedelta(hours=1) if self.isdst(dt) else datetime.timedelta(0) |
| 11 | + |
| 12 | + def tzname(self, dt): |
| 13 | + return 'CEST' if self.isdst(dt) else 'CET' |
| 14 | + |
| 15 | + def isdst(self, dt): |
| 16 | + if dt is None: |
| 17 | + return False |
| 18 | + year, month, day, hour, minute, second, tz = dt.tuple() |
| 19 | + if not 2000 <= year < 2100: |
| 20 | + raise ValueError |
| 21 | + if 3 < month < 10: |
| 22 | + return True |
| 23 | + if month == 3: |
| 24 | + beg = 31 - (5*year//4 + 4) % 7 # last Sunday of March |
| 25 | + if day < beg: return False |
| 26 | + if day > beg: return True |
| 27 | + return hour >= 3 |
| 28 | + if month == 10: |
| 29 | + end = 31 - (5*year//4 + 1) % 7 # last Sunday of October |
| 30 | + if day < end: return True |
| 31 | + if day > end: return False |
| 32 | + return hour < 3 |
| 33 | + return False |
| 34 | + |
| 35 | +# initialization |
| 36 | +CET = Cet() |
| 37 | +Rome = suntime.Sundatetime(42.5966460, 12.4360233) |
| 38 | +Rome.calc_sunrise_sunset(datetime.datetime(2000, 1, 1, tzinfo=CET)) |
| 39 | + |
| 40 | +# main loop (every minute or more) |
| 41 | +now = datetime.datetime(*time.localtime()[:5], tzinfo=CET) |
| 42 | +if (now.date() > Rome.sunset.date()): |
| 43 | + Rome.calc_sunrise_sunset(now) |
| 44 | +print (now, Rome.is_daytime(now)) |
| 45 | + |
| 46 | + |
| 47 | +####################################################################### |
| 48 | + |
| 49 | +# place: latitude longitude |
| 50 | +pl1 = ( 42.5966460, 12.4360233) # Rome |
| 51 | +pl2 = ( 51.1627938,-122.9593616) # Vancouver |
| 52 | +pl3 = (-33.9252192, 18.4240762) # CapeTown |
| 53 | +pl4 = ( 55.1574890, 82.8547661) # Novosibirsk |
| 54 | +pl5 = ( 78.6560170, 16.3447384) # Pyramiden |
| 55 | +pl6 = pl5 |
| 56 | +pl7 = (-77.7817838, 166.4561470) # McMurdo |
| 57 | +pl8 = pl7 |
| 58 | + |
| 59 | +# date: YY MM DD sunrise sunset |
| 60 | +dt1 = (2000, 1, 1) # 7:37 16:49 - https://www.timeanddate.com/sun/italy/rome?month=1&year=2000 |
| 61 | +dt2 = (2014, 10, 3) # 7:15 18:46 - https://www.timeanddate.com/sun/canada/vancouver?month=10&year=2014 |
| 62 | +dt3 = (2016, 12, 21) # 5:32 19:57 - https://www.timeanddate.com/sun/south-africa/cape-town?month=12&year=2016 |
| 63 | +dt4 = (2021, 4, 24) # 6:04 20:50 - https://www.timeanddate.com/sun/russia/novosibirsk?month=4&year=2021 |
| 64 | +dt5 = (2040, 8, 25) # up all day - https://www.timeanddate.com/sun/@2729216?month=8&year=2033 |
| 65 | +dt6 = (2040, 8, 26) # 00:09 |
| 66 | + # 1:45 23:41 - https://www.timeanddate.com/sun/@2729216?month=8&year=2040 |
| 67 | +dt7 = (2033, 8, 10) # down all day - https://www.timeanddate.com/sun/antarctica/mcmurdo?month=8&year=2033 |
| 68 | +dt8 = (2033, 10, 21) # 3:00 24:13 - https://www.timeanddate.com/sun/antarctica/mcmurdo?month=10&year=2033 |
| 69 | + |
| 70 | +# timezone offsets and DSTs (in hours) |
| 71 | +tz1 = ( 1, 0) |
| 72 | +tz2 = (-8, 1) |
| 73 | +tz3 = ( 2, 0) |
| 74 | +tz4 = ( 0, 0) # wrong; it generates negative hour because actual timezone is (7, 0) |
| 75 | +tz5 = ( 1, 1) |
| 76 | +tz6 = ( 1, 1) |
| 77 | +tz7 = (13,-1) |
| 78 | +tz8 = (13, 0) |
| 79 | + |
| 80 | + |
| 81 | +####################################################################### |
| 82 | + |
| 83 | +# if `datetime` module is available |
| 84 | +from suntime import Sundatetime |
| 85 | +from datetime import datetime, timedelta, timezone |
| 86 | + |
| 87 | +class Tz(timezone): |
| 88 | + def __init__(self, hours, dst=0): |
| 89 | + super().__init__(timedelta(hours=hours)) |
| 90 | + self._dst = dst |
| 91 | + |
| 92 | + def dst(self, dt): |
| 93 | + return timedelta(hours=self._dst) if self.isdst(dt) else timedelta(0) |
| 94 | + |
| 95 | + def isdst(self, dt): |
| 96 | + return self._dst != 0 |
| 97 | + |
| 98 | +now = datetime(*dt1, tzinfo=Tz(*tz1)) |
| 99 | +sd1 = Sundatetime(*pl1) |
| 100 | +sd1.calc_sunrise_sunset(now) |
| 101 | +print('Rome:', now) |
| 102 | +print('>', sd1.sunrise) # 2000-01-01 07:40:00+01:00 |
| 103 | +print('>', sd1.sunset ) # 2000-01-01 16:47:00+01:00 |
| 104 | + |
| 105 | +now = datetime(*dt2, tzinfo=Tz(*tz2)) |
| 106 | +sd2 = Sundatetime(*pl2) |
| 107 | +sd2.calc_sunrise_sunset(now) |
| 108 | +print('Vancouver:', now) |
| 109 | +print('>', sd2.sunrise) # 2014-10-03 07:16:00-08:00 |
| 110 | +print('>', sd2.sunset ) # 2014-10-03 18:46:00-08:00 |
| 111 | + |
| 112 | +now = datetime(*dt3, tzinfo=Tz(*tz3)) |
| 113 | +sd3 = Sundatetime(*pl3) |
| 114 | +sd3.calc_sunrise_sunset(now) |
| 115 | +print('Cape Town:', now) |
| 116 | +print('>', sd3.sunrise) # 2016-12-21 05:32:00+02:00 |
| 117 | +print('>', sd3.sunset ) # 2016-12-21 19:57:00+02:00 |
| 118 | + |
| 119 | +now = datetime(*dt4, tzinfo=Tz(*tz4)) |
| 120 | +sd4 = Sundatetime(*pl4) |
| 121 | +sd4.calc_sunrise_sunset(now) |
| 122 | +print('Novosibirsk:', now) |
| 123 | +print('>', sd4.sunrise) # 2021-04-23 23:04:00+00:00 |
| 124 | +print('>', sd4.sunset ) # 2021-04-24 13:49:00+00:00 |
| 125 | + |
| 126 | +now = datetime(*dt5, tzinfo=Tz(*tz5)) |
| 127 | +sd5 = Sundatetime(*pl5) |
| 128 | +sd5.calc_sunrise_sunset(now) |
| 129 | +print('Pyramiden:', now) |
| 130 | +print('>', sd5.sunrise) # 2040-08-24 12:57:00+02:00 |
| 131 | +print('>', sd5.sunset ) # 2040-08-26 12:57:00+02:00 |
| 132 | + |
| 133 | +now = datetime(*dt6, tzinfo=Tz(*tz6)) |
| 134 | +sd6 = Sundatetime(*pl6) |
| 135 | +sd6.calc_sunrise_sunset(now) |
| 136 | +print('Pyramiden:', now) |
| 137 | +print('>', sd6.sunrise) # 2040-08-26 01:35:00+02:00 |
| 138 | +print('>', sd6.sunset ) # 2040-08-27 00:18:00+02:00 |
| 139 | + |
| 140 | +now = datetime(*dt7, tzinfo=Tz(*tz7)) |
| 141 | +sd7 = Sundatetime(*pl7) |
| 142 | +sd7.calc_sunrise_sunset(now) |
| 143 | +print('McMurdo:', now) |
| 144 | +print('>', sd7.sunrise) # 2033-08-11 13:00:00+12:00 |
| 145 | +print('>', sd7.sunset ) # 2033-08-09 13:00:00+12:00 |
| 146 | + |
| 147 | +now = datetime(*dt8, tzinfo=Tz(*tz8)) |
| 148 | +sd8 = Sundatetime(*pl8) |
| 149 | +sd8.calc_sunrise_sunset(now) |
| 150 | +print('McMurdo:', now) |
| 151 | +print('>', sd8.sunrise) # 2033-10-21 03:06:00+13:00 |
| 152 | +print('>', sd8.sunset ) # 2033-10-22 00:12:00+13:00 |
| 153 | + |
| 154 | + |
| 155 | +####################################################################### |
| 156 | + |
| 157 | +from suntime import Suntime |
| 158 | + |
| 159 | +st1 = Suntime(*pl1, timezone=tz1[0]*60) |
| 160 | +st1.calc_sunrise_sunset(*dt1, dst=tz1[1]*60) |
| 161 | +print('Rome:', dt1, tz1) |
| 162 | +print('>', divmod(st1.sunrise, 60)) # (7, 40) |
| 163 | +print('>', divmod(st1.sunset , 60)) # (16, 47) |
| 164 | + |
| 165 | +st2 = Suntime(*pl2, timezone=tz2[0]*60) |
| 166 | +st2.calc_sunrise_sunset(*dt2, dst=tz2[1]*60) |
| 167 | +print('Vancouver:', dt2, tz2) |
| 168 | +print('>', divmod(st2.sunrise, 60)) # (7, 16) |
| 169 | +print('>', divmod(st2.sunset , 60)) # (18, 46) |
| 170 | + |
| 171 | +st3 = Suntime(*pl3, timezone=tz3[0]*60) |
| 172 | +st3.calc_sunrise_sunset(*dt3, dst=tz3[1]*60) |
| 173 | +print('Cape Town:', dt3, tz3) |
| 174 | +print('>', divmod(st3.sunrise, 60)) # (5, 32) |
| 175 | +print('>', divmod(st3.sunset , 60)) # (19, 57) |
| 176 | + |
| 177 | +st4 = Suntime(*pl4, timezone=tz4[0]*60) |
| 178 | +st4.calc_sunrise_sunset(*dt4, dst=tz4[1]*60) |
| 179 | +print('Novosibirsk:', dt4, tz4) |
| 180 | +print('>', divmod(st4.sunrise, 60)) # (-1, 4) |
| 181 | +print('>', divmod(st4.sunset , 60)) # (13, 49) |
| 182 | + |
| 183 | +st5 = Suntime(*pl5, timezone=tz5[0]*60) |
| 184 | +st5.calc_sunrise_sunset(*dt5, dst=tz5[1]*60) |
| 185 | +print('Pyramiden:', dt5, tz5) |
| 186 | +print('>', divmod(st5.sunrise, 60)) # (-12, 57) |
| 187 | +print('>', divmod(st5.sunset , 60)) # (36, 57) |
| 188 | + |
| 189 | +st6 = Suntime(*pl6, timezone=tz6[0]*60) |
| 190 | +st6.calc_sunrise_sunset(*dt6, dst=tz6[1]*60) |
| 191 | +print('Pyramiden:', dt6, tz6) |
| 192 | +print('>', divmod(st6.sunrise, 60)) # (1, 35) |
| 193 | +print('>', divmod(st6.sunset , 60)) # (24, 18) |
| 194 | + |
| 195 | +st7 = Suntime(*pl7, timezone=tz7[0]*60) |
| 196 | +st7.calc_sunrise_sunset(*dt7, dst=tz7[1]*60) |
| 197 | +print('McMurdo:', dt7, tz7) |
| 198 | +print('>', divmod(st7.sunrise, 60)) # (37, 0) |
| 199 | +print('>', divmod(st7.sunset , 60)) # (-11, 0) |
| 200 | + |
| 201 | +st8 = Suntime(*pl8, timezone=tz8[0]*60) |
| 202 | +st8.calc_sunrise_sunset(*dt8, dst=tz8[1]*60) |
| 203 | +print('McMurdo:', dt8, tz8) |
| 204 | +print('>', divmod(st8.sunrise, 60)) # (3, 6) |
| 205 | +print('>', divmod(st8.sunset , 60)) # (24, 12) |
0 commit comments