timotejroiko / sweph

The definitive Swiss Ephemeris bindings for Node.js
Other
93 stars 15 forks source link

Wrong sunrise time for negative timezones #12

Open prateek-intelegencia opened 11 months ago

prateek-intelegencia commented 11 months ago

I am trying to get sunrise time of:

longitude: 112.06666667
latitude: 33.45000000
timezone: -7
elevation: 330
year: 2023
month: 10
date: 1
hour: 0
minute: 0
second: 0

I converted the above date time to UTC and then to julian date which came to: 2460218.7916674046

Then I used rise_trans function from sweph package. Here is the code

rise_trans(
      2460218.7916674046,
      0, // Planet sun
      null,
      2, // flag.SWIEPH,
      1, // For rising 
      [112.06666667, 33.45000000, 330],
      0,
      0,
    )

I am getting this result in Julian date: 2460218.928608603, when converted to UTC it becomes 2023-10-01 10:17:00 (which is wrong) because in local time the sunrise time becomes at 3:17 AM

timotejroiko commented 11 months ago

Hello, could you describe all the steps you took for the entire process? In my tests everything is working correctly.

Also, are you using the latest version or the GPL version? When I run rise_trans() with the exact same parameters you posted, I get 2460219.434819401 and not 2460218.928608603.

Hrsikesa108 commented 4 months ago

Hi Timotejroiko ,

i am trying to calculate sun rise following below steps i got sun rise around 9:37 am but sun rise here in my locality is around 6.05 am when i used to convert milliseconds to time using native new Date(milliseconds) of the output it Screenshot 2024-04-13 180053

const {rise_trans} = sweph const rise = rise_trans( 2460414.072327234, 0, // Planet sun null, 2, // flag.SWIEPH, 1, // For rising [18.751372110577833, 79.51021061378489, 170], 0, 0, ) console.log("rise==>",rise) function millisecondsToTime(milliseconds) { const hours = Math.floor(milliseconds / (1000 * 60 * 60)); const minutes = Math.floor((milliseconds % (1000 * 60 * 60)) / (1000 * 60)); const seconds = Math.floor((milliseconds % (1000 * 60)) / 1000); return${hours}:${minutes}:${seconds}`; }

const milliseconds = (rise.data - 2460414.072327234) 86400 1000; // Convert Julian date to milliseconds // console.log("millisecons", milliseconds) const utcDate = new Date(milliseconds); const time = millisecondsToTime(milliseconds); console.log('time===>',time);`

but im getting wrong output im confused lost in understanding properly

please can you help me guide me on this ?

also when i try to get moon longitude it is giving me 3 deg 20 min extra than the current moon longitude in my place, i have checked with jHora windows app please can you help me on this Regards, Aravind

timotejroiko commented 4 months ago

@Hrsikesa108 it seems like you have inverted latitude and longitude, the geopos array in the rise_trans() function should be longitude first, latitude second.

Also, you can use the jdut1_to_utc() function to convert from julian day (jdut) to calendar date.

3 moon degrees equals roughly 6 hours difference, check for conversion between UTC and local time for your timezone.

const now = new Date();

const jd = utc_to_jd(
      now.getUTCFullYear(),
      now.getUTCMonth() + 1, // months in javascript Date start at 0
      now.getUTCDate(),
      now.getUTCHours(),
      now.getUTCMinutes(),
      now.getUTCSeconds() + now.getUTCMilliseconds() / 1000,
      1 // gregorian calendar flag
);

const rise = rise_trans(
      jd.data[1], // get jd_ut
      0, // Sun
      null,
      2, // flag.SWIEPH,
      1, // For rising 
      [79.51021061378489, 18.751372110577833, 170], // longitude first, latitude second
      0,
      0
);

const utc = jdut1_to_utc(
      rise.data,
      1 // gregorian calendar flag
);

const local = utc_time_zone(
      utc.year,
      utc.month,
      utc.day,
      utc.hour,
      utc.minute,
      utc.second,
      -5.5 // time zone of -05:30
);
Hrsikesa108 commented 4 months ago

Hi sir one doubt i have i am using below code which you have suggested but found utc_time_zone is not properly converting current time `

const getPanchanga = (now = new Date()) => { console.log('timeNow', now) const jd = utc_to_jd(now.getUTCFullYear(), now.getUTCMonth() + 1, // months in javascript Date start at 0 now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds() + now.getUTCMilliseconds() / 1000, 1) console.log('jd.data[1]==>', jd.data[1])

const rise = rise_trans(jd.data[1], SE_SUN, null, 2, // flag.SWIEPH
    1,
    [79.51021061378489, 18.751372110577833, 200],
    0, 0)

console.log('sweph.constants==>', rise)
const utc = jdut1_to_utc(rise.data, 1)  // gregorian calendar flag 1
console.log("utc==>", utc)
const local = utc_time_zone(utc.year, utc.month, utc.day, utc.hour, utc.minute, utc.second, -5.5)// time zone of -05:30
console.log('localTime', local)
const data = planets(jd.data[1])
// console.log('data==>', data)
const sunLong = data.sun.data[0]
const moonLong = data.moon.data[0]
console.log("sunLong==>", sunLong,"moonLong==>", moonLong)
const sign = zodiacSign(moonLong)

} getPanchanga() `

from use utc_time_zone function when given the timezone -5.5 i am getting below output which is showing 1 day extra timeNow 2024-04-28T10:37:51.553Z jd.data[1]==> 2460428.94295912 sweph.constants==> { flag: 0, error: '', data: 2460429.5106294174 } utc==> { year: 2024, month: 4, day: 29, hour: 0, minute: 15, second: 18.266554176807404 } localTime { year: 2024, month: 4, day: 29, hour: 5, minute: 45, second: 18.266554176807404 }

when i use 1 without giving the time zone then it is giving the time of timeNow 2024-04-28T10:42:55.702Z jd.data[1]==> 2460428.9464793634 sweph.constants==> { flag: 0, error: '', data: 2460429.5106294174 } utc==> { year: 2024, month: 4, day: 29, hour: 0, minute: 15, second: 18.266554176807404 } localTime { year: 2024, month: 4, day: 28, hour: 23, minute: 15, second: 18.266554176807404 }

means 5hr.30 min extra from my current time can you please guide me Thanks

timotejroiko commented 4 months ago

@Hrsikesa108

I'm not sure i understand what your issue is. As i do not know your location or your time zone, i cannot see what is correct and what is incorrect from your code.

The last parameter of the function utc_time_zone has to be your correct time zone in decimal format, for example 15 minutes equals 0.25 in decimal, 30 minutes equals 0.5 in decimal, and the sign is negative for east of GMT and positive for west of GMT.

If your time zone is GMT-6 (6 hours less than GMT, ie New York), the parameter should be 6, if your timezone is GMT+5:30 (5:30 hours more than GMT, ie India) then the parameter should be -5.5.

Other than that i cannot help you without further information, like which values are incorrect and what values were you expecting to see.

Hrsikesa108 commented 4 months ago

sir one small doubt , please dont feel bad, every time we should pass current time in utc format only right for all calculations? i am from india karimnagar, and time zone is GMT + 5.30 hrs

timotejroiko commented 4 months ago

Yes, all swisseph calculations are always done in UTC.

Hrsikesa108 commented 4 months ago

Hi sir, If I want to know tomorrow's sunrise which date and time do I need to pass ? tomorrow's date past mid night 12 or tomorrow's date + GMT + 5.30

timotejroiko commented 4 months ago

@Hrsikesa108

The function rise_trans always looks for the next event starting from the input date and time. So for tomorrow's sunrise, any time today will work as long as its after today's sunrise. So it is safe to use the JavaScript current time new Date().

The code i showed you before in https://github.com/timotejroiko/sweph/issues/12#issuecomment-2053872327 should give you exactly the result you want.

Start with the current time, use Javascript's Date methods to get the UTC parts, calculate the julian day, calculate rise trans, convert sunrise julian day back to calendar date, then convert the date to your timezone.