UNPKG

intl-relativeformat

Version:

Formats JavaScript dates to relative time strings.

202 lines (197 loc) 8.12 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = global || self, global.IntlRelativeFormat = factory()); }(this, function () { 'use strict'; /* Copyright (c) 2014, Yahoo! Inc. All rights reserved. Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. */ function daysToYears(days) { // 400 years have 146097 days (taking into account leap year rules) return (days * 400) / 146097; } // Thanks to date-fns // https://github.com/date-fns/date-fns // MIT © Sasha Koss var MILLISECONDS_IN_MINUTE = 60000; var MILLISECONDS_IN_DAY = 86400000; function startOfDay(dirtyDate) { var date = new Date(dirtyDate); date.setHours(0, 0, 0, 0); return date; } function differenceInCalendarDays(dirtyDateLeft, dirtyDateRight) { var startOfDayLeft = startOfDay(dirtyDateLeft); var startOfDayRight = startOfDay(dirtyDateRight); var timestampLeft = startOfDayLeft.getTime() - startOfDayLeft.getTimezoneOffset() * MILLISECONDS_IN_MINUTE; var timestampRight = startOfDayRight.getTime() - startOfDayRight.getTimezoneOffset() * MILLISECONDS_IN_MINUTE; // Round the number of days to the nearest integer // because the number of milliseconds in a day is not constant // (e.g. it's different in the day of the daylight saving time clock shift) return Math.round((timestampLeft - timestampRight) / MILLISECONDS_IN_DAY); } function diff(from, to) { // Convert to ms timestamps. from = +from; to = +to; var millisecond = Math.round(to - from), second = Math.round(millisecond / 1000), minute = Math.round(second / 60), hour = Math.round(minute / 60); // We expect a more precision in rounding when dealing with // days as it feels wrong when something happended 13 hours ago and // is regarded as "yesterday" even if the time was this morning. var day = differenceInCalendarDays(to, from); var week = Math.round(day / 7); var rawYears = daysToYears(day), month = Math.round(rawYears * 12), year = Math.round(rawYears); return { second: second, 'second-short': second, 'second-narrow': second, minute: minute, 'minute-short': minute, 'minute-narrow': minute, hour: hour, 'hour-short': hour, 'hour-narrow': hour, day: day, 'day-short': day, 'day-narrow': day, week: week, 'week-short': week, 'week-narrow': week, month: month, 'month-short': month, 'month-narrow': month, year: year, 'year-short': year, 'year-narrow': year }; } /* Copyright (c) 2014, Yahoo! Inc. All rights reserved. Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. */ // ----------------------------------------------------------------------------- var SUPPORTED_FIELDS = [ "second" /* second */, "second-short" /* secondShort */, "minute" /* minute */, "minute-short" /* minuteShort */, "hour" /* hour */, "hour-short" /* hourShort */, "day" /* day */, "day-short" /* dayShort */, "month" /* month */, "month-short" /* monthShort */, "year" /* year */, "year-short" /* yearShort */ ]; function isValidUnits(units) { if (!units || ~SUPPORTED_FIELDS.indexOf(units)) { return true; } if (typeof units === 'string') { var suggestion = /s$/.test(units) && units.substr(0, units.length - 1); if (suggestion && ~SUPPORTED_FIELDS.indexOf(suggestion)) { throw new Error("\"" + units + "\" is not a valid IntlRelativeFormat 'units' value, did you mean: " + suggestion); } } throw new Error("\"" + units + "\" is not a valid IntlRelativeFormat 'units' value, it must be one of: " + SUPPORTED_FIELDS.join('", "')); } function resolveStyle(style) { // Default to "best fit" style. if (!style) { return "best fit" /* bestFit */; } if (style === 'best fit' || style === 'numeric') { return style; } throw new Error("\"" + style + "\" is not a valid IntlRelativeFormat 'style' value, it must be one of: 'best fit' or 'numeric'"); } function selectUnits(diffReport) { var fields = SUPPORTED_FIELDS.filter(function (field) { return field.indexOf('-short') < 1; }); var units = fields[0]; for (var _i = 0, fields_1 = fields; _i < fields_1.length; _i++) { units = fields_1[_i]; if (Math.abs(diffReport[units]) < RelativeFormat.thresholds[units]) { break; } } return units; } var RelativeFormat = (function (locales, options) { if (options === void 0) { options = {}; } var resolvedOptions = { style: resolveStyle(options.style), units: isValidUnits(options.units) && options.units }; var numeric = resolvedOptions.style === 'best fit' ? 'auto' : 'always'; var rtf = new Intl.RelativeTimeFormat(locales, { numeric: numeric }); return { format: function (date, options) { var now = options && options.now !== undefined ? options.now === null ? 0 : options.now : Date.now(); if (date === undefined) { date = now; } // Determine if the `date` and optional `now` values are valid, and throw a // similar error to what `Intl.DateTimeFormat#format()` would throw. if (!isFinite(now)) { throw new RangeError('The `now` option provided to IntlRelativeFormat#format() is not ' + 'in valid range.'); } if (!isFinite(date)) { throw new RangeError('The date value provided to IntlRelativeFormat#format() is not ' + 'in valid range.'); } var diffReport = diff(now, date); var units = resolvedOptions.units || selectUnits(diffReport); var diffInUnits = diffReport[units]; var style = units.substring(units.length - 6, units.length) === '-short' ? 'narrow' : 'long'; var rtfUnit = units.replace('-short', ''); return new Intl.RelativeTimeFormat(locales, { numeric: numeric, style: style }).format(diffInUnits, rtfUnit); }, resolvedOptions: function () { return { locale: rtf.resolvedOptions().locale, style: resolvedOptions.style, units: resolvedOptions.units }; } }; }); // Define public `defaultLocale` property which can be set by the developer, or // it will be set when the first RelativeFormat instance is created by // leveraging the resolved locale from `Intl`. RelativeFormat.defaultLocale = 'en'; RelativeFormat.thresholds = { second: 45, 'second-short': 45, minute: 45, 'minute-short': 45, hour: 22, 'hour-short': 22, day: 26, 'day-short': 26, month: 11, 'month-short': 11 // months to year }; return RelativeFormat; })); //# sourceMappingURL=intl-relativeformat.js.map