Open oneuxco opened 6 years ago
It seems like SunCalc will always calculate sun times in the local time zone. I managed to work around this issue with the following approach.
Where,
Given,
const tzB = tzLookup(B.lat, b.lng)
const currentTimeAtB = DateTime.fromISO(new Date().toISOString(), { zone: tzB })
const suntimesAtB_in_tzA = SunCalc.getTimes(new Date(currentTimeAtB), B.lat, B.lng)
const sunriseAtB_in_tzB = DateTime.fromISO(suntimesAtB_in_tzA.sunrise.toISOString(), { zone: tzB })
thanks men is working 👌
Also would like a fix for this. AWS machines are always set to UTC.
@SrGrieves Does the workaround I posted work for you? I also blogged about it at https://tech.beyondtracks.com/posts/sun-times/
@andrewharvey I'm working on an embedded system. Adding two additional external libraries is something I'd like to avoid. I like that SunCalc is small and self-sufficient.
@andrewharvey I have tried your script and it seems to works but only if I edit "toJulian" function (with this ) isn't it?
@ottopic I didn't do that, though my times could be a day off without it. I haven't done that detailed testing. If that's the case, good catch.
It seems like SunCalc will always calculate sun times in the local time zone. I managed to work around this issue with the following approach.
Where,
Given,
- Location A is where the user is located (in time zone A)
- Location B is where you want to calculate the sun times for in time zone B
const tzB = tzLookup(B.lat, b.lng) const currentTimeAtB = DateTime.fromISO(new Date().toISOString(), { zone: tzB }) const suntimesAtB_in_tzA = SunCalc.getTimes(new Date(currentTimeAtB), B.lat, B.lng) const sunriseAtB_in_tzB = DateTime.fromISO(suntimesAtB_in_tzA.sunrise.toISOString(), { zone: tzB })
This saved me hours of figuring out how to do the transformation. Such a nice little library but in so many applications you have to operate with UTC times.
For a personal project I ended up creating an NPM package of a modified suncalc
to do this. It's called suncalc-tz, if anyone comes across this and is looking for something quick and dirty, might be worth a try. I wouldn't recommend it for production though, I haven't thoroughly tested it.
Similar to the code above, the package basically just pulls in a minified tzlookup to get the timezone and combines that with the Intl
standard library:
// Convert dates to the time at lat/lng
for (let time in result) {
const options = {timeZone: tz, year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric'};
result[time] = new Date(Date.parse(new Intl.DateTimeFormat('default', options).format(result[time])));
}
For a personal project I ended up creating an NPM package of a modified
suncalc
to do this. It's called suncalc-tz, if anyone comes across this and is looking for something quick and dirty, might be worth a try. I wouldn't recommend it for production though, I haven't thoroughly tested it.Similar to the code above, the package basically just pulls in a minified tzlookup to get the timezone and combines that with the
Intl
standard library:// Convert dates to the time at lat/lng for (let time in result) { const options = {timeZone: tz, year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric'}; result[time] = new Date(Date.parse(new Intl.DateTimeFormat('default', options).format(result[time]))); }
Found a minor issue - it crashes for high latitudes where some of the values are not available (for example, in summer there is no nautical dusk / dawn or night in Iceland). I think that the fix should be as easy as adding if ( !isNaN(result[time]) ) {Â ... }
around the conversion, so I didn't bother with a pull request.
This will probably not work for regions that implement day light saving?
const { sunrise } = getTimes(new Date(), lat, lon);
const tzOffset = sunrise.getTimezoneOffset();
console.log('Corrected time', new Date(sunrise.getTime() - tzOffset * 60000));
If you're only calling getPosition
, you can pass in a UTC epoch int in milliseconds for the time, rather than a Date
object, as the function only calls valueOf
on that parameter.
If I live in GMT-7 (DST), and look up New York coordinates, the times are all messed up.
I made a date variable that is specific for New York (or the location given by user) but the suncalc still screws up the timing...is there any fix for this?
Thanks!