Is winter coming? `seasoning.js` adds season awareness to your programs.
/* | |
`seasoning.js` adds season awareness to your programs. Help finding out what season it is. | |
Usage: | |
// Get the season using the user's browser location (NOTE: it requires the user's authorisation) | |
seasoning.getSeason() | |
.then(console.log); | |
// Get the season using the user's geoip | |
seasoning.getSeason({ locationProvider: 'ipinfo' }) | |
.then(console.log); | |
// Get the season providing the location (NOTE: only the latitude matters) | |
seasoning.getSeason({ latLng: { lat: -123 } }) | |
.then(console.log); | |
// Get the season giving the date | |
const date = new Date(); | |
date.setMonth((date.getMonth()+6)%12); | |
seasoning.getSeason({ date }) | |
.then(console.log); | |
// Get the "opposite" season | |
seasoning.getOppositeSeason({ date: new Date() }) | |
.then(console.log); | |
// Create your own helpers; | |
const isWinterComing = () => { | |
return seasoning.getSeason() | |
.then(season => season === 'autumn'); | |
}; | |
isWinterComing().then(winterComing => { | |
if (winterComing) { | |
console.log("The ennemy of my ennemy is my friend? Naaaah let's just keep killing the Starks."); | |
} else { | |
console.log("Either this is already winter and the undead are unleashed, or we're good for another scene with either incest, or boobs, or both... I feel like watching season 1."); | |
} | |
}); | |
*/ | |
const HEMISPHERES = { | |
north: [ | |
{ month: 'jan', season: 'winter' }, | |
{ month: 'feb', season: 'winter' }, | |
{ month: 'mar', season: 'spring' }, | |
{ month: 'apr', season: 'spring' }, | |
{ month: 'may', season: 'spring' }, | |
{ month: 'jun', season: 'summer' }, | |
{ month: 'jul', season: 'summer' }, | |
{ month: 'aug', season: 'summer' }, | |
{ month: 'sep', season: 'autumn' }, | |
{ month: 'oct', season: 'autumn' }, | |
{ month: 'nov', season: 'autumn' }, | |
{ month: 'dev', season: 'winter' }, | |
], | |
south: [ | |
{ month: 'jan', season: 'summer' }, | |
{ month: 'feb', season: 'summer' }, | |
{ month: 'mar', season: 'autumn' }, | |
{ month: 'apr', season: 'autumn' }, | |
{ month: 'may', season: 'autumn' }, | |
{ month: 'jun', season: 'winter' }, | |
{ month: 'jul', season: 'winter' }, | |
{ month: 'aug', season: 'winter' }, | |
{ month: 'sep', season: 'spring' }, | |
{ month: 'oct', season: 'spring' }, | |
{ month: 'nov', season: 'spring' }, | |
{ month: 'dev', season: 'summer' }, | |
], | |
}; | |
const GEOLOCATION_OPTIONS = { | |
enableHighAccuracy: true, | |
timeout: 5000, | |
maximumAge: 0, | |
}; | |
const makeRemoteProvider = (url, transform) => () => fetch(url, { | |
headers: { Accept: 'application/json' }, | |
}) | |
.then(r => r.json()) | |
.then(makeRemoteProvider); | |
const locationProviders = { | |
browser() { | |
return new Promise((res, rej) => { | |
navigator.geolocation.getCurrentPosition( | |
({ coords }) => res({ lat: coords.latitude, lng: coords.longitude }), | |
error => rej(error), | |
GEOLOCATION_OPTIONS | |
); | |
}); | |
}, | |
ipinfo: makeRemoteProvider('https://ipinfo.io/json', ({ loc }) => { | |
const latLng = loc.split(','); | |
return { lat: latLng[0], lng: latLng[1] }; | |
}), | |
}; | |
const getLatLng = provider => { | |
let p = provider; | |
if (!provider) { | |
p = navigator.geolocation ? 'browser' : 'ipinfo'; | |
} | |
return locationProviders[p](); | |
}; | |
const seasoning = { | |
async getHemisphere(latLng, locationProvider) { | |
const { lat: latitude } = latLng || await getLatLng(locationProvider); | |
return Promise.resolve(latitude > 0 ? 'north' : 'south'); | |
}, | |
async getSeason({ date, latLng, locationProvider } = {}) { | |
const hemisphere = await this.getHemisphere(latLng, locationProvider); | |
const monthIndex = (date || new Date()).getMonth(); | |
return Promise.resolve(HEMISPHERES[hemisphere][monthIndex].season); | |
}, | |
getOppositeSeason({ date, ...params }) { | |
const newDate = date ? new Date(date) : new Date(); | |
newDate.setMonth((date.getMonth()+6)%12); // the following only works with 12 months' years | |
return this.getSeason(Object.assign(params, { date: newDate })); | |
}, | |
}; | |
export default seasoning; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment