@angelrove/forecast-utils 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1046 -0
- package/dist/types/OpenMeteo/conf.d.ts +13 -0
- package/dist/types/OpenMeteo/current/fetchParams.d.ts +1 -0
- package/dist/types/OpenMeteo/current/transformer.d.ts +13 -0
- package/dist/types/OpenMeteo/current/useForecastCurrent.d.ts +14 -0
- package/dist/types/OpenMeteo/daily/fetchParams.d.ts +1 -0
- package/dist/types/OpenMeteo/daily/transformer.d.ts +9 -0
- package/dist/types/OpenMeteo/daily/useForecastDaily.d.ts +14 -0
- package/dist/types/OpenMeteo/helpers.d.ts +10 -0
- package/dist/types/OpenMeteo/hourly/fetchParams.d.ts +1 -0
- package/dist/types/OpenMeteo/hourly/useForecastHourly.d.ts +15 -0
- package/dist/types/OpenMeteo/weatherSymbol/lib/WeatherCodesEn.d.ts +43 -0
- package/dist/types/OpenMeteo/weatherSymbol/lib/WeatherCodesEs.d.ts +43 -0
- package/dist/types/OpenMeteo/weatherSymbol/lib/getWeatherCodeEntry.d.ts +7 -0
- package/dist/types/OpenMeteo/weatherSymbol/weatherSymbol.d.ts +13 -0
- package/dist/types/astronomy/moon/MoonCalc.d.ts +63 -0
- package/dist/types/astronomy/moon/parseBasicData.d.ts +8 -0
- package/dist/types/astronomy/sun/SunCalc.d.ts +73 -0
- package/dist/types/astronomy/sun/helpers.d.ts +0 -0
- package/dist/types/astronomy/timeZoneInfo.d.ts +10 -0
- package/dist/types/astronomy/timehelpers.d.ts +27 -0
- package/dist/types/astronomy/types.d.ts +43 -0
- package/dist/types/geolocation/getGeolocation.d.ts +12 -0
- package/dist/types/geolocation/lib/geolocation.d.ts +10 -0
- package/dist/types/geolocation/lib/geolocationCapacitor.d.ts +10 -0
- package/dist/types/geolocation/lib/reversegeocoding.d.ts +19 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/utils/degreesToCompass.d.ts +11 -0
- package/dist/types/utils/warning.d.ts +46 -0
- package/dist/types/utils/wind/WindArrow.d.ts +32 -0
- package/dist/types/utils/wind/windArrowTx.d.ts +9 -0
- package/dist/types/utils/wind/windLevel.d.ts +29 -0
- package/package.json +40 -0
- package/src/OpenMeteo/conf.js +47 -0
- package/src/OpenMeteo/current/fetchParams.js +21 -0
- package/src/OpenMeteo/current/transformer.js +37 -0
- package/src/OpenMeteo/current/useForecastCurrent.js +34 -0
- package/src/OpenMeteo/daily/fetchParams.js +9 -0
- package/src/OpenMeteo/daily/transformer.js +21 -0
- package/src/OpenMeteo/daily/useForecastDaily.js +38 -0
- package/src/OpenMeteo/helpers.js +19 -0
- package/src/OpenMeteo/hourly/fetchParams.js +12 -0
- package/src/OpenMeteo/hourly/useForecastHourly.js +42 -0
- package/src/OpenMeteo/weatherSymbol/lib/WeatherCodesEn.js +89 -0
- package/src/OpenMeteo/weatherSymbol/lib/WeatherCodesEs.js +81 -0
- package/src/OpenMeteo/weatherSymbol/lib/getWeatherCodeEntry.js +12 -0
- package/src/OpenMeteo/weatherSymbol/weatherSymbol.js +60 -0
- package/src/astronomy/moon/MoonCalc.js +171 -0
- package/src/astronomy/moon/parseBasicData.js +38 -0
- package/src/astronomy/sun/SunCalc.js +167 -0
- package/src/astronomy/sun/helpers.js +0 -0
- package/src/astronomy/timeZoneInfo.js +89 -0
- package/src/astronomy/timehelpers.js +69 -0
- package/src/astronomy/types.js +30 -0
- package/src/geolocation/getGeolocation.js +49 -0
- package/src/geolocation/lib/geolocation.js +44 -0
- package/src/geolocation/lib/geolocationCapacitor.js +21 -0
- package/src/geolocation/lib/reversegeocoding.js +109 -0
- package/src/index.js +38 -0
- package/src/utils/degreesToCompass.js +51 -0
- package/src/utils/warning.js +130 -0
- package/src/utils/wind/WindArrow.jsx +53 -0
- package/src/utils/wind/windArrowTx.js +24 -0
- package/src/utils/wind/windLevel.js +49 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* @module MoonCalc
|
|
4
|
+
* @description
|
|
5
|
+
* MoonCalc for calculating moon times, positions, and phases.
|
|
6
|
+
* - import { MoonCalc } from '@angelrov/forecast';
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
import SunCalc from "suncalc3";
|
|
11
|
+
import { dateFormat, getLocalTimeFromTz, timeString } from "../timehelpers.js";
|
|
12
|
+
import { parseBasicData } from "./parseBasicData.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* IMPORTANTE!!:
|
|
16
|
+
* ¡Solo proporcionar HORA LOCAL DEL SISTEMA!: 'new Date()'
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Mapa de fases lunares.
|
|
21
|
+
*
|
|
22
|
+
* @type {Object.<string, string>}
|
|
23
|
+
*/
|
|
24
|
+
const phasesES = {
|
|
25
|
+
newMoon: "Luna Nueva",
|
|
26
|
+
waxingCrescentMoon: "Luna Creciente",
|
|
27
|
+
firstQuarterMoon: "Cuarto Creciente",
|
|
28
|
+
waxingGibbousMoon: "Gibosa creciente",
|
|
29
|
+
fullMoon: "Luna Llena",
|
|
30
|
+
waningGibbousMoon: "Gibosa menguante",
|
|
31
|
+
thirdQuarterMoon: "Cuarto Menguante",
|
|
32
|
+
waningCrescentMoon: "Luna Menguante",
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const MoonCalc = {
|
|
36
|
+
data,
|
|
37
|
+
dataExt,
|
|
38
|
+
times,
|
|
39
|
+
emoji,
|
|
40
|
+
getUpOrDown,
|
|
41
|
+
};
|
|
42
|
+
export default MoonCalc;
|
|
43
|
+
|
|
44
|
+
//--------------------------------------------------------------------
|
|
45
|
+
/**
|
|
46
|
+
* @param {number} latitude
|
|
47
|
+
* @param {number} longitude
|
|
48
|
+
* @param {Date} [date=new Date()]
|
|
49
|
+
* @param {string} [language=es-ES]
|
|
50
|
+
* @returns {MoonData}
|
|
51
|
+
*/
|
|
52
|
+
function data(latitude, longitude, date = new Date(), language = "es-ES") {
|
|
53
|
+
// date.setHours(date.getHours() + 0); // debug
|
|
54
|
+
const data = SunCalc.getMoonData(date, latitude, longitude);
|
|
55
|
+
// console.log("%cdebug:", "color:yellow", data.illumination.next.newMoon.value);
|
|
56
|
+
|
|
57
|
+
return parseBasicData(data, language);
|
|
58
|
+
}
|
|
59
|
+
//--------------------------------------------------------------------
|
|
60
|
+
/**
|
|
61
|
+
* Información de la luna para una fecha y hora dadas.
|
|
62
|
+
* La fecha y hora se devolverán en la zona horaria local.
|
|
63
|
+
*
|
|
64
|
+
* @param {number} latitude
|
|
65
|
+
* @param {number} longitude
|
|
66
|
+
* @param {Date} [date=new Date()]
|
|
67
|
+
* @param {string} [language=es-ES]
|
|
68
|
+
* @returns {{ date: string, time: string, illumination: string, phase: string, phaseId: string, emoji: string, parallacticAngle: number, angle: number, position: AstroPosition, next: object }}
|
|
69
|
+
*/
|
|
70
|
+
function dataExt(latitude, longitude, date = new Date(), language = "es-ES") {
|
|
71
|
+
const data = SunCalc.getMoonData(date, latitude, longitude);
|
|
72
|
+
|
|
73
|
+
// Illumination
|
|
74
|
+
const illumination =
|
|
75
|
+
Number((data.illumination.fraction * 100).toFixed(1)) + "%";
|
|
76
|
+
|
|
77
|
+
// Phase
|
|
78
|
+
const emoji = data.illumination.phase.emoji;
|
|
79
|
+
const phaseId = String(data.illumination.phase.id);
|
|
80
|
+
const phase = phasesES[phaseId];
|
|
81
|
+
|
|
82
|
+
// Angle
|
|
83
|
+
const parallacticAngle = data.parallacticAngleDegrees;
|
|
84
|
+
const angle =
|
|
85
|
+
phaseId === "fullMoon" || phaseId === "newMoon" ? 0 : parallacticAngle;
|
|
86
|
+
|
|
87
|
+
// Basic data
|
|
88
|
+
const basicData = parseBasicData(data, language);
|
|
89
|
+
|
|
90
|
+
// Return ---
|
|
91
|
+
return {
|
|
92
|
+
date: dateFormat(date),
|
|
93
|
+
time: timeString(date),
|
|
94
|
+
illumination: illumination,
|
|
95
|
+
phase: phase,
|
|
96
|
+
phaseId: phaseId,
|
|
97
|
+
emoji: emoji,
|
|
98
|
+
parallacticAngle: parallacticAngle,
|
|
99
|
+
angle: Math.round(angle),
|
|
100
|
+
position: basicData.position,
|
|
101
|
+
next: basicData.next,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
//--------------------------------------------------------------------
|
|
105
|
+
/**
|
|
106
|
+
* @param {number} latitude
|
|
107
|
+
* @param {number} longitude
|
|
108
|
+
* @param {Date} [date=new Date()]
|
|
109
|
+
* @returns {string} - Emoji of the moon phase
|
|
110
|
+
*/
|
|
111
|
+
function emoji(latitude, longitude, date = new Date()) {
|
|
112
|
+
const data = SunCalc.getMoonData(date, latitude, longitude);
|
|
113
|
+
return data.illumination.phase.emoji;
|
|
114
|
+
}
|
|
115
|
+
//--------------------------------------------------------------------
|
|
116
|
+
/**
|
|
117
|
+
* @param {number} latitude
|
|
118
|
+
* @param {number} longitude
|
|
119
|
+
* @param {string} timezoneId
|
|
120
|
+
* @param {Date} date
|
|
121
|
+
* @returns {{rise: string, set: string, highest: string}}
|
|
122
|
+
*/
|
|
123
|
+
function times(latitude, longitude, timezoneId, date = new Date()) {
|
|
124
|
+
const ret = {
|
|
125
|
+
rise: "",
|
|
126
|
+
set: "",
|
|
127
|
+
highest: "",
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const times = SunCalc.getMoonTimes(date, latitude, longitude);
|
|
131
|
+
if (times.alwaysUp) {
|
|
132
|
+
ret.rise = "always up";
|
|
133
|
+
ret.set = "always up";
|
|
134
|
+
ret.highest = "always up";
|
|
135
|
+
return ret;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (times.alwaysDown) {
|
|
139
|
+
ret.rise = "always down";
|
|
140
|
+
ret.set = "always down";
|
|
141
|
+
ret.highest = "always down";
|
|
142
|
+
return ret;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
ret.rise = getLocalTimeFromTz(timezoneId, times.rise);
|
|
146
|
+
ret.set = getLocalTimeFromTz(timezoneId, times.set);
|
|
147
|
+
ret.highest = getLocalTimeFromTz(timezoneId, times.highest);
|
|
148
|
+
return ret;
|
|
149
|
+
}
|
|
150
|
+
//--------------------------------------------------------------------
|
|
151
|
+
/**
|
|
152
|
+
* @param {number} altitude
|
|
153
|
+
* @param {Date} highest
|
|
154
|
+
* @returns {string} - Up or down emoji
|
|
155
|
+
*/
|
|
156
|
+
function getUpOrDown(altitude, highest) {
|
|
157
|
+
const now = new Date();
|
|
158
|
+
let upOrDown = ""; // ◓ ◒
|
|
159
|
+
|
|
160
|
+
if (altitude > 0) {
|
|
161
|
+
if (highest.getHours() > now.getHours()) {
|
|
162
|
+
upOrDown = "🔺";
|
|
163
|
+
} else {
|
|
164
|
+
upOrDown = "🔻";
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// console.log(highest.getHours(), now.getHours());
|
|
168
|
+
|
|
169
|
+
return upOrDown;
|
|
170
|
+
}
|
|
171
|
+
//--------------------------------------------------------------------
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { degreesToCompass } from "../../utils/degreesToCompass.js";
|
|
2
|
+
import { dateFormat } from "../timehelpers.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Parse basic data from SunCalc
|
|
6
|
+
*
|
|
7
|
+
* @param {any} data
|
|
8
|
+
* @param {string} language
|
|
9
|
+
* @returns {MoonData}
|
|
10
|
+
*/
|
|
11
|
+
export function parseBasicData(data, language) {
|
|
12
|
+
// Position ---
|
|
13
|
+
const altitude = Number(data.altitudeDegrees.toFixed(1));
|
|
14
|
+
const azimuth = Math.round(data.azimuthDegrees);
|
|
15
|
+
const direction = degreesToCompass(data.azimuthDegrees, language);
|
|
16
|
+
|
|
17
|
+
// Next moon ---
|
|
18
|
+
const nextNewMoon = dateFormat(
|
|
19
|
+
new Date(data.illumination.next.newMoon.value),
|
|
20
|
+
);
|
|
21
|
+
const nextFullMoon = dateFormat(
|
|
22
|
+
new Date(data.illumination.next.fullMoon.value),
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
position: {
|
|
27
|
+
// up_down: null,
|
|
28
|
+
altitude: altitude,
|
|
29
|
+
azimuth: azimuth,
|
|
30
|
+
direction: direction.short,
|
|
31
|
+
direction_full: direction.full,
|
|
32
|
+
},
|
|
33
|
+
next: {
|
|
34
|
+
newMoon: nextNewMoon,
|
|
35
|
+
fullMoon: nextFullMoon,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module SunCalc
|
|
3
|
+
* @description
|
|
4
|
+
* SunCalc for calculating solar times, positions, and phases.
|
|
5
|
+
* - import { SunCalc } from '@angelrov/forecast';
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
import { default as SunCalc3 } from "suncalc3";
|
|
10
|
+
import { degreesToCompass } from "../../utils/degreesToCompass.js";
|
|
11
|
+
import {
|
|
12
|
+
dateFormat,
|
|
13
|
+
getLocalTimeFromTz,
|
|
14
|
+
nowString,
|
|
15
|
+
timeString,
|
|
16
|
+
} from "../timehelpers.js";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* IMPORTANTE!!:
|
|
20
|
+
* ¡Solo proporcionar HORA LOCAL DEL SISTEMA!: 'new Date()'
|
|
21
|
+
* La única excepción es 'getSolarTime()': hay que darle la hora local correspondiente a la localización dada.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
// Export ----
|
|
25
|
+
const SunCalc = {
|
|
26
|
+
all,
|
|
27
|
+
times,
|
|
28
|
+
getSolarTime,
|
|
29
|
+
position,
|
|
30
|
+
getIsNight,
|
|
31
|
+
getPhase,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default SunCalc;
|
|
35
|
+
|
|
36
|
+
//-------------------------------------------------------
|
|
37
|
+
/**
|
|
38
|
+
* @param {Date} date
|
|
39
|
+
* @param {number} latitude
|
|
40
|
+
* @param {number} longitude
|
|
41
|
+
* @param {string} timezoneId
|
|
42
|
+
* @returns {{ sunTimes: object, sunPosition: object, sunPhase: string }}
|
|
43
|
+
*/
|
|
44
|
+
function all(date, latitude, longitude, timezoneId) {
|
|
45
|
+
const sunTimes = SunCalc.times(date, latitude, longitude, timezoneId);
|
|
46
|
+
const sunPosition = SunCalc.position(latitude, longitude, date);
|
|
47
|
+
const sunPhase = SunCalc.getPhase(sunPosition.altitude, sunTimes.noon);
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
sunTimes,
|
|
51
|
+
sunPosition,
|
|
52
|
+
sunPhase,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//-------------------------------------------------------
|
|
56
|
+
// 'timeZone' es necesario para devolver las horas locales
|
|
57
|
+
/**
|
|
58
|
+
* @param {Date} date
|
|
59
|
+
* @param {number} latitude
|
|
60
|
+
* @param {number} longitude
|
|
61
|
+
* @param {string} timezoneId
|
|
62
|
+
* @returns {{ date: Date, sunrise: string, sunset: string, noon: string, dawn: string, dusk: string }}
|
|
63
|
+
*/
|
|
64
|
+
function times(date, latitude, longitude, timezoneId) {
|
|
65
|
+
const times = SunCalc3.getSunTimes(date, latitude, longitude);
|
|
66
|
+
|
|
67
|
+
const sunTimes = {
|
|
68
|
+
date: date,
|
|
69
|
+
sunrise: getLocalTimeFromTz(timezoneId, times.sunriseStart.value),
|
|
70
|
+
sunset: getLocalTimeFromTz(timezoneId, times.sunsetStart.value),
|
|
71
|
+
noon: getLocalTimeFromTz(timezoneId, times.solarNoon.value),
|
|
72
|
+
dawn: getLocalTimeFromTz(timezoneId, times.civilDawn.value),
|
|
73
|
+
dusk: getLocalTimeFromTz(timezoneId, times.civilDusk.value),
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// console.log(sunTimes);
|
|
77
|
+
return sunTimes;
|
|
78
|
+
}
|
|
79
|
+
//-------------------------------------------------------
|
|
80
|
+
/**
|
|
81
|
+
* @param {Date} date
|
|
82
|
+
* @param {number} lng
|
|
83
|
+
* @param {string} offsetSign - "+" or "-"
|
|
84
|
+
* @param {number} offset - UTC offset in hours
|
|
85
|
+
* @returns {string} - Local time in "HH:mm" format
|
|
86
|
+
*/
|
|
87
|
+
function getSolarTime(date, lng, offsetSign, offset) {
|
|
88
|
+
// Convert offsetSign and offset to a numeric UTC offset (e.g., -3, +2)
|
|
89
|
+
const utcOffset = (offsetSign === "-" ? -1 : 1) * Math.abs(Number(offset));
|
|
90
|
+
const solarTime = SunCalc3.getSolarTime(date, lng, utcOffset);
|
|
91
|
+
return timeString(solarTime);
|
|
92
|
+
}
|
|
93
|
+
//-------------------------------------------------------
|
|
94
|
+
/**
|
|
95
|
+
* @param {number} latitude
|
|
96
|
+
* @param {number} longitude
|
|
97
|
+
* @returns {{date: string, azimuth: number, direction: string, direction_full: string, altitude: number, zenith: number, declination: number}}
|
|
98
|
+
*/
|
|
99
|
+
function position(latitude, longitude, date = new Date(), language = "es-ES") {
|
|
100
|
+
const position = SunCalc3.getPosition(date, latitude, longitude);
|
|
101
|
+
|
|
102
|
+
// Get text
|
|
103
|
+
const direction = degreesToCompass(position.azimuthDegrees, language);
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
date: dateFormat(date),
|
|
107
|
+
azimuth: position.azimuthDegrees,
|
|
108
|
+
direction: direction.short,
|
|
109
|
+
direction_full: direction.full,
|
|
110
|
+
altitude: Math.round(position.altitudeDegrees),
|
|
111
|
+
zenith: position.zenithDegrees,
|
|
112
|
+
declination: position.declination,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//-------------------------------------------------------
|
|
116
|
+
// Sun phase
|
|
117
|
+
//-------------------------------------------------------
|
|
118
|
+
/**
|
|
119
|
+
* @param {number} lat
|
|
120
|
+
* @param {number} lon
|
|
121
|
+
* @param {string} timezoneId
|
|
122
|
+
* @param {number | Date} date
|
|
123
|
+
* @param {string} dateStr
|
|
124
|
+
* @returns {boolean} - true if it's night, false otherwise
|
|
125
|
+
*/
|
|
126
|
+
function getIsNight(lat, lon, timezoneId, date, dateStr) {
|
|
127
|
+
const times = SunCalc3.getSunTimes(date, lat, lon);
|
|
128
|
+
|
|
129
|
+
// se pueden comparar horas(hh:mm) estando en formato texto
|
|
130
|
+
// y así no tenemos que tener en cuenta el día, mes.
|
|
131
|
+
const timeUp = getLocalTimeFromTz(timezoneId, times.sunriseEnd.value);
|
|
132
|
+
const timeDown = getLocalTimeFromTz(
|
|
133
|
+
timezoneId,
|
|
134
|
+
times.goldenHourDuskStart.value,
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
return dateStr < timeUp || dateStr > timeDown;
|
|
138
|
+
}
|
|
139
|
+
//-------------------------------------------------------
|
|
140
|
+
/**
|
|
141
|
+
* @param {number} altitude
|
|
142
|
+
* @param {string} noon
|
|
143
|
+
* @returns {string} - The phase of the sun based on its altitude
|
|
144
|
+
*/
|
|
145
|
+
function getPhase(altitude, noon) {
|
|
146
|
+
const nowTime = nowString();
|
|
147
|
+
|
|
148
|
+
let phase = "day";
|
|
149
|
+
if (altitude < 4) {
|
|
150
|
+
phase = nowTime > noon ? "dayEnd" : "dayStart";
|
|
151
|
+
}
|
|
152
|
+
if (altitude < 2) {
|
|
153
|
+
phase = nowTime > noon ? "sunset" : "sunrise";
|
|
154
|
+
}
|
|
155
|
+
if (altitude < -5) {
|
|
156
|
+
phase = nowTime > noon ? "dusk" : "dawn";
|
|
157
|
+
}
|
|
158
|
+
if (altitude < -18) {
|
|
159
|
+
phase = "night";
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return phase;
|
|
163
|
+
}
|
|
164
|
+
//-------------------------------------------------------
|
|
165
|
+
// function getPhase2(date, sunTimes, timeZone) {
|
|
166
|
+
// }
|
|
167
|
+
//-------------------------------------------------------
|
|
File without changes
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* @module astronomy/time-date
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { timeString } from "./timehelpers.js";
|
|
7
|
+
|
|
8
|
+
//------------------------------------------------------
|
|
9
|
+
/**
|
|
10
|
+
* Google API: Get local time from any location
|
|
11
|
+
*
|
|
12
|
+
* @param {string} apiKey - GoogleMaps API key.
|
|
13
|
+
* @param {number} lat
|
|
14
|
+
* @param {number} lng
|
|
15
|
+
* @returns {Promise<any | LocalTimeData>} - An object containing the local time and timezone information:
|
|
16
|
+
* @throws {Error} - If the API request fails or returns an error status.
|
|
17
|
+
*/
|
|
18
|
+
export async function getLocalTimeInfo(apiKey, lat, lng) {
|
|
19
|
+
const timestamp = Math.floor(Date.now() / 1000);
|
|
20
|
+
const url =
|
|
21
|
+
"https://maps.googleapis.com/maps/api/timezone/json?" +
|
|
22
|
+
`location=${lat},${lng}×tamp=${timestamp}&key=${apiKey}`;
|
|
23
|
+
|
|
24
|
+
// Log: hidden apiKey
|
|
25
|
+
console.info(">> Google (time)", url.replace(/key=[^&]+/, "key=********"));
|
|
26
|
+
|
|
27
|
+
// Fetch timezone information ---
|
|
28
|
+
return fetch(url)
|
|
29
|
+
.then((response) => response.json())
|
|
30
|
+
.then((data) => {
|
|
31
|
+
// Error ---
|
|
32
|
+
if (data.status !== "OK") {
|
|
33
|
+
console.error(data);
|
|
34
|
+
return getLocalTimeDataErr();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Success ---
|
|
38
|
+
return getLocalTimeData(data);
|
|
39
|
+
})
|
|
40
|
+
.catch((error) => {
|
|
41
|
+
console.error(error);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
//------------------------------------------------------
|
|
45
|
+
/**
|
|
46
|
+
* @private
|
|
47
|
+
* @param {Object} timezoneInfo - The timezone Google API information.
|
|
48
|
+
* @param {number} timezoneInfo.rawOffset - The raw offset in seconds.
|
|
49
|
+
* @param {number} timezoneInfo.dstOffset - The DST offset in seconds.
|
|
50
|
+
* @param {string} timezoneInfo.timeZoneName - The name of the timezone.
|
|
51
|
+
* @param {string} timezoneInfo.timeZoneId - The ID of the timezone.
|
|
52
|
+
* @returns {LocalTimeData} - An object containing the local time and timezone information.
|
|
53
|
+
*/
|
|
54
|
+
function getLocalTimeData(timezoneInfo) {
|
|
55
|
+
// Time
|
|
56
|
+
const date = new Date();
|
|
57
|
+
const utc = date.getTime() + date.getTimezoneOffset() * 60000;
|
|
58
|
+
const localTime =
|
|
59
|
+
utc + 1000 * timezoneInfo.rawOffset + 1000 * timezoneInfo.dstOffset;
|
|
60
|
+
const time = new Date(localTime);
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
time: time,
|
|
64
|
+
timeStr: timeString(time),
|
|
65
|
+
timezone: timezoneInfo.timeZoneName,
|
|
66
|
+
timezoneId: timezoneInfo.timeZoneId,
|
|
67
|
+
offset: timezoneInfo.rawOffset / 3600,
|
|
68
|
+
offsetSign: timezoneInfo.rawOffset < 0 ? "" : "+",
|
|
69
|
+
dstOffset: timezoneInfo.dstOffset / 3600,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//------------------------------------------------------
|
|
73
|
+
/**
|
|
74
|
+
* @private
|
|
75
|
+
* @returns {LocalTimeData} - An object containing the local time and timezone information when error.
|
|
76
|
+
*/
|
|
77
|
+
function getLocalTimeDataErr() {
|
|
78
|
+
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
79
|
+
return {
|
|
80
|
+
time: new Date(),
|
|
81
|
+
timeStr: timeString(new Date()),
|
|
82
|
+
timezone: timezone,
|
|
83
|
+
timezoneId: timezone,
|
|
84
|
+
offset: 0,
|
|
85
|
+
offsetSign: "+",
|
|
86
|
+
dstOffset: 0,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//------------------------------------------------------
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module astronomy/time-date
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
//------------------------------------------------------
|
|
6
|
+
/**
|
|
7
|
+
* Formatea una fecha a un string legible.
|
|
8
|
+
*
|
|
9
|
+
* @param {Date} [date]
|
|
10
|
+
* @param {boolean} [sec=false]
|
|
11
|
+
* @returns {string} La fecha formateada.
|
|
12
|
+
*/
|
|
13
|
+
export function timeString(date = new Date(), sec = false) {
|
|
14
|
+
if (sec) {
|
|
15
|
+
return date.toLocaleTimeString([], {
|
|
16
|
+
hour: "2-digit",
|
|
17
|
+
minute: "2-digit",
|
|
18
|
+
hour12: false,
|
|
19
|
+
second: "2-digit",
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return date.toLocaleTimeString([], {
|
|
24
|
+
hour: "2-digit",
|
|
25
|
+
minute: "2-digit",
|
|
26
|
+
hour12: false,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
//------------------------------------------------------
|
|
30
|
+
export function nowString(sec = false) {
|
|
31
|
+
return timeString(new Date(), sec);
|
|
32
|
+
}
|
|
33
|
+
//------------------------------------------------------
|
|
34
|
+
/**
|
|
35
|
+
* Formatea una fecha a un string legible.
|
|
36
|
+
*
|
|
37
|
+
* @param {Date} [date=new Date()] La fecha a formatear.
|
|
38
|
+
* @returns {string} La fecha formateada.
|
|
39
|
+
*/
|
|
40
|
+
export function dateFormat(date = new Date()) {
|
|
41
|
+
const options = {
|
|
42
|
+
weekday: "long",
|
|
43
|
+
day: "numeric",
|
|
44
|
+
month: "short",
|
|
45
|
+
};
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
return date.toLocaleDateString([], options);
|
|
48
|
+
}
|
|
49
|
+
//------------------------------------------------------
|
|
50
|
+
/**
|
|
51
|
+
* Get local time from timezone
|
|
52
|
+
*
|
|
53
|
+
* @param {string} timeZone - The timezone string (e.g., 'America/New_York').
|
|
54
|
+
* @param {Date | number} [date=new Date()] - The date object to format. Defaults to the current date.
|
|
55
|
+
* @returns {string} - The formatted local time string.
|
|
56
|
+
*/
|
|
57
|
+
export function getLocalTimeFromTz(timeZone, date = new Date()) {
|
|
58
|
+
// Timezone example
|
|
59
|
+
// timeZone = 'America/New_York';
|
|
60
|
+
|
|
61
|
+
const formatter = new Intl.DateTimeFormat("en-US", {
|
|
62
|
+
timeZone: timeZone,
|
|
63
|
+
hour: "numeric",
|
|
64
|
+
minute: "numeric",
|
|
65
|
+
hour12: false,
|
|
66
|
+
});
|
|
67
|
+
return formatter.format(date);
|
|
68
|
+
}
|
|
69
|
+
//------------------------------------------------------
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module astronomy/types
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {Object} AstroPosition
|
|
7
|
+
* @property {number} altitude
|
|
8
|
+
* @property {number} azimuth
|
|
9
|
+
* @property {string} direction
|
|
10
|
+
* @property {string} direction_full
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {Object} MoonData
|
|
15
|
+
* @property {AstroPosition} position
|
|
16
|
+
* @property {Object} next
|
|
17
|
+
* @property {string} next.newMoon - Date of the next new moon.
|
|
18
|
+
* @property {string} next.fullMoon - Date of the next full moon.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {Object} LocalTimeData
|
|
23
|
+
* @property {Date} time - The local time.
|
|
24
|
+
* @property {string} timeStr - The formatted local time string.
|
|
25
|
+
* @property {string} timezone - The timezone name.
|
|
26
|
+
* @property {string} timezoneId - The timezone ID.
|
|
27
|
+
* @property {number} offset - The UTC offset in hours.
|
|
28
|
+
* @property {string} offsetSign - The sign of the offset ('+' or '-').
|
|
29
|
+
* @property {number} dstOffset - The DST offset in hours.
|
|
30
|
+
*/
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module Geolocation
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import geolocationCapacitor from "./lib/geolocation.js";
|
|
6
|
+
import reverseGeocoding from "./lib/reversegeocoding.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Get the current geolocation of the device and reverse
|
|
10
|
+
* geocode it to get the address.
|
|
11
|
+
*
|
|
12
|
+
* @returns {Promise<{latitude: number, longitude: number, formatted_address: string}>}
|
|
13
|
+
* @throws {Error} If geolocation is not supported or permission is denied.
|
|
14
|
+
*/
|
|
15
|
+
export async function getGeolocation() {
|
|
16
|
+
let location = null;
|
|
17
|
+
let address = null;
|
|
18
|
+
|
|
19
|
+
// Location ---
|
|
20
|
+
try {
|
|
21
|
+
location = await geolocationCapacitor();
|
|
22
|
+
// location.latitude = '25.90197748117876'; location.longitude = '-65.71650426928204';
|
|
23
|
+
} catch (error) {
|
|
24
|
+
throw new Error("Geolocation error: " + error.message);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Address ---
|
|
28
|
+
try {
|
|
29
|
+
address = await reverseGeocoding(
|
|
30
|
+
location.latitude,
|
|
31
|
+
location.longitude,
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
import.meta.env.VITE_googlemaps_api_key,
|
|
34
|
+
);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.log("reverseGeocoding - error: ", error.message);
|
|
37
|
+
address = {
|
|
38
|
+
formatted_address:
|
|
39
|
+
"[" + location.latitude + ", " + location.longitude + "]",
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Return data ---
|
|
44
|
+
return {
|
|
45
|
+
...location,
|
|
46
|
+
...address,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//--------------------------------------------
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the current geolocation of the device with the browser.
|
|
3
|
+
*
|
|
4
|
+
* @returns {Promise<{latitude: number, longitude: number}>}
|
|
5
|
+
* @throws {Error} If geolocation is not supported or permission is denied.
|
|
6
|
+
*/
|
|
7
|
+
export default async function geolocation() {
|
|
8
|
+
const geolocOptions = {
|
|
9
|
+
enableHighAccuracy: true,
|
|
10
|
+
timeout: 6 * 1000,
|
|
11
|
+
maximumAge: 0,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
const data = await new Promise((resolve, reject) => {
|
|
16
|
+
if ("geolocation" in navigator) {
|
|
17
|
+
navigator.geolocation.getCurrentPosition(
|
|
18
|
+
resolve,
|
|
19
|
+
reject,
|
|
20
|
+
geolocOptions,
|
|
21
|
+
);
|
|
22
|
+
} else {
|
|
23
|
+
reject(new Error("Geolocation is not supported"));
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
latitude: data.coords.latitude,
|
|
29
|
+
longitude: data.coords.longitude,
|
|
30
|
+
};
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error(error);
|
|
33
|
+
if (error.code === error.PERMISSION_DENIED) {
|
|
34
|
+
throw new Error("Geolocation: permission denied");
|
|
35
|
+
}
|
|
36
|
+
if (error.code === error.POSITION_UNAVAILABLE) {
|
|
37
|
+
throw new Error("Geolocation: position unavailable");
|
|
38
|
+
}
|
|
39
|
+
if (error.code === error.TIMEOUT) {
|
|
40
|
+
throw new Error("Geolocation: timeout");
|
|
41
|
+
}
|
|
42
|
+
throw new Error("Geolocation: unknown error");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Geolocation } from "@capacitor/geolocation";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get the current GPS location of the device with Capacitor.
|
|
5
|
+
*
|
|
6
|
+
* @returns {Promise<{latitude: number, longitude: number}>}
|
|
7
|
+
* @throws {Error} If geolocation is not supported or permission is denied.
|
|
8
|
+
*/
|
|
9
|
+
export default async function geolocationCapacitor() {
|
|
10
|
+
try {
|
|
11
|
+
const coordinates = await Geolocation.getCurrentPosition();
|
|
12
|
+
// console.log('geolocation - coordinates: ', coordinates);
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
latitude: coordinates.coords.latitude,
|
|
16
|
+
longitude: coordinates.coords.longitude,
|
|
17
|
+
};
|
|
18
|
+
} catch (_error) {
|
|
19
|
+
throw new Error("Error al obtener la ubicación");
|
|
20
|
+
}
|
|
21
|
+
}
|