bDateController.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. import * as luxon from 'luxon';
  2. import {LocalBadiDate} from 'badidate';
  3. /**
  4. * @typedef {PlainObject} DateConfig
  5. * @property {string} latitude
  6. * @property {string} longitude
  7. * @property {string} timezoneId
  8. */
  9. /**
  10. * @param {Date} dte
  11. * @param {DateConfig} dateCfg
  12. * @returns {LocalBadiDate}
  13. */
  14. function createDateObject (dte, {
  15. // Bahjí
  16. latitude = 32.9434,
  17. longitude = 35.0924,
  18. timezoneId = 'Asia/Jerusalem'
  19. } = {}) {
  20. const luxonDate = luxon.DateTime.fromJSDate(dte);
  21. return new LocalBadiDate(luxonDate, latitude, longitude, timezoneId);
  22. }
  23. /**
  24. * @param {string} tz
  25. * @returns {string|undefined}
  26. */
  27. function sanitizeTimeZone (tz) {
  28. try {
  29. const timeZone = tz.replace(/ /gu, '_');
  30. Intl.DateTimeFormat(undefined, {timeZone});
  31. return timeZone;
  32. } catch (err) {
  33. // Will allow default above to be used
  34. return undefined;
  35. }
  36. }
  37. /**
  38. * @param {any} s
  39. * @returns {Float|undefined}
  40. */
  41. function sanitizeFloat (s) {
  42. if (s === '' || s === undefined || s === null || s === false ||
  43. Number.isNaN(Number(s))) {
  44. // Will allow default above to be used
  45. return undefined;
  46. }
  47. return Number.parseFloat(s);
  48. }
  49. /**
  50. * @param {any} s
  51. * @returns {Integer}
  52. */
  53. function sanitizeInteger (s) {
  54. if (s === '' || s === undefined || s === null || s === false ||
  55. Number.isNaN(Number(s))) {
  56. return 0;
  57. }
  58. return Number.parseInt(s);
  59. }
  60. /**
  61. * @param {Request} req
  62. * @param {Response} res
  63. * @returns {void}
  64. */
  65. function test (req, res) {
  66. res.json({message: 'Hi there'});
  67. }
  68. /**
  69. * @typedef {PlainObject} BadiDateInfo
  70. * @property {string} message
  71. * @property {PlainObject} badi_date
  72. * @property {Integer} badi_date.year
  73. * @property {Integer} badi_date.month
  74. * @property {Integer} badi_date.day
  75. * @property {string} badi_date.month_name
  76. * @property {string} badi_date.timezone_id
  77. * @property {PlainObject} greg_date
  78. * @property {Integer} greg_date.year
  79. * @property {Integer} greg_date.month
  80. * @property {Integer} greg_date.day
  81. * @property {Integer} greg_date.hour
  82. * @property {Integer} greg_date.minute
  83. * @property {Integer} greg_date.second
  84. * @property {Integer} greg_date.timezoneOffset
  85. */
  86. /**
  87. * @typedef {PlainObject} BadiDateResponse
  88. * @property {Date} now
  89. * @property {LocalBadiDate} nowBadi
  90. * @property {BadiDateInfo} json
  91. */
  92. /**
  93. * @param {DateConfig} dateObj
  94. * @returns {BadiDateResponse}
  95. */
  96. const getTodayJSON = function (dateObj = {}) {
  97. const now = new Date();
  98. const latitude = sanitizeFloat(dateObj.latitude);
  99. const longitude = sanitizeFloat(dateObj.longitude);
  100. const timezoneId = sanitizeTimeZone(dateObj.timezoneId);
  101. const nowBadi = createDateObject(now, {
  102. latitude, longitude, timezoneId
  103. });
  104. return {
  105. now,
  106. nowBadi,
  107. json: {
  108. message: 'Today is ' + nowBadi.badiDate.format(),
  109. badi_date: {
  110. year: nowBadi.badiDate.year,
  111. month: nowBadi.badiDate.month,
  112. day: nowBadi.badiDate.day,
  113. month_name: nowBadi.badiDate.format('MM+'),
  114. timezone_id: nowBadi.timezoneId
  115. },
  116. greg_date: {
  117. year: now.getFullYear(),
  118. month: now.getMonth() + 1,
  119. day: now.getDate(),
  120. hour: now.getHours(),
  121. minute: now.getMinutes(),
  122. second: now.getSeconds(),
  123. timezoneOffset: now.getTimezoneOffset()
  124. }
  125. }
  126. };
  127. };
  128. /**
  129. * @param {Request} req
  130. * @param {Response} res
  131. * @returns {void}
  132. */
  133. function today (req, res) {
  134. const {json, nowBadi} = getTodayJSON(req.query);
  135. // eslint-disable-next-line no-console -- CLI
  136. console.log('Today: ' + nowBadi.badiDate.format());
  137. res.json(json);
  138. }
  139. /**
  140. * @param {Request} req
  141. * @param {Response} res
  142. * @returns {void}
  143. */
  144. function todayHtml (req, res) {
  145. res.set('content-type', 'text/html;charset=utf-8');
  146. res.end(JSON.stringify(getTodayJSON(req.query).json, null, 2));
  147. }
  148. /**
  149. * @param {Request} req
  150. * @param {Response} res
  151. * @returns {void}
  152. */
  153. function date (req, res) {
  154. const dateInfo = getDate(req.query);
  155. // eslint-disable-next-line no-console -- CLI
  156. console.log(
  157. 'Date: ' + dateInfo.now.toString() + ' -> ' +
  158. dateInfo.nowBadi.badiDate.format()
  159. );
  160. res.json(dateInfo.json);
  161. }
  162. /**
  163. * @typedef {DateConfig} FullDateConfig
  164. * @property {Integer} year
  165. * @property {Integer} month
  166. * @property {Integer} day
  167. * @property {Integer} hour
  168. * @property {Integer} minute
  169. * @property {Integer} second
  170. */
  171. /**
  172. * @param {FullDateConfig} dateObj
  173. * @returns {BadiDateResponse}
  174. */
  175. const getDate = function (dateObj) {
  176. const year = sanitizeInteger(dateObj.year);
  177. const month = sanitizeInteger(dateObj.month) - 1;
  178. const day = sanitizeInteger(dateObj.day);
  179. const hour = sanitizeInteger(dateObj.hour);
  180. const minute = sanitizeInteger(dateObj.minute);
  181. const second = sanitizeInteger(dateObj.second);
  182. const now = new Date(year, month, day, hour, minute, second);
  183. const latitude = sanitizeFloat(dateObj.latitude);
  184. const longitude = sanitizeFloat(dateObj.longitude);
  185. const timezoneId = sanitizeTimeZone(dateObj.timezoneId);
  186. const nowBadi = createDateObject(now, {
  187. latitude, longitude, timezoneId
  188. });
  189. return {
  190. now,
  191. nowBadi,
  192. json: {
  193. message: 'The date is: ' + nowBadi.badiDate.format(),
  194. badi_date: {
  195. year: nowBadi.badiDate.year,
  196. month: nowBadi.badiDate.month,
  197. day: nowBadi.badiDate.day,
  198. month_name: nowBadi.badiDate.format('MM+'),
  199. timezone_id: nowBadi.timezoneId
  200. },
  201. greg_date: {
  202. year,
  203. month: month + 1,
  204. day,
  205. hour,
  206. minute,
  207. second,
  208. timezoneOffset: now.getTimezoneOffset()
  209. }
  210. }
  211. };
  212. };
  213. export {test, getTodayJSON, today, todayHtml, date, getDate};