bDateController.js 5.6 KB

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