index.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. var typeToPos = {
  2. year: 0,
  3. month: 1,
  4. day: 2,
  5. hour: 3,
  6. minute: 4,
  7. second: 5
  8. };
  9. var ms = 'ms';
  10. export default (function (o, c, d) {
  11. var defaultTimezone;
  12. var localUtcOffset = d().utcOffset();
  13. var tzOffset = function tzOffset(timestamp, timezone) {
  14. var date = new Date(timestamp);
  15. var dtf = new Intl.DateTimeFormat('en-US', {
  16. hour12: false,
  17. timeZone: timezone,
  18. year: 'numeric',
  19. month: '2-digit',
  20. day: '2-digit',
  21. hour: '2-digit',
  22. minute: '2-digit',
  23. second: '2-digit'
  24. });
  25. var formatResult = dtf.formatToParts(date);
  26. var filled = [];
  27. for (var i = 0; i < formatResult.length; i += 1) {
  28. var _formatResult$i = formatResult[i],
  29. type = _formatResult$i.type,
  30. value = _formatResult$i.value;
  31. var pos = typeToPos[type];
  32. if (pos >= 0) {
  33. filled[pos] = parseInt(value, 10);
  34. }
  35. } // Workaround for the same behavior in different node version
  36. // https://github.com/nodejs/node/issues/33027
  37. var hour = filled[3];
  38. var fixedHour = hour === 24 ? 0 : hour;
  39. var utcString = filled[0] + "-" + filled[1] + "-" + filled[2] + " " + fixedHour + ":" + filled[4] + ":" + filled[5] + ":000";
  40. var utcTs = d.utc(utcString).valueOf();
  41. var asTS = +date;
  42. var over = asTS % 1000;
  43. asTS -= over;
  44. return (utcTs - asTS) / (60 * 1000);
  45. }; // find the right offset a given local time. The o input is our guess, which determines which
  46. // offset we'll pick in ambiguous cases (e.g. there are two 3 AMs b/c Fallback DST)
  47. // https://github.com/moment/luxon/blob/master/src/datetime.js#L76
  48. var fixOffset = function fixOffset(localTS, o0, tz) {
  49. // Our UTC time is just a guess because our offset is just a guess
  50. var utcGuess = localTS - o0 * 60 * 1000; // Test whether the zone matches the offset for this ts
  51. var o2 = tzOffset(utcGuess, tz); // If so, offset didn't change and we're done
  52. if (o0 === o2) {
  53. return [utcGuess, o0];
  54. } // If not, change the ts by the difference in the offset
  55. utcGuess -= (o2 - o0) * 60 * 1000; // If that gives us the local time we want, we're done
  56. var o3 = tzOffset(utcGuess, tz);
  57. if (o2 === o3) {
  58. return [utcGuess, o2];
  59. } // If it's different, we're in a hole time.
  60. // The offset has changed, but the we don't adjust the time
  61. return [localTS - Math.min(o2, o3) * 60 * 1000, Math.max(o2, o3)];
  62. };
  63. var proto = c.prototype;
  64. proto.tz = function (timezone) {
  65. if (timezone === void 0) {
  66. timezone = defaultTimezone;
  67. }
  68. var target = this.toDate().toLocaleString('en-US', {
  69. timeZone: timezone
  70. });
  71. var diff = Math.round((this.toDate() - new Date(target)) / 1000 / 60);
  72. return d(target).utcOffset(localUtcOffset - diff, true).$set(ms, this.$ms);
  73. };
  74. d.tz = function (input, timezone) {
  75. if (timezone === void 0) {
  76. timezone = defaultTimezone;
  77. }
  78. var previousOffset = tzOffset(+d(), timezone);
  79. var localTs;
  80. if (typeof input !== 'string') {
  81. // timestamp number || js Date || Day.js
  82. localTs = d(input) + previousOffset * 60 * 1000;
  83. }
  84. localTs = localTs || d.utc(input).valueOf();
  85. var _fixOffset = fixOffset(localTs, previousOffset, timezone),
  86. targetTs = _fixOffset[0],
  87. targetOffset = _fixOffset[1];
  88. var ins = d(targetTs).utcOffset(targetOffset);
  89. return ins;
  90. };
  91. d.tz.guess = function () {
  92. return Intl.DateTimeFormat().resolvedOptions().timeZone;
  93. };
  94. d.tz.setDefault = function (timezone) {
  95. defaultTimezone = timezone;
  96. };
  97. });