/node_modules/moment/src/lib/units/offset.js

https://bitbucket.org/coleman333/smartsite · JavaScript · 235 lines · 176 code · 35 blank · 24 comment · 46 complexity · 784f2319ed7751e64272d0953b6cc701 MD5 · raw file

  1. import zeroFill from '../utils/zero-fill';
  2. import { createDuration } from '../duration/create';
  3. import { addSubtract } from '../moment/add-subtract';
  4. import { isMoment, copyConfig } from '../moment/constructor';
  5. import { addFormatToken } from '../format/format';
  6. import { addRegexToken, matchOffset, matchShortOffset } from '../parse/regex';
  7. import { addParseToken } from '../parse/token';
  8. import { createLocal } from '../create/local';
  9. import { prepareConfig } from '../create/from-anything';
  10. import { createUTC } from '../create/utc';
  11. import isDate from '../utils/is-date';
  12. import toInt from '../utils/to-int';
  13. import isUndefined from '../utils/is-undefined';
  14. import compareArrays from '../utils/compare-arrays';
  15. import { hooks } from '../utils/hooks';
  16. // FORMATTING
  17. function offset (token, separator) {
  18. addFormatToken(token, 0, 0, function () {
  19. var offset = this.utcOffset();
  20. var sign = '+';
  21. if (offset < 0) {
  22. offset = -offset;
  23. sign = '-';
  24. }
  25. return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
  26. });
  27. }
  28. offset('Z', ':');
  29. offset('ZZ', '');
  30. // PARSING
  31. addRegexToken('Z', matchShortOffset);
  32. addRegexToken('ZZ', matchShortOffset);
  33. addParseToken(['Z', 'ZZ'], function (input, array, config) {
  34. config._useUTC = true;
  35. config._tzm = offsetFromString(matchShortOffset, input);
  36. });
  37. // HELPERS
  38. // timezone chunker
  39. // '+10:00' > ['10', '00']
  40. // '-1530' > ['-15', '30']
  41. var chunkOffset = /([\+\-]|\d\d)/gi;
  42. function offsetFromString(matcher, string) {
  43. var matches = (string || '').match(matcher);
  44. if (matches === null) {
  45. return null;
  46. }
  47. var chunk = matches[matches.length - 1] || [];
  48. var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
  49. var minutes = +(parts[1] * 60) + toInt(parts[2]);
  50. return minutes === 0 ?
  51. 0 :
  52. parts[0] === '+' ? minutes : -minutes;
  53. }
  54. // Return a moment from input, that is local/utc/zone equivalent to model.
  55. export function cloneWithOffset(input, model) {
  56. var res, diff;
  57. if (model._isUTC) {
  58. res = model.clone();
  59. diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();
  60. // Use low-level api, because this fn is low-level api.
  61. res._d.setTime(res._d.valueOf() + diff);
  62. hooks.updateOffset(res, false);
  63. return res;
  64. } else {
  65. return createLocal(input).local();
  66. }
  67. }
  68. function getDateOffset (m) {
  69. // On Firefox.24 Date#getTimezoneOffset returns a floating point.
  70. // https://github.com/moment/moment/pull/1871
  71. return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
  72. }
  73. // HOOKS
  74. // This function will be called whenever a moment is mutated.
  75. // It is intended to keep the offset in sync with the timezone.
  76. hooks.updateOffset = function () {};
  77. // MOMENTS
  78. // keepLocalTime = true means only change the timezone, without
  79. // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
  80. // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
  81. // +0200, so we adjust the time as needed, to be valid.
  82. //
  83. // Keeping the time actually adds/subtracts (one hour)
  84. // from the actual represented time. That is why we call updateOffset
  85. // a second time. In case it wants us to change the offset again
  86. // _changeInProgress == true case, then we have to adjust, because
  87. // there is no such time in the given timezone.
  88. export function getSetOffset (input, keepLocalTime, keepMinutes) {
  89. var offset = this._offset || 0,
  90. localAdjust;
  91. if (!this.isValid()) {
  92. return input != null ? this : NaN;
  93. }
  94. if (input != null) {
  95. if (typeof input === 'string') {
  96. input = offsetFromString(matchShortOffset, input);
  97. if (input === null) {
  98. return this;
  99. }
  100. } else if (Math.abs(input) < 16 && !keepMinutes) {
  101. input = input * 60;
  102. }
  103. if (!this._isUTC && keepLocalTime) {
  104. localAdjust = getDateOffset(this);
  105. }
  106. this._offset = input;
  107. this._isUTC = true;
  108. if (localAdjust != null) {
  109. this.add(localAdjust, 'm');
  110. }
  111. if (offset !== input) {
  112. if (!keepLocalTime || this._changeInProgress) {
  113. addSubtract(this, createDuration(input - offset, 'm'), 1, false);
  114. } else if (!this._changeInProgress) {
  115. this._changeInProgress = true;
  116. hooks.updateOffset(this, true);
  117. this._changeInProgress = null;
  118. }
  119. }
  120. return this;
  121. } else {
  122. return this._isUTC ? offset : getDateOffset(this);
  123. }
  124. }
  125. export function getSetZone (input, keepLocalTime) {
  126. if (input != null) {
  127. if (typeof input !== 'string') {
  128. input = -input;
  129. }
  130. this.utcOffset(input, keepLocalTime);
  131. return this;
  132. } else {
  133. return -this.utcOffset();
  134. }
  135. }
  136. export function setOffsetToUTC (keepLocalTime) {
  137. return this.utcOffset(0, keepLocalTime);
  138. }
  139. export function setOffsetToLocal (keepLocalTime) {
  140. if (this._isUTC) {
  141. this.utcOffset(0, keepLocalTime);
  142. this._isUTC = false;
  143. if (keepLocalTime) {
  144. this.subtract(getDateOffset(this), 'm');
  145. }
  146. }
  147. return this;
  148. }
  149. export function setOffsetToParsedOffset () {
  150. if (this._tzm != null) {
  151. this.utcOffset(this._tzm, false, true);
  152. } else if (typeof this._i === 'string') {
  153. var tZone = offsetFromString(matchOffset, this._i);
  154. if (tZone != null) {
  155. this.utcOffset(tZone);
  156. }
  157. else {
  158. this.utcOffset(0, true);
  159. }
  160. }
  161. return this;
  162. }
  163. export function hasAlignedHourOffset (input) {
  164. if (!this.isValid()) {
  165. return false;
  166. }
  167. input = input ? createLocal(input).utcOffset() : 0;
  168. return (this.utcOffset() - input) % 60 === 0;
  169. }
  170. export function isDaylightSavingTime () {
  171. return (
  172. this.utcOffset() > this.clone().month(0).utcOffset() ||
  173. this.utcOffset() > this.clone().month(5).utcOffset()
  174. );
  175. }
  176. export function isDaylightSavingTimeShifted () {
  177. if (!isUndefined(this._isDSTShifted)) {
  178. return this._isDSTShifted;
  179. }
  180. var c = {};
  181. copyConfig(c, this);
  182. c = prepareConfig(c);
  183. if (c._a) {
  184. var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
  185. this._isDSTShifted = this.isValid() &&
  186. compareArrays(c._a, other.toArray()) > 0;
  187. } else {
  188. this._isDSTShifted = false;
  189. }
  190. return this._isDSTShifted;
  191. }
  192. export function isLocal () {
  193. return this.isValid() ? !this._isUTC : false;
  194. }
  195. export function isUtcOffset () {
  196. return this.isValid() ? this._isUTC : false;
  197. }
  198. export function isUtc () {
  199. return this.isValid() ? this._isUTC && this._offset === 0 : false;
  200. }