lib/timezones.js

  1. /**
  2. * @file Handle timezones
  3. * @author Antonio Olmo Titos <a@olmo-titos.info>
  4. * @exports lib/timezones
  5. */
  6. // External packages:
  7. const MOMENT_TIMEZONE = require('moment-timezone');
  8. // Internal packages:
  9. const LOGGING = require('./logging'),
  10. UTIL = require('./util');
  11. // Constants:
  12. const // REGEX_TZ_CODE = /^[A-Z]{2,4}$/,
  13. REGEX_TZ_CONTINENT_AND_COUNTRY = /^[^/]+\/[^/]+$/,
  14. REGEX_REPLACE_DASHES = /_/gi,
  15. FORMAT_DATETIME = 'ddd, D MMM Y, H:mm';
  16. // Variables:
  17. var zones;
  18. /**
  19. * Set up timezones
  20. */
  21. const setUp = function() {
  22. if (zones)
  23. LOGGING.warn(`“timezones.setUp()” called more than once`);
  24. else {
  25. zones = MOMENT_TIMEZONE.tz.names();
  26. const // codes = zones.filter(v => { return v.match(REGEX_TZ_CODE); }),
  27. continentAndCountry = zones.filter(function(v) {
  28. return v.match(REGEX_TZ_CONTINENT_AND_COUNTRY);
  29. }),
  30. // others = zones.filter(v => { return !v.match(REGEX_TZ_CODE) && !v.match(REGEX_TZ_CONTINENT_AND_COUNTRY); }),
  31. continents = {UTC: {UTC: 'UTC/UTC'}};
  32. continentAndCountry.forEach(function(i) {
  33. const p = i.replace(REGEX_REPLACE_DASHES, '&nbsp;').split('/');
  34. if ('Etc' !== p[0]) {
  35. if (!continents.hasOwnProperty(p[0]))
  36. continents[p[0]] = {};
  37. if (!continents[p[0]].hasOwnProperty(p[1]))
  38. continents[p[0]][p[1]] = i;
  39. }
  40. });
  41. // Export more stuff:
  42. // exports.tzCodes = codes;
  43. exports.tzContinents = continents;
  44. // exports.tzOthers = others;
  45. exports.timezoneExists = timezoneExists;
  46. exports.processTimezone = processTimezone;
  47. exports.shiftTime = shiftTime;
  48. }
  49. };
  50. /**
  51. * Check if a string corresponds to a known timezone
  52. * @param {String} tz - the string
  53. * @returns {Boolean} whether it's a valid timezone
  54. */
  55. const timezoneExists = function(tz) {
  56. return zones.includes(tz);
  57. };
  58. /**
  59. * @TODO: Document this.
  60. */
  61. const processTimezone = function(data) {
  62. const correctedTimezone = 'UTC/UTC' === data.tz ? 'UTC' : data.tz;
  63. const m = new MOMENT_TIMEZONE().tz(correctedTimezone),
  64. abbrs = m._z.abbrs,
  65. offset = m._offset;
  66. LOGGING.dir(m);
  67. data.time = m.tz(correctedTimezone).format(FORMAT_DATETIME);
  68. data.offset = UTIL.formatDuration(offset, true);
  69. data.related = Array.from(new Set(abbrs));
  70. LOGGING.dir(data);
  71. };
  72. /**
  73. * Return the equivalent date-time in a different timezone
  74. * @param {String} to - the target timezone
  75. * @param {Object} time - (optional) the date-time (<code>now()</code> if not present)
  76. * @returns {Object} the equivalent date-time
  77. */
  78. const shiftTime = function(to, time) {
  79. const t = time ? time : new MOMENT_TIMEZONE();
  80. const result = t.tz(to).format();
  81. return result;
  82. };
  83. // Export stuff:
  84. exports.setUp = setUp;