timeZone
})
+TODO
+* freeze Moment after creation (until we test it properly)
+* nextDay
+* isValid -> compute before "construction", checkOverflow
+ - do we have parsing flags if the object is constructed without format?
+* parseZone -> fixedOffset(...., 'parse') + special tmp timezone + check in quick
+* Moment should be called from 3 places (invalid, local, utc)
+OLD TODO (maybe del)
+* remove _nextDay from moment -> handle it before "creation"
+* adjust valueOf to add _offset
+* fix createInvalid
+* no more default createFromInputFallback?
+* make sure isValid is done before constrution, verify raw isValid vs moment isValid. Check also checkOverflow
+ -- moment#isValid calls raw isValid, but it should already be computed
+ -- stores result in _isValid (config or moment)
+ -- checkOverflow sets pf.overflow (-2 unset, -1 no overflow)
+ -- some places directly store _isValid
+ -> [isValid] from-anything -> prepareConfig
+ -> [isValid] from-string-and-array -> to check if tempConfig is valid
+ -- ? invalid dates should have _d == null or _d == new Date(NaN)
+* add internal method momentize that will return a new or existing obj from input
+
+!! dropping momentProperties (no longer needed by moment-timezone
+!! Duration Object should be immutable
+!! Locale(Data) should be (if not already) immutable
+
* createLocal (local)
* createLocalOrUTC (from-anything) -> just puts inp data in config object
* createFromConfig (from-anything)
* prepareConfig (from-anything)
--> from moment
--> from date
- --> from str+array configFromStringAndArray
- --> from str+fmt configFromStringAndFormat
- --> from input (str only) configFromInput
+ --> from str+array configFromStringAndArray ->.
+ --> from input (str only) configFromInput>. .
+ --> from str+fmt configFromStringAndFormat-'--'->.
+ --> from object configFromObject >. |
+ --> from array configFromArray --'--------------'
# am/pm bug 297 -- should be able to skip am/pm ?
# array of formats --> there won't be any leftovers, so rethink strict with arrays
-import { createCollect } from './from-anything';
+import { createCollect, createInvalid } from './from-anything';
import { localTimeZone } from '../timezone/local';
import { fixedTimeZoneForOffset } from '../timezone/fixed-offset';
+import { isMoment } from '../moment/constructor';
export function createUTC (input, format, locale, strict) {
return createCollect(input, format, locale, strict, fixedTimeZoneForOffset(0));
}
-export function createFixedOffset (offset) {
- // maybe parse offset
- return function (input, format, locale, strict) {
- return createCollect(input, format, locale, strict, fixedTimeZoneForOffset(offset));
+// TODO(Iskren): Enabled 'parse' offset, which uses it from the parsed string.
+export function createFixedOffset () {
+ var args = [].slice.apply(arguments),
+ reg = args.slice(0, args.length - 1),
+ last = args.length > 0 ? args[args.length - 1] : null;
+ if (args.length === 0) {
+ return createInvalid();
}
+ return createCollect(reg[0], reg[1], reg[2], reg[3], fixedTimeZoneForOffset(last));
}
-// TODO(Iskren): Recheck all internal uses and take into account that it
-// WON'T copy the zone any more
export function createLocal (input, format, locale, strict) {
return createCollect(input, format, locale, strict, localTimeZone);
}
-export function createZoned (tz) {
- return function (input, format, locale, strict) {
- return createCollect(input, format, locale, strict, tz);
+export function createZoned () {
+ var args = [].slice.apply(arguments),
+ reg = args.slice(0, args.length - 1),
+ last = args.length > 0 ? args[args.length - 1] : null;
+ if (args.length === 0) {
+ return createInvalid();
}
+ return createCollect(reg[0], reg[1], reg[2], reg[3], last);
+}
+
+// TODO (Iskren): Create defaultCreator and make it settable
+export function momentize (obj) {
+ return isMoment(obj) ? obj : createLocal(obj);
}
-export function createDate (y, m, d, h, M, s, ms) {
- // can't just apply() to create a date:
- // https://stackoverflow.com/q/181348
- var date = new Date(y, m, d, h, M, s, ms);
+// export function createDate (y, m, d, h, M, s, ms) {
+// // can't just apply() to create a date:
+// // https://stackoverflow.com/q/181348
+// var date = new Date(y, m, d, h, M, s, ms);
- // the date constructor remaps years 0-99 to 1900-1999
- if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
- date.setFullYear(y);
- }
- return date;
-}
+// // the date constructor remaps years 0-99 to 1900-1999
+// if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
+// date.setFullYear(y);
+// }
+// return date;
+// }
export function createUTCDate (y) {
var date = new Date(Date.UTC.apply(null, arguments));
import isNumber from '../utils/is-number';
import isDate from '../utils/is-date';
import map from '../utils/map';
-import { createInvalid } from './valid';
+import extend from '../utils/extend';
import { Moment, isMoment } from '../moment/constructor';
import { getLocale } from '../locale/locales';
import { hooks } from '../utils/hooks';
import checkOverflow from './check-overflow';
import { isValid } from './valid';
+import { default as getParsingFlags, defaultParsingFlags } from './parsing-flags';
import { configFromStringAndArray } from './from-string-and-array';
import { configFromStringAndFormat } from './from-string-and-format';
var updateInProgress = false;
-function createFromConfig (config) {
- var res = new Moment(checkOverflow(prepareConfig(config)));
-
- // Prevent infinite loop in case updateOffset creates new moment objects.
- // if (updateInProgress === false) {
- // updateInProgress = true;
- // res = hooks.updateOffset(res);
- // updateInProgress = false;
- // }
-
- if (res._nextDay) {
- // Adding is smart enough around DST
- res = res.add(1, 'd');
- res._nextDay = undefined;
- }
-
- return res;
+export function createInvalid(flags) {
+ flags = extend(defaultParsingFlags(), {input: NaN, format: undefined, strict: true}, flags ? flags : {});
+ return new Moment({_i: NaN, _pf: flags, _locale: getLocale(null), _d: new Date(NaN), _isValid: false});
}
-export function prepareConfig (config) {
+function createFromConfig (config) {
var input = config._i,
format = config._f;
config._i = input = config._locale.preparse(input);
}
- if (input._d != null || input._l != null && input._isAMomentObject !== true) {
- // If it looks like a moment, but isn't
- throw new Error("No uninitialized config should ever reach this place");
- } else if (isMoment(input)) {
- // TODO(iskren): This is wrong, we create moment twice, this is
- // supposed to return ready config
- //
- // TODOv3(iskren): config._i could be just config in-progress? I don't
- // think this should be allowed -- find all places by removing
- // isAMomentObject from config and setting it in the constructor.
- return new Moment(checkOverflow(input));
- } else if (isDate(input)) {
- config._d = input;
+ if (isUndefined(input)) {
+ return quickCreateUTC(hooks.now(), config._locale, config._tz);
+ } else if (isMoment(input) || isDate(input)) {
+ return quickCreateUTC(input.valueOf(), config._locale, config._tz);
+ } else if (isNumber(input)) {
+ return quickCreateUTC(input, config._locale, config._tz);
} else if (isArray(format)) {
configFromStringAndArray(config);
} else if (format) {
configFromStringAndFormat(config);
- } else {
- configFromInput(config);
- }
-
- if (!isValid(config)) {
- config._d = null;
- }
-
- return config;
-}
-
-function configFromInput(config) {
- var input = config._i;
- if (isUndefined(input)) {
- config._d = new Date(hooks.now());
- } else if (isDate(input)) {
- config._d = new Date(input.valueOf());
} else if (typeof input === 'string') {
configFromString(config);
} else if (isArray(input)) {
configFromArray(config);
} else if (isObject(input)) {
configFromObject(config);
- } else if (isNumber(input)) {
- // from milliseconds
- config._d = new Date(input);
} else {
hooks.createFromInputFallback(config);
}
+ if (!isValid(config) && (config._d == null || !isNaN(config._d.getTime()))) {
+ return createInvalid(getParsingFlags(config));
+ }
+
+ if (!config._useUTC) {
+ return quickCreateLocal(+config._d, config._locale, config._tz, config._pf);
+ } else {
+ // this case is hit only if there is a timezone present in the string,
+ // and it is not ignored with ignoreOffset: true
+ return quickCreateUTC(+config._d, config._locale, config._tz, config._pf);
+ }
+
+ // Prevent infinite loop in case updateOffset creates new moment objects.
+ // if (updateInProgress === false) {
+ // updateInProgress = true;
+ // res = hooks.updateOffset(res);
+ // updateInProgress = false;
+ // }
+
+ // if (res._nextDay) {
+ // // Adding is smart enough around DST
+ // res = res.add(1, 'd');
+ // res._nextDay = undefined;
+ // }
+
+ // return res;
}
-// TODO: Check what existing moments have in them
-// ts, off, locale, tz + parsing flags (only for new)
-export function quickCreateLocal(lts, locale, timeZone, flags) {
- var local_ts_offset = computeOffset(lts, timeZone, flags);
- return new Moment({local_ts[0], local_ts[1], locale, timeZone});
+export function prepareConfig (config) {
}
-export function quickCreateUTC(uts, locale, timeZone) {
- var offset = timeZone.offsetFromTimestamp(uts);
- return new Moment({uts + offset, offset, locale, timeZone});
+function configFromInput(config) {
+ var input = config._i;
+}
+
+export function quickCreateLocal(lts, locale, timeZone, pf) {
+ var localTsOffset = computeOffset(lts, timeZone);
+ console.log('Local', lts, '###', localTsOffset[0], localTsOffset[1]);
+ return new Moment({_ts: localTsOffset[0], _offset: localTsOffset[1], _locale: locale, _tz: timeZone, _pf: pf});
}
-function computeOffset(lts, timeZone, flags) {
- // TODO: Flags are being ignored. Take them into account some day
+export function quickCreateUTC(uts, locale, timeZone, pf) {
+ var offset = timeZone.offsetFromTimestamp(uts);
+ console.log('UTC', uts, '###', uts + offset, offset);
+ return new Moment({_ts: uts + offset, _offset: offset, _locale: locale, _tz: timeZone, _pf: pf});
+}
- var of1 = timezone.offsetFromTimestamp(lts) // we treat local timestamp as unix to get
- // a ballbpark estimate
- var of2 = timezone.offsetFromTimestamp(lts - of1) // adjust local by probable offset
- if (of1 == of2) {
+function computeOffset(lts, timeZone) {
+ // we treat local timestamp as unix to get a ballbpark estimate
+ var of1 = timeZone.offsetFromTimestamp(lts),
+ // adjust local by probable offset
+ of2 = timeZone.offsetFromTimestamp(lts - of1),
+ of3;
+ if (of1 === of2) {
// (lts, of1) is valid, but could be ambigous (second)
- of3 = timezone.offsetFromTimestamp(lts - of1 - 6 * 60 * 60 * 1000); // subtract 6h to see if
- // we're near DST
+
+ // subtract 6h to see if we're near DST
+ of3 = timeZone.offsetFromTimestamp(lts - of1 - 6 * 60 * 60 * 1000);
if (of1 === of3) {
+ // not near DST, its all good
return [lts, of1];
- } else if (timezone.offsetFromTimestamp(lts - of3) === of3) {
+ } else if (timeZone.offsetFromTimestamp(lts - of3) === of3) {
// ambiguous, variants are [lts, of3], [lts, of1], of3 being
- // the previous
+ // the first
return [lts, of3];
} else {
// there was DST shortly before [lts, of1], but it fully passed
}
} else {
// we try a second time, this could happen around invalid time
- var of3 = timezone.offsetFromTimestamp(lts - of2);
+ of3 = timeZone.offsetFromTimestamp(lts - of2);
if (of3 === of2) {
- return [lts, of2]
+ return [lts, of2];
} else {
// invalid time!
if (of2 > of3) {
var tmp = of2; of2 = of3; of3 = tmp;
}
var dstGap = of3 - of2;
- if (timezone.offsetFromTimestamp(lts + dstGap - of3) == of3) {
+ if (timeZone.offsetFromTimestamp(lts + dstGap - of3) === of3) {
return [lts + dstGap, of3];
} else {
- throw new Error("should never happen (test)");
+ throw new Error('should never happen (test)');
}
}
}
import { hooks } from '../utils/hooks';
-import { createDate, createUTCDate } from './date-from-array';
+import { createUTCDate } from './date-from-array';
+import { quickCreateUTC } from './from-anything';
import { daysInYear } from '../units/year';
import { weekOfYear, weeksInYear, dayOfYearFromWeeks } from '../units/week-calendar-utils';
import { YEAR, MONTH, DATE, HOUR, MINUTE, SECOND, MILLISECOND } from '../units/constants';
-import { createLocal } from './local';
+import { fixedTimeZoneForOffset } from '../timezone/fixed-offset';
import defaults from '../utils/defaults';
import getParsingFlags from './parsing-flags';
+import checkOverflow from './check-overflow';
-// TODO(Iskren): The proper impl of this function, should:
-// - check if there is config._tzm, if there is, get the local time in that
-// fixed offset timezone
-// - otherwise, return the local date for the config._tz (quickCreateUTC(now(),
-// _l, _tz).year()/.month()/.date()
-// But then every moment object creation creates another object ... at least
-// not recursive, but much slower.
-function currentDateArray(config) {
- // hooks is actually the exported moment object
- var nowValue = new Date(hooks.now());
- // if (config._useUTC) {
- // return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
- // }
- return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
+// TODO(Iskren): Call only if needed
+function currentDateArray(config, tz) {
+ var now = hooks.now(),
+ nowValue = new Date(now + tz.offsetFromTimestamp(now));
+ return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
}
// convert an array to a date.
// note: all values past the year are optional and will default to the lowest possible value.
// [year, month, day , hour, minute, second, millisecond]
export function configFromArray (config) {
- var i, date, input = [], currentDate, yearToUse;
+ var i, date, input = [], currentDate, yearToUse, tz = config._tz;
if (config._d) {
return;
}
- currentDate = currentDateArray(config);
+ // TODO: Implement ignoreOffset config flag
+ if (config._tzm) {
+ tz = fixedTimeZoneForOffset(config._tzm);
+ }
+
+ currentDate = currentDateArray(config, tz);
//compute day of the year from weeks and weekdays
if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
- dayOfYearFromWeekInfo(config);
+ dayOfYearFromWeekInfo(config, tz);
}
//if the day of the year is set, figure out what it is
}
config._d = createUTCDate.apply(null, input);
+ // TODO: Handle ignoreOffset flag
// Apply timezone offset from input. The actual utcOffset can be changed
// with parseZone.
if (config._tzm != null) {
config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
+ config._useUTC = true;
}
+ // TODO: Implement fixedOffset 'parse'
+ // if (config._tz === parseTimeZone) {
+ // config._tz = fixedTimeZoneForOffset(config._tzm);
+ // }
+
if (config._nextDay) {
config._a[HOUR] = 24;
}
+ checkOverflow(config);
}
-function dayOfYearFromWeekInfo(config) {
+function dayOfYearFromWeekInfo(config, tz) {
var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow, now;
w = config._w;
dow = 1;
doy = 4;
- // TODO: NOW we can do this, revisit after making sure config._tz is an
- // object at this point.
- // TODO: We need to take the current isoWeekYear, but that depends on
- // how we interpret now (local, utc, fixed offset). So create
- // a now version of current config (take local/utc/offset flags, and
- // create now).
- weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
+ // TODO: Compute only if required.
+ now = quickCreateUTC(hooks.now(), config._locale, tz);
+ weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(now, 1, 4).year);
week = defaults(w.W, 1);
weekday = defaults(w.E, 1);
if (weekday < 1 || weekday > 7) {
dow = config._locale._week.dow;
doy = config._locale._week.doy;
- var curWeek = weekOfYear(createLocal(), dow, doy);
+ // TODO: Compute only if required
+ now = quickCreateUTC(hooks.now(), config._locale, tz);
+ var curWeek = weekOfYear(now, dow, doy);
weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
configFromArray(config);
- checkOverflow(config);
}
if (matched !== null) {
config._d = new Date(+matched[1]);
+ config._useUTC = true;
return;
}
hooks.createFromInputFallback(config);
}
-hooks.createFromInputFallback = deprecate(
- 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
- 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
- 'discouraged and will be removed in an upcoming major release. Please refer to ' +
- 'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
- function (config) {
- config._d = new Date(config._i + (config._tz.type != 'local' ? ' UTC' : ''));
- }
-);
+hooks.createFromInputFallback = function (config) {
+ config._d = new Date(NaN);
+};
+
+// hooks.createFromInputFallback = deprecate(
+// 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
+// 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
+// 'discouraged and will be removed in an upcoming major release. Please refer to ' +
+// 'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
+// function (config) {
+// config._d = new Date(config._i + (config._tz.type != 'local' ? ' UTC' : ''));
+// }
+// );
-function defaultParsingFlags() {
+export function defaultParsingFlags() {
// We need to deep clone this object.
return {
+ input : null,
+ format : null,
+ strict : null,
+ offsetInInput : null,
empty : false,
unusedTokens : [],
unusedInput : [],
};
}
-export default function getParsingFlags(m) {
+export default function getParsingFlags(m, refetch) {
if (m._pf == null) {
m._pf = defaultParsingFlags();
+ m._pf.input = m._i;
+ m._pf.format = m._f;
+ m._pf.strict = m._strict;
+ }
+ if (refetch) {
+ m._pf.offsetInInput = m._tzm;
}
return m._pf;
}
import extend from '../utils/extend';
-import { createUTC } from './utc';
+import { createUTC } from './constructors';
import getParsingFlags from '../create/parsing-flags';
import some from '../utils/some';
}
return m._isValid;
}
-
-export function createInvalid (flags) {
- var m = createUTC(NaN);
- if (flags != null) {
- extend(getParsingFlags(m), flags);
- }
- else {
- getParsingFlags(m).userInvalidated = true;
- }
-
- return m;
-}
import absFloor from '../utils/abs-floor';
import absCeil from '../utils/abs-ceil';
-import { createUTCDate } from '../create/date-from-array';
export function bubble (duration) {
var milliseconds = duration._milliseconds;
import { Duration, isDuration } from './constructor';
+import { momentize } from '../create/constructors';
import isNumber from '../utils/is-number';
import toInt from '../utils/to-int';
import absRound from '../utils/abs-round';
import hasOwnProp from '../utils/has-own-prop';
import { DATE, HOUR, MINUTE, SECOND, MILLISECOND } from '../units/constants';
-import { cloneWithOffset } from '../units/offset';
-import { createLocal } from '../create/local';
+import { changeTimezone } from '../units/offset';
import { createInvalid as invalid } from './valid';
// ASP.NET json date format regex
} else if (duration == null) {// checks for null or undefined
duration = {};
} else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
- // TODO: Do not createLocal, instead, use the zone of one of them, and
- // align the other.
- diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
+ diffRes = momentsDifference(duration.from, duration.to);
duration = {};
duration.ms = diffRes.milliseconds;
function momentsDifference(base, other) {
var res;
+ base = momentize(base);
+ other = changeTimezone(momentize(other), base._tz);
if (!(base.isValid() && other.isValid())) {
return {milliseconds: 0, months: 0};
}
- other = cloneWithOffset(other, base);
if (base.isBefore(other)) {
res = positiveMomentsDifference(base, other);
} else {
import isNumber from '../utils/is-number';
import { getLocale } from './locales';
-import { createUTC } from '../create/utc';
+import { createUTC } from '../create/constructors';
function get (format, index, field, setter) {
var locale = getLocale();
import { deprecateSimple } from '../utils/deprecate';
import { hooks } from '../utils/hooks';
import absRound from '../utils/abs-round';
+import { quickCreateUTC, quickCreateLocal } from '../create/from-anything';
// TODO: remove 'name' arg after deprecation is removed
d = new Date(mom._d);
if (months) {
// takes care of 31st Jan + 1m -> 28th Feb
- smartSetUTCMonth(d, d.getUTCMonth() + months);
+ smartSetUTCMonth(d, d.getUTCMonth() + months * isAdding);
}
if (days) {
- d.setUTCDate(d.getUTCDate() + days);
+ d.setUTCDate(d.getUTCDate() + days * isAdding);
}
- return quickCreateLocal(d.valueOf() + milliseconds, mom._l, mom._tz);
+ return quickCreateLocal(d.valueOf() + milliseconds * isAdding, mom._locale, mom._tz);
} else {
- return quickCreateUTC(mom.unix() + milliseconds, mom._l, mom._tz);
+ return quickCreateUTC(mom.valueOf() + milliseconds * isAdding, mom._locale, mom._tz);
}
-
-// if (milliseconds) {
-// // TODOv3 -- work on the config if necessary
-// // TODOv3 -- 1) order MS, D, M or M, D, MS
-// // TODOv3 -- 2) work on date object directly (all operations)
-// // TODOv3 -- 3) figure out updateOffset so it only happens once in
-// // constructor
-// mom = new Moment(mom);
-// mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
-// }
-// if (days) {
-// mom = set(mom, 'Date', get(mom, 'Date') + days * isAdding);
-// }
-// if (months) {
-// mom = setMonth(mom, get(mom, 'Month') + months * isAdding);
-// }
-// if (updateOffset) {
-// mom = hooks.updateOffset(mom, days || months);
-// }
-// return mom;
}
export var add = createAdder(1, 'add');
-import { createLocal } from '../create/local';
-import { cloneWithOffset } from '../units/offset';
import isFunction from '../utils/is-function';
import { hooks } from '../utils/hooks';
+import { momentize } from '../create/constructors';
export function getCalendarFormat(myMoment, now) {
var diff = myMoment.diff(now, 'days', true);
export function calendar (time, formats) {
// We want to compare the start of today, vs this.
// Getting start-of-today depends on whether we're local/utc/offset or not.
- var now = time != null ? createLocal(time) : createLocal(),
- sod = cloneWithOffset(now, this).startOf('day'),
+ var now = momentize(time != null ? time : undefined),
+ sod = now.zoneData(this.zoneData()).startOf('day'),
format = hooks.calendarFormat(this, sod) || 'sameElse';
var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
-import { isMoment } from './constructor';
import { normalizeUnits } from '../units/aliases';
-import { createLocal } from '../create/local';
+import { momentize } from '../create/constructors';
import isUndefined from '../utils/is-undefined';
export function isAfter (input, units) {
- var localInput = isMoment(input) ? input : createLocal(input);
- if (!(this.isValid() && localInput.isValid())) {
+ input = momentize(input);
+ if (!(this.isValid() && input.isValid())) {
return false;
}
units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
if (units === 'millisecond') {
- return this.valueOf() > localInput.valueOf();
+ return this.valueOf() > input.valueOf();
} else {
- return localInput.valueOf() < this.startOf(units).valueOf();
+ return input.valueOf() < this.startOf(units).valueOf();
}
}
export function isBefore (input, units) {
- var localInput = isMoment(input) ? input : createLocal(input);
- if (!(this.isValid() && localInput.isValid())) {
+ input = momentize(input);
+ if (!(this.isValid() && input.isValid())) {
return false;
}
units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
if (units === 'millisecond') {
- return this.valueOf() < localInput.valueOf();
+ return this.valueOf() < input.valueOf();
} else {
- return this.endOf(units).valueOf() < localInput.valueOf();
+ return this.endOf(units).valueOf() < input.valueOf();
}
}
}
export function isSame (input, units) {
- var localInput = isMoment(input) ? input : createLocal(input),
- inputMs;
- if (!(this.isValid() && localInput.isValid())) {
+ var inputMs;
+ input = momentize(input);
+ if (!(this.isValid() && input.isValid())) {
return false;
}
units = normalizeUnits(units || 'millisecond');
if (units === 'millisecond') {
- return this.valueOf() === localInput.valueOf();
+ return this.valueOf() === input.valueOf();
} else {
- inputMs = localInput.valueOf();
+ inputMs = input.valueOf();
return this.startOf(units).valueOf() <= inputMs && inputMs <= this.endOf(units).valueOf();
}
}
export function copyConfig(to, from) {
var i, prop, val;
- if (!isUndefined(from._isAMomentObject)) {
- to._isAMomentObject = from._isAMomentObject;
- }
- if (!isUndefined(from._i)) {
- to._i = from._i;
- }
- if (!isUndefined(from._f)) {
- to._f = from._f;
- }
- if (!isUndefined(from._l)) {
- to._l = from._l;
- }
- if (!isUndefined(from._strict)) {
- to._strict = from._strict;
- }
- if (!isUndefined(from._tzm)) {
- to._tzm = from._tzm;
- }
- if (!isUndefined(from._isUTC)) {
- to._isUTC = from._isUTC;
- }
+ // TODO(iskren): These are going in parsing flags
+ // if (!isUndefined(from._i)) {
+ // to._i = from._i;
+ // }
+ // if (!isUndefined(from._f)) {
+ // to._f = from._f;
+ // }
+ // if (!isUndefined(from._l)) {
+ // to._l = from._l;
+ // }
+ // if (!isUndefined(from._strict)) {
+ // to._strict = from._strict;
+ // }
+ // if (!isUndefined(from._tzm)) {
+ // to._tzm = from._tzm;
+ // }
+
+ // this can not be null, and should be a freshly created object
+ to._d = from._ts != null ? new Date(from._ts) : from._d;
if (!isUndefined(from._offset)) {
to._offset = from._offset;
}
if (!isUndefined(from._pf)) {
- to._pf = getParsingFlags(from);
+ to._pf = getParsingFlags(from, true);
}
if (!isUndefined(from._locale)) {
to._locale = from._locale;
}
-
- if (momentProperties.length > 0) {
- for (i = 0; i < momentProperties.length; i++) {
- prop = momentProperties[i];
- val = from[prop];
- if (!isUndefined(val)) {
- to[prop] = val;
- }
- }
+ if (!isUndefined(from._tz)) {
+ to._tz = from._tz;
}
+ if (!isUndefined(from._isValid)) {
+ to._isValid = from._isValid;
+ }
+
+ // TODO(iskren): Drop these, not needed any more
+ // if (momentProperties.length > 0) {
+ // for (i = 0; i < momentProperties.length; i++) {
+ // prop = momentProperties[i];
+ // val = from[prop];
+ // if (!isUndefined(val)) {
+ // to[prop] = val;
+ // }
+ // }
+ // }
return to;
}
// (Or just use from-anything's createFromConfig(), which handles this for you.)
export function Moment(config) {
copyConfig(this, config);
- this._d = new Date(config._d != null ? config._d.getTime() : NaN);
- if (!this.isValid()) {
- this._d = new Date(NaN);
- }
this._isAMomentObject = true;
}
input: this._i,
format: this._f,
locale: this._locale,
- isUTC: this._isUTC,
+ tz: this._tz,
strict: this._strict
};
}
import absFloor from '../utils/abs-floor';
-import { cloneWithOffset } from '../units/offset';
+import { changeTimezone } from '../units/offset';
import { normalizeUnits } from '../units/aliases';
+import { momentize } from '../create/constructors';
export function diff (input, units, asFloat) {
var that,
return NaN;
}
- that = cloneWithOffset(input, this);
+ that = changeTimezone(momentize(input), this._tz);
if (!that.isValid()) {
return NaN;
import { createDuration } from '../duration/create';
-import { createLocal } from '../create/local';
-import { isMoment } from '../moment/constructor';
+import { momentize, createLocal } from '../create/constructors';
export function from (time, withoutSuffix) {
- if (this.isValid() &&
- ((isMoment(time) && time.isValid()) ||
- createLocal(time).isValid())) {
+ time = momentize(time);
+ if (this.isValid() && time.isValid()) {
return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
} else {
return this.localeData().invalidDate();
import { Moment } from './constructor';
import { normalizeUnits, normalizeObjectUnits } from '../units/aliases';
import { getPrioritizedUnits } from '../units/priorities';
+import { smartSetUTCMonth } from '../units/month';
import { hooks } from '../utils/hooks';
+import { quickCreateUTC, quickCreateLocal } from '../create/from-anything';
import isFunction from '../utils/is-function';
};
}
-function get (mom, unit) {
+export function get (mom, unit) {
return mom.isValid() ?
- mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
+ mom._d['getUTC' + unit]() : NaN;
}
function set (mom, unit, value, msCoef) {
if (!mom.isValid()) {
return mom;
- // TODOv3 -- clone & modify config directly
}
var d, uts;
+ console.log('SET', arguments);
if (msCoef != null) {
// this is one of ms, second, minute, hour
- uts = mom.unix();
- uts += (unit - get(mom, unit)) * msCoef;
- return quickCreateUTC(uts, mom._l, mom._tz);
+ uts = mom.valueOf();
+ uts += (value - get(mom, unit)) * msCoef;
+ return quickCreateUTC(uts, mom._locale, mom._tz);
} else {
- // this is one of day, year. NOT month
+ // day or year, NOT month
d = new Date(mom._d);
d['setUTC' + unit](value);
- return quickCreateLocal(d.valueOf(), mom._l, mom._tz);
+ return quickCreateLocal(d.valueOf(), mom._locale, mom._tz);
}
}
-import { Moment } from './constructor';
+import { quickCreateUTC } from '../create/from-anything';
import { getLocale } from '../locale/locales';
+
// If passed a locale key, it will return a cloned instance that is set
// to the specified locale. Otherwise, it will return the name of the
// locale that is set on this instance.
} else {
newLocaleData = getLocale(key);
if (newLocaleData != null) {
- return quickCreateUTC(this.unix(), newLocaleData, this._tz);
+ return quickCreateUTC(this.valueOf(), newLocaleData, this._tz);
}
return this;
}
import { deprecate } from '../utils/deprecate';
import isArray from '../utils/is-array';
-import { createLocal } from '../create/local';
-import { createInvalid } from '../create/valid';
+import { createLocal } from '../create/constructors';
+import { createInvalid } from '../create/from-anything';
export var prototypeMin = deprecate(
'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
-import { createLocal } from '../create/local';
-import { createUTC } from '../create/utc';
-import { createInvalid } from '../create/valid';
+import { createLocal, createUTC, createFixedOffset } from '../create/constructors';
+import { createInvalid } from '../create/from-anything';
import { isMoment } from './constructor';
import { min, max } from './min-max';
import { now } from './now';
return createLocal(input * 1000);
}
-function createInZone () {
- return createLocal.apply(null, arguments).parseZone();
-}
+// function createInZone () {
+// return createLocal.apply(null, arguments).parseZone();
+// }
export {
now,
createUTC,
createUnix,
createLocal,
- createInZone,
+ createFixedOffset,
createInvalid,
momentPrototype
};
proto.isUTC = isUtc;
// Timezone
-import { getZoneAbbr, getZoneName } from '../units/timezone';
+import { getZoneAbbr, getZoneName, getSetZoneData } from '../units/timezone';
proto.zoneAbbr = getZoneAbbr;
proto.zoneName = getZoneName;
+proto.zoneData = getSetZoneData;
// Deprecations
import { deprecate } from '../utils/deprecate';
proto.zone = deprecate(
'moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/',
getSetZone);
-proto.isDSTShifted = deprecate(
- 'isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information',
- isDaylightSavingTimeShifted);
+// proto.isDSTShifted = deprecate(
+// 'isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information',
+// isDaylightSavingTimeShifted);
export default proto;
export function valueOf () {
- return this._d.valueOf() - ((this._offset || 0) * 60000);
+ return this._d.valueOf() - (this._offset || 0);
}
export function unix () {
import { createDuration } from '../duration/create';
-import { createLocal } from '../create/local';
-import { isMoment } from '../moment/constructor';
+import { momentize, createLocal } from '../create/constructors';
export function to (time, withoutSuffix) {
- if (this.isValid() &&
- ((isMoment(time) && time.isValid()) ||
- createLocal(time).isValid())) {
+ time = momentize(time);
+ if (this.isValid() && time.isValid()) {
return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
} else {
return this.localeData().invalidDate();
import getParsingFlags from '../create/parsing-flags';
export function isValid () {
- return _isValid(this);
+ return this._isValid !== false;
}
+// TODO: Why copy?
export function parsingFlags () {
return extend({}, getParsingFlags(this));
}
--- /dev/null
+import hasOwnProp from '../utils/has-own-prop';
+
+var memo = {};
+
+function FixedOffsetTimeZone(offset) {
+ this.offset = offset;
+ this.offsetMs = offset * 60 * 1000;
+}
+
+FixedOffsetTimeZone.fromOffset = function (offset) {
+ if (!hasOwnProp(memo, offset)) {
+ memo[offset] = new FixedOffsetTimeZone(offset);
+ }
+ return memo[offset];
+};
+
+FixedOffsetTimeZone.prototype.offsetFromTimestamp = function (uts) {
+ return this.offsetMs;
+};
+
+FixedOffsetTimeZone.prototype.type = 'fixed-offset';
+
+export var fixedTimeZoneForOffset = FixedOffsetTimeZone.fromOffset;
--- /dev/null
+function LocalTimeZone() {
+}
+
+LocalTimeZone.prototype.offsetFromTimestamp = function (uts) {
+ return -(new Date(uts).getTimezoneOffset()) * 60 * 1000;
+};
+
+LocalTimeZone.prototype.type = 'local';
+
+export var localTimeZone = new LocalTimeZone();
import isArray from '../utils/is-array';
import indexOf from '../utils/index-of';
import hasOwnProp from '../utils/has-own-prop';
-import { createUTC } from '../create/utc';
+import { createUTC } from '../create/constructors';
import getParsingFlags from '../create/parsing-flags';
// FORMATTING
if (!this.isValid()) {
return input != null ? this : NaN;
}
- var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
+ var day = this._d.getUTCDay();
if (input != null) {
input = parseWeekday(input, this.localeData());
return this.add(input - day, 'd');
import { addUnitPriority } from './priorities';
import { addRegexToken, match3, match1to3 } from '../parse/regex';
import { daysInYear } from './year';
-import { createUTCDate } from '../create/date-from-array';
import { addParseToken } from '../parse/token';
import toInt from '../utils/to-int';
import isArray from '../utils/is-array';
import isNumber from '../utils/is-number';
import indexOf from '../utils/index-of';
-import { createUTC } from '../create/utc';
+import { quickCreateLocal } from '../create/from-anything';
import getParsingFlags from '../create/parsing-flags';
+import { createUTC } from '../create/constructors';
export function daysInMonth(year, month) {
return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
}
}
- // TODOv3 -- there is a low-level set method, this should be one of its
- // cases.
d = new Date(mom._d);
smartSetUTCMonth(d, value);
- return quickCreateLocal(d.valueOf(), mom._l, mom._tz);
+ return quickCreateLocal(d.valueOf(), mom._locale, mom._tz);
}
export function smartSetUTCMonth(d, month) {
- var dayOfMonth = Math.min(d.getUTCDate(), daysInMonth(d.getUTCFullYear(), value));
- d.setUTCMonth(value, dayOfMonth);
+ var dayOfMonth = Math.min(d.getUTCDate(), daysInMonth(d.getUTCFullYear(), month));
+ d.setUTCMonth(month, dayOfMonth);
}
export function getSetMonth (value) {
import zeroFill from '../utils/zero-fill';
+import { momentize } from '../create/constructors';
import { createDuration } from '../duration/create';
import { addSubtract } from '../moment/add-subtract';
-import { Moment, isMoment, copyConfig } from '../moment/constructor';
import { addFormatToken } from '../format/format';
import { addRegexToken, matchOffset, matchShortOffset } from '../parse/regex';
import { addParseToken } from '../parse/token';
-import { createLocal } from '../create/local';
import { quickCreateLocal, quickCreateUTC } from '../create/from-anything';
-import { createUTC } from '../create/utc';
import isDate from '../utils/is-date';
import toInt from '../utils/to-int';
import isUndefined from '../utils/is-undefined';
import compareArrays from '../utils/compare-arrays';
import { hooks } from '../utils/hooks';
+import { localTimeZone } from '../timezone/local';
+import { fixedTimeZoneForOffset } from '../timezone/fixed-offset';
// FORMATTING
parts[0] === '+' ? minutes : -minutes;
}
-// Return a moment from input, that is local/utc/zone equivalent to model.
-export function cloneWithOffset(input, model) {
- // TODO: input could be a non-moment object, in certain cases
- // createLocal("....z") --> is this UTC?
- return changeTimezone(input, model._tz);
-}
-
function getDateOffset (m) {
// On Firefox.24 Date#getTimezoneOffset returns a floating point.
// https://github.com/moment/moment/pull/1871
// _changeInProgress == true case, then we have to adjust, because
// there is no such time in the given timezone.
-function changeTimezone(mom, newTz, keepLocalTime) {
+export function changeTimezone(mom, newTz, keepLocalTime) {
// TODO: Check if newTz is same as current (by comparing zone._key or sth)
// -- it is used a lot with possibly same tz (from cloneWithOffset)
if (keepLocalTime) {
- return quickCreateLocal(mom._d.valueOf(), mom._l, newTz);
+ return quickCreateLocal(mom._d.valueOf(), mom._locale, newTz);
} else {
- return quickCreateUTC(mom.unix(), mom._l, newTz);
+ return quickCreateUTC(mom.valueOf(), mom._locale, newTz);
}
}
if (typeof input === 'string') {
input = offsetFromString(matchShortOffset, input);
if (input === null) {
- return mom;
+ return this;
}
} else if (Math.abs(input) < 16 && !keepMinutes) {
input = input * 60;
// if (this._tz.type === 'fixed-offset' && this._tz.offset === input) {
// return mom;
// }
- var newTz = FixedOffsetTimeZone.fromOffset(input);
+ var newTz = fixedTimeZoneForOffset(input);
return changeTimezone(this, newTz, keepLocalTime);
} else {
return this._offset / 60000;
}
export function setOffsetToUTC (keepLocalTime) {
- return changeTimezone(this, FixedOffsetTimeZone.fromOffset(0), keepLocalTime);
+ return changeTimezone(this, fixedTimeZoneForOffset(0), keepLocalTime);
}
export function setOffsetToLocal (keepLocalTime) {
- return changeTimezone(this, LocalTimeZone.instance(), keepLocalTime);
+ return changeTimezone(this, localTimeZone, keepLocalTime);
}
export function setOffsetToParsedOffset () {
if (!this.isValid()) {
return false;
}
- input = input ? createLocal(input).utcOffset() : 0;
+ input = input != null ? momentize(input).utcOffset() : 0;
return (this.utcOffset() - input) % 60 === 0;
}
// }
export function isLocal () {
- return this._tz.type == 'local';
+ return this._tz.type === 'local';
}
export function isUtcOffset () {
- return this._tz.type == 'fixed-offset';
+ return this._tz.type === 'fixed-offset';
}
export function isUtc () {
- return this._tz.type == 'fixed-offset' && this._tz.offset === 0;
+ return this._tz.type === 'fixed-offset' && this._tz.offset === 0;
}
import { addFormatToken } from '../format/format';
+import { changeTimezone } from './offset';
// FORMATTING
// MOMENTS
+// TODO(Iskren): use _tz provided functions
export function getZoneAbbr () {
- return this._isUTC ? 'UTC' : '';
+ return this._tz.type === 'fixed-offset' && this._tz.offset === 0 ? 'UTC' : '';
}
+// TODO(Iskren): use _tz provided functions
export function getZoneName () {
- return this._isUTC ? 'Coordinated Universal Time' : '';
+ return this._tz.type === 'fixed-offset' && this._tz.offset === 0 ? 'Coordinated Universal Time' : '';
+}
+
+export function getSetZoneData (input) {
+ if (input == null) {
+ return this._tz;
+ } else {
+ return changeTimezone(this, input);
+ }
}
// TODOv3 -- I guess the generic set method should accept all args that the Date
// object accepts.
d.setUTCFullYear(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
- return quickCreateLocal(d.valueOf(), mom._l, mom._tz);
+ return quickCreateLocal(d.valueOf(), mom._locale, mom._tz);
}
// PRIORITY
createUnix as unix,
createLocal as local,
createInvalid as invalid,
- createInZone as parseZone
+ createFixedOffset as fixedOffset
} from './lib/moment/moment';
import {
moment.duration = duration;
moment.isMoment = isMoment;
moment.weekdays = weekdays;
-moment.parseZone = parseZone;
+moment.fixedOffset = fixedOffset;
moment.localeData = localeData;
moment.isDuration = isDuration;
moment.monthsShort = monthsShort;