可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'd like to extract only the month and day from a timestamp using the datetime module (not time) and then determine if it falls within a given season (fall, summer, winter, spring) based on the fixed dates of the solstices and equinoxes.
For instance, if the date falls between March 21 and June 20, it is spring. Regardless of the year. I want it to just look at the month and day and ignore the year in this calculation.
I've been running into trouble using this because the month is not being extracted properly from my data, for this reason.
回答1:
if the date falls between March 21 and June 20, it is spring.
Regardless of the year. I want it to just look at the month and day
and ignore the year in this calculation.
#!/usr/bin/env python
from datetime import date, datetime
Y = 2000 # dummy leap year to allow input X-02-29 (leap day)
seasons = [('winter', (date(Y, 1, 1), date(Y, 3, 20))),
('spring', (date(Y, 3, 21), date(Y, 6, 20))),
('summer', (date(Y, 6, 21), date(Y, 9, 22))),
('autumn', (date(Y, 9, 23), date(Y, 12, 20))),
('winter', (date(Y, 12, 21), date(Y, 12, 31)))]
def get_season(now):
if isinstance(now, datetime):
now = now.date()
now = now.replace(year=Y)
return next(season for season, (start, end) in seasons
if start <= now <= end)
print(get_season(date.today()))
It is an extended version of @Manuel G answer to support any year.
回答2:
It might be easier just to use the day of year parameter. It's not much different than your approach, but possibly easier to understand than the magic numbers.
# get the current day of the year
doy = datetime.today().timetuple().tm_yday
# "day of year" ranges for the northern hemisphere
spring = range(80, 172)
summer = range(172, 264)
fall = range(264, 355)
# winter = everything else
if doy in spring:
season = 'spring'
elif doy in summer:
season = 'summer'
elif doy in fall:
season = 'fall'
else:
season = 'winter'
回答3:
This is how I finally solved it. I doubt this is the best solution, but it works. Feel free to offer better solutions.
import datetime
def get_season(date):
"""
convert date to month and day as integer (md), e.g. 4/21 = 421, 11/17 = 1117, etc.
"""
m = date.month * 100
d = date.day
md = m + d
if ((md >= 301) and (md <= 531)):
s = 0 # spring
elif ((md > 531) and (md < 901)):
s = 1 # summer
elif ((md >= 901) and (md <= 1130)):
s = 2 # fall
elif ((md > 1130) and (md <= 0229)):
s = 3 # winter
else:
raise IndexError("Invalid date")
return s
season = get_season(dt.date())
回答4:
The hemisphere that you are in must be taken into account. You must determine the hemisphere using geolocation yourself.
def season(self, HEMISPHERE):
date = self.now()
md = date.month * 100 + date.day
if ((md > 320) and (md < 621)):
s = 0 #spring
elif ((md > 620) and (md < 923)):
s = 1 #summer
elif ((md > 922) and (md < 1223)):
s = 2 #fall
else:
s = 3 #winter
if not HEMISPHERE == 'north':
s = (s + 2) % 3
return s
回答5:
I came here looking how to map dates to seasons, and based on this answer I finally solved it in the following way:
def season_of_date(date):
year = str(date.year)
seasons = {'spring': pd.date_range(start='21/03/'+year, end='20/06/'+year),
'summer': pd.date_range(start='21/06/'+year, end='22/09/'+year),
'autumn': pd.date_range(start='23/09/'+year, end='20/12/'+year)}
if date in seasons['spring']:
return 'spring'
if date in seasons['summer']:
return 'summer'
if date in seasons['autumn']:
return 'autumn'
else:
return 'winter'
# Assuming df has a date column of type `datetime`
df['season'] = df.date.map(season_of_date)
So in principle it works for any year, given a datetime
.
回答6:
This is what i normally use:
seasons = {'Summer':(datetime(2014,6,21), datetime(2014,9,22)),
'Autumn':(datetime(2014,9,23), datetime(2014,12,20)),
'Spring':(datetime(2014,3,21), datetime(2014,6,20))}
def get_season(date):
for season,(season_start, season_end) in seasons.items():
if date>=season_start and date<= season_end:
return season
else:
return 'Winter'
回答7:
I'm too new to comment, and my edit was rejected, so here is corrected code for @adsf reponse.
def season(date, hemisphere):
''' date is a datetime object
hemisphere is either 'north' or 'south', dependent on long/lat.
'''
md = date.month * 100 + date.day
if ((md > 320) and (md < 621)):
s = 0 #spring
elif ((md > 620) and (md < 923)):
s = 1 #summer
elif ((md > 922) and (md < 1223)):
s = 2 #fall
else:
s = 3 #winter
if hemisphere != 'north':
if s < 2:
s += 2
else:
s -= 2
return s