包详细信息

ember-moment

adopted-ember-addons147.9kMIT10.0.2

Moment.js template helpers Ember.js

ember-addon, moment, momentjs

自述文件

ember-moment

npm Version Build Status Ember Observer Score

moment.js template helpers for Ember.js

Compatibility

  • Ember.js v3.16 or above
  • Embroider or ember-auto-import 2.0

Using Moment.js in Ember Apps & Addons

This addon provides Ember-specific Helpers and a Service that make it convenient to use Moment.js in your templates. If you just want to call Moment.js directly from Javascript, you don't need this addon.

The recommended way to use Moment.js in an Ember app is:

  1. Add either moment or moment-timezone to your dependencies.
  2. Make sure you have ember-auto-import in your dependencies.
  3. Make sure you don't have ember-cli-moment-shim in your dependencies (it would add a redundant copy).
  4. Use imports in your Javascript like import moment from 'moment' or import moment from 'moment-timezone'.
  5. Optional but strongly recommended: Configure which locales and timezones will be included in your app by following the instructions below in "Controlling Locale and Timezone Data".

The recommended way to use Moment.js in an Ember addon is:

  1. Add either moment or moment-timezone to your peerDependencies. This ensures that your addon and the app must use the same copy.
  2. Also add it to your devDependencies so your own test suite satisfies the peerDep.
  3. Make sure you don't depend on ember-cli-moment-shim.
  4. Make sure you do depend on ember-auto-import.

Moment itself is no longer actively developed and new projects should not add it. You can look at alternative libraries like Luxon, or better yet keep an eye on Temporal which is likely to add moment-like capabilities directly to Javascript quite soon.

Controlling Locale and Timezone Data

Apps should configure their locale and timezone support (which can have a large impact on bundle size) by following Moment's documentation about Webpack:

and passing the resulting webpack configuration to either ember-auto-import or Embroider. For example:

const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
const MomentTimezoneDataPlugin = require('moment-timezone-data-webpack-plugin');

module.exports = function (defaults) {
  let app = new EmberApp(defaults, {
    autoImport: {
      webpack: {
        plugins: [
          new MomentLocalesPlugin({
            // 'en' is built into moment and cannot be removed. This strips the others.
            localesToKeep: [], 
          }),

          new MomentTimezoneDataPlugin({
            // Keep timezone data for the US, covering all possible years.
            matchCountries: 'US',
          }),
        ],
      },
    },
  });

Installing or Upgrading ember-moment

  1. First, install Moment.js using the instructions above.
  2. Then you can install ember-moment: ember install ember-moment

Compatibility:

  • Ember Octane+ : >= v9 // the default branch
  • Ember Classic : < v9 // the ember-classic branch.

    the ember-classic branch is in maintenance mode, and will only receive bugfixes

Usage

Helpers

moment

{{moment <date>}}
Parameters Values
<date> Any value(s) interpretable as a date/time by moment (a date String or a Moment or a Date...)

Returns a Moment.

Example

{{moment '12-25-1995' 'MM-DD-YYYY'}} {{!-- Mon Dec 25 1995 00:00:00 GMT-0500 --}}

utc

{{utc <date>}}
{{utc}}
Parameters Values
<date> Any value(s) interpretable as a date/time by moment (a date String or a Moment or a Date...)

Returns a Moment with utc mode set.

Example

{{utc '2001-10-31T08:24:56'}} {{!-- Wed Oct 31 2001 08:24:56 GMT+0000 --}}
{{utc}} {{!-- current time utc, like Mon Feb 12 2018 20:33:08 GMT+0000 --}}
{{utc (moment '2018-01-01T00:00:00+01:00' 'YYYY-MM-DD HH:mm:ssZ')}}  {{!-- Sun Dec 31 2017 23:00:00 GMT+0000 --}}

moment-format

{{moment-format <date> [outputFormat=moment.defaultFormat [<inputFormat>]]}}
Parameters Values
<date> Any value(s) interpretable as a date/time by moment (a date String or a Moment or a Date...)
outputFormat An optional date/time String output format, defaults to moment.defaultFormat which you must explicitly define
<inputFormat> An optional date/time String input format

Formats a <date> to an optional outputFormat from an optional inputFormat. If the inputFormat is not provided, the date String is parsed on a best effort basis. If the outputFormat is not given the global moment.defaultFormat is used. Typically, outputFormat and inputFormat are given. See momentjs#format.

NOTE: for all other helpers, the input format string is the second argument.

Example

{{moment-format '12-1995-25' 'MM/DD/YYYY' 'MM-YYYY-DD'}} {{!-- 12/25/1995 --}}

moment-from / moment-from-now

{{moment-from <dateA> [<dateB>] [hideAffix=false]}}
{{moment-from-now <dateA> [hideAffix=false]}}
Parameters Values
<dateA> Any value(s) interpretable as a date/time by moment (a date String or a Moment or a Date...)
<dateB> An optional value(s) interpretable as a date/time by moment (a date String or a Moment or a Date...), defaults to now
hideAffix An optional Boolean to hide the relative prefix/suffix or not.

Returns the time between <dateA> and <dateB> relative to <dateB>. See momentjs#from.

Note that moment-from-now is just a more verbose moment-from without dateB. You don't need to use it anymore.

Examples

{{!-- in January 2018 at time of writing --}}
{{moment-from '2995-12-25'}} {{!-- in 978 years --}}
{{moment-from-now '2995-12-25'}} {{!-- in 978 years --}}
{{moment-from '1995-12-25' '2995-12-25' hideAffix=true}} {{!-- 1000 years --}}

moment-to / moment-to-now

{{moment-to <dateA> [<dateB>] [hideAffix=false]}}
{{moment-to-now <dateA> [hideAffix=false]}}
Parameters Values
<dateA> Any value(s) interpretable as a date/time by moment (a date String or a Moment or a Date...)
<dateB> An optional value(s) interpretable as a date/time by moment (a date String or a Moment or a Date...), defaults to now
hideAffix An optional Boolean to hide the relative prefix/suffix or not.

Returns the time between <dateA> and <dateB> relative to <dateA>. See momentjs#to.

Note that moment-to-now is just a more verbose moment-to without dateB. You don't need to use it anymore.

Examples

{{!-- in January 2018 at time of writing --}}
{{moment-to '2995-12-25'}} {{!-- 978 years ago --}}
{{moment-to '1995-12-25' '2995-12-25'}} {{!-- in 1000 years --}}
{{moment-to-now '1995-12-25' hideAffix=true}} {{!-- 22 years --}}

moment-duration

{{moment-duration <number> [<units>]}}
Parameters Values
<number> Any value(s) interpretable as a duration by moment (typically a Number in milliseconds)
<units> An optional String to specify the units of <number> (typically 'seconds', 'minutes', 'hours'...)

Returns a Duration automatically humanized. See momentjs#duration.

Examples

{{moment-duration 100}} {{!-- a few seconds --}}
{{moment-duration 24 'hours'}} {{!-- a day --}}

moment-calendar

{{moment-calendar <dateA> [<dateB> [<formatHash>]]}}
Parameters Values
<dateA> Any value(s) interpretable as a date/time by moment (a date String or a Moment or a Date...)
<dateB> An optional value(s) interpretable as a date/time by moment (a date String or a Moment or a Date...) used as a reference, defaults to now
<formatHash> An optional output format hash, defaults to {}

Returns the time between <dateA> and <dateB> relative to <dateB> in a way that is different from moment-from and customizable via <formatHash>. See momentjs#calendar.

Examples

{{!-- in January 2018 at time of writing --}}
{{moment-from-now '2018-01-25'}} {{!-- 2 days ago --}}
{{moment-calendar '2018-01-25'}} {{!-- Yesterday at 12:00 AM --}}

moment-diff

{{moment-diff <dateA> <dateB> [precision='milliseconds' [float=false]]}}
Parameters Values
<dateA> Any value(s) interpretable as a date/time by moment (a date String or a Moment or a Date...)
<dateB> Any value(s) interpretable as a date/time by moment (a date String or a Moment or a Date...)
precision An optional unit of measurement, defaults to 'milliseconds'
float An optional Boolean to get the floating point result, rather than the integer value

Returns the difference in precision units between <dateA> and <dateB> with floating point accuracy if float is true. See momentjs#diff.

Examples

{{moment-diff '2018-01-25' '2018-01-26'}} {{!-- 86400000 --}}
{{moment-diff '2018-01-25' '2018-01-26' precision='years' float=true}} {{!-- 0.0026881720430107525 --}}

moment-add

{{moment-add <date> <number> [precision='milliseconds']}}
Parameters Values
<date> An optional value interpretable as a date/time by moment (a date String or a Moment or a Date...). Defaults to value of moment()
<number> Any value(s) interpretable as a duration by moment that is the amount of the precision you want to add to the date provided
precision An optional unit of measurement, defaults to 'milliseconds'

Mutates the original moment by adding time. See momentjs#add.

Examples

{{!-- Add 6 days to a date --}}
{{moment-add '10-19-2019' 6 precision='days'}}

{{!-- Add 6 days to a date --}}
const duration = { days: 6 }
{{moment-add '10-19-2019' duration}}

{{!-- Print a date 6 days from now --}}
{{moment-add 6 precision='days'}}

moment-subtract

{{moment-subtract <date> <number> [precision='milliseconds']}}
Parameters Values
<date> An optional value interpretable as a date/time by moment (a date String or a Moment or a Date...). Defaults to value of moment()
<number> Any value(s) interpretable as a duration by moment that is the amount of the precision you want to subtract from the date provided
precision An optional unit of measurement, defaults to 'milliseconds'

Mutates the original moment by removing time. See momentjs#subtract.

Examples

{{!-- Remove 6 days from a date --}}
{{moment-subtract '10-19-2019' 6 precision='days'}}

{{!-- Remove 6 days from a date --}}
const duration = { days: 6 }
{{moment-subtract '10-19-2019' duration}}

{{!-- Print a date 6 days earlier --}}
{{moment-subtract 6 precision='days'}}

is-before / is-after / is-same / is-same-or-before / is-same-or-after

{{is-before <dateA> [<dateB>] [precision='milliseconds']}}
{{is-after <dateA> [<dateB>] [precision='milliseconds']}}
{{is-same <dateA> [<dateB>] [precision='milliseconds']}}
{{is-same-or-before <dateA> [<dateB>] [precision='milliseconds']}}
{{is-same-or-after <dateA> [<dateB>] [precision='milliseconds']}}
Parameters Values
<dateA> Any value(s) interpretable as a date/time by moment (a date String or a Moment or a Date...)
<dateB> An optional value(s) interpretable as a date/time by moment (a date String or a Moment or a Date...). If not given, <dateA> becomes now and <dateB> becomes <dateA>
precision An optional String unit of comparison precision, defaults to 'milliseconds'

Returns a Boolean that indicates if <dateA> is respectively before/after/the same/same or before/ same or after <dateB> to the precision level. See momentjs#queries.

Examples

{{is-before '2995-12-25'}} {{!-- false --}}
{{is-before '2018-01-25' '2018-01-26' precision='years'}} {{!-- false --}}
{{is-same-or-after '2018-01-25' '2018-01-26' precision='years'}} {{!-- true --}}

is-between

{{is-between <date> <dateA> [<dateB>] [precision='year' inclusivity='[)']}}
Parameters Values
<date> Any value(s) interpretable as a date/time by moment (a date String or a Moment or a Date...)
<dateA> A boundary value(s) interpretable as a date/time by moment (a date String or a Moment or a Date...)
<dateB> An optional boundary value(s) interpretable as a date/time by moment (a date String or a Moment or a Date...). If not given <date> is assigned now, <dateA> is assigned <date> and <dateB> is assigned <dateA>.
precision An optional String unit of comparison precision, defaults to 'milliseconds'
inclusivity An optional String indicating inclusivity of the boundaries, defaults to ()

Returns a Boolean that indicates if <date> is between <dateA> and <dateB> to the precision level and with boundary inclusions specified by inclusivity. See momentjs#is-between.

Examples

{{is-between '1995-12-25' '2995-12-25'}} {{!-- true --}}
{{is-between '1995-12-25' '1995-12-25' '2995-12-25' precision='years' inclusivity='()'}} {{!-- true --}}

now

{{now}}
{{moment-format (now) 'MM-DD-YYYY'}}

Returns the present Moment.

Examples

{{!-- date at time of writing }}
{{now}} {{!-- Sat Jan 27 2018 11:59:31 GMT-0500 --}}
{{!-- interval is a common named parameter (see the corresponding section) }}
{{now interval=1000}} {{!-- <current date and updating every 1-second (1000 milliseconds).> --}}

unix

{{unix <timestamp>}}
Parameters Values
<timestamp> An integer Number or String value representing the number of seconds since the Unix Epoch (January 1 1970 12AM UTC)

Returns a Moment corresponding to the <timestamp>.

Examples

{{unix '1516586508'}} {{!-- Sun Jan 21 2018 21:01:48 GMT-0500 --}}
{{!-- Warning: Passing a literal integer value does not work --}}
{{unix 1516586508}} {{!-- Invalid date --}}

Common optional named arguments

All helpers accept the following optional named arguments (even though they are not always applicable):

Parameters Values
locale An optional String locale, to override the default global moment.locale
timeZone An optional String time zone, defaults to moment.timeZone (the default time zone)
interval An optional interval Number of milliseconds when the helper should be recomputed
allow-empty An optional Boolean to ignore the Invalid date output when knowingly passing null, undefined, or '', defaults to false

Note that interval does not recompute the value of the helper parameters, unless it is part of a helper that is a value in which case it is useful for "live" updating as time elapses.

Warning: allow-empty is currently inconsistent and should not always be trusted.

Examples

{{now interval=1000}} {{!-- <current date and updating every 1-second (1000 milliseconds)> --}}
{{is-before (now) '2018-01-26' interval=60000}} {{!-- if this was true initially, it will always be true despite interval --}}
{{moment-format '' allow-empty=true}}  {{!-- <nothing> --}}

Configuration Options

Global Default Output Format

Your application may require a default format other than the default, ISO 8601. For example, you may want dates to fallback on the localized shorthand format L by default.

// config/environment.js
module.exports = function() {
  return {
    'ember-moment': {
      outputFormat: 'L'
    }
  }
};

If you need to change the default format during runtime, use the service API. Doing so will cause the moment-format helper instances to re-render with the new default format.

// app/controller/index.js
export default Ember.Controller.extend({
  moment: Ember.inject.service(),
  actions: {
    changeDefaultFormat() {
      this.set('moment.defaultFormat', 'MM.DD.YYYY');
    }
  }
})

Global Allow Empty Dates

If null, undefined, or an empty string are passed as a date to any of the moment helpers then you will get Invalid Date in the output. To avoid this issue globally, you can set the option allowEmpty which all of the helpers respect and will result in nothing being rendered instead of Invalid Date.

// config/environment.js
module.exports = function() {
  return {
    'ember-moment': {
      allowEmpty: true // default: false
    }
  }
};

Configure default runtime locale/timeZone

Globally set locale

// app/routes/applicaton.js
export default Ember.Route.extend({
  moment: Ember.inject.service(),
  beforeModel() {
    this.get('moment').setLocale('es');
  }
});

Globally set time zone

// app/routes/applicaton.js
export default Ember.Route.extend({
  moment: Ember.inject.service(),
  beforeModel() {
    this.get('moment').setTimeZone('America/Los_Angeles');
  }
});

Frequently Asked Questions

Invalid Date is being rendered into the DOM, how do I avoid this?

An invalid date string is being passed into momentjs and/or the input string format was omitted.

If you are knowingly passing null, undefined, or an empty string and want to ignore the output of Invalid Date then pass the option allow-empty=true to the helper (all helpers accept this property)

{{moment-format ''}}  {{!-- Invalid date --}}
{{moment-format '' allow-empty=true}}  {{!-- <nothing> --}}
`

Contributing

See the Contributing guide for details.

Docs to add

更新日志

Changelog

Release (2025-06-06)

ember-moment 10.0.2 (patch)

:bug: Bug Fix

  • ember-moment, test-app-3.x, test-app-4.x, test-app-5.x

Committers: 1

Release (2024-06-27)

ember-moment 10.0.1 (patch)

:memo: Documentation

:house: Internal

Committers: 6

10.0.0

  • [BREAKING] This addon no longer provides the moment library itself. Apps should depend directly on either moment or moment-timezone and import it via ember-auto-import. Apps should make sure to remove any dependencies on ember-cli-moment-shim. See "Using Moment in Ember Apps & Addons" in the README.
  • [BREAKING] This is a v2 addon so your app must have ember-auto-import >= 2.
  • [BREAKING] includeTimezone, includeLocales, and localeOutputPath options in config/environment.js are removed, since this addon is no longer responsible for providing moment. See "Controlling Locale and Timezone Data" in the README.

9.0.1

  • @jfdnc fix error related to not having defaultFormat configured #363

9.0.0

  • [BREAKING] drops support for Node 8 and 10
  • [BREAKING] drops support for ember-source < 3.16

    If you need to use ember-moment with ember-source older than 3.16, you can still use ember-moment@v8.x -- there is a branch on GitHub, ember-classic that is still open for bugfixes and other updates, if folks need them.

    Currently supported ember-source versions (tested in CI) are:

    • 3.16
    • 3.20
    • 3.24

    Additionally, CI is also testing against ember-release/beta/canary as well as embroider-safe and embroider-optimized builds.

  • [BREAKING] removed computed property macros

    Octane prefers vanillaJS:tm: getters over computed macros.

    For example, where you would previously have

    @duration(...) myDuration
    

    you would now want:

    get myDuration() {
      return moment.duration(...);
    }
    
  • (internal): Migrate to GitHub Actions

8.0.0

  • [BREAKING] drops Node 6 support
  • Updates ember-macro-helpers to 4.x

7.8.1

  • @puwelous Substitute merge() with assign() - Ember deprecation #296
  • @jasonmit ci: Bump Supported Node version from 4 to 6.
  • @kellyselden update ember-macro-helpers #285
  • @scottkidder Replace Logger with console #281

7.7.0

  • @fenekku deprecated hideSuffix/hidePrefix in favor of hideAffix
  • @crotwell added utc helper & macro *

7.6.0

  • @kellyselden Fix invalid reexport for helpers/unix
  • Upgrade ember-cli and dependencies

7.3.0

  • Setting locale now sets locale on global moment object
  • Added setLocale and setTimeZone. Better naming. Will continue to support changeLocale and changeTimeZone but have updated README to prefer new method names
  • Added localeChanged and timeZoneChanged events
  • @mfeltz scoped moment-subtract and moment-add to use the moment service locale property

7.2.0

  • @kellyselden add back ember-macro-helpers

7.1.1

  • Removed ember-macro-helpers

7.1.0

  • @kellyselden ported computed macro factory to use computed macro utility methods from ember-macro-helpers

7.0.3

  • Upgrade ember-cli-moment-shim to 3.0.0
  • now helper now recomputes using setTimeout instead of run.later #205

7.0.2

  • Revert upgrade ember-cli-moment-shim to 2.2.1 (moment.now issue)

7.0.1

  • Upgrade ember-cli-moment-shim to 2.2.1

7.0.0

  • Upgrade ember-cli-moment-shim to 1.3.0
  • now helper returns moment.now() instead of new Date()
  • Added moment helper
  • Added moment-calendar helper
  • @GarPit Added moment-to-date helper
  • @stavarotti added unix helper
  • @yads added moment-subtract moment-add helpers
  • Removed ember-getowner-polyfill as a direct dep
  • Add moment query helpers (is-between, is-same-or-after, is-same-or-before, is-same, is-after, is-before)
  • BREAKING: no longer defaults moment-format to LLLL and instead uses the moment default format (ISO 8601)
  • Adopted yarn

6.0.0

5.1.0

5.0.2

  • Prevent moment 2.11.0 from being installed due to it being unsupported

5.0.1

  • Reduce size and complexity of computeds

5.0.0

  • Rewrote computeds to support literals as arguments
  • Do not warn on missing date when allowEmpty

4.2.1

  • Remove ember-new-computed
  • Remove use of an Ember global
  • Remove need for instance initializer

4.2.0

  • Upgrade ember-cli-moment-shim
  • Add a defaultFormat property to the service, which moment-format helpers observer to recompute
  • BUGFIX: outputFormat typo on config/environment.js lookup led to it never being properly looked up

4.1.0

  • Adds support a timeZone argument on all helpers
  • Adds a service which contains two methods: changeLocale and changeTimeZone
    • Invoking either of these methods will cause all helpers to rerender if a locale/timezone was not specified

4.0.1

  • Removes two unused npm deps

4.0.0

  • Removes support for legacy helpers
  • Drops support for Ember < 1.13.0 (continue to use 3.x for < 1.13.0 support)

3.6.3-3.6.4

  • Ember version detection incorrectly reported

3.6.2

  • Warn on locale mismatch, silently ignore en locale since included by default in moment

3.6.1

  • Bugfix global output format

3.6.0

  • 2.0-beta + 2.0-canary supported again
  • test support for deprecated helpers
  • global allowEmpty configuration option
  • removes unused helper modules from builds (slimmer dists)

3.5.1

  • destroy interval timers on Helper destroy
  • work around issue with Ember.run.next blocking test helpers

3.5.0

  • Support for 2.0.0-beta and canary
  • Upgrades dependencies

3.4.0

  • Adds allow-empty argument to helpers to prevent Invalid Date to be rendered when passed an empty value (null, undefined, or "")
{{moment-format date allow-empty=true}}
  • Adds locale argument to helpers to locally scope locale format to specific helpers
{{moment-format date locale='es'}}
  • Adds a global output format string option to config/environment
module.exports = function() {
  return {
    moment: {
      outputFormat: 'L' // overrides the `LLLL` that moment defaults to
    }
  }
};

3.3.0

  • Adds toNow computed property macro
  • Adds moment-to-now htmlbar helper
  • Fixes documentation error around computed property macro argument order
  • Adds the ability to hide the prefix/suffix from toNow/fromNow helpers and computed property macro output

3.2.1

  • Removes deprecation warnings from Ember 1.13.6

3.2.0

  • Deprecate helpers: moment, ago, duration in favor of moment-format, moment-from-now, moment-duration
  • Deprecate computed property modules:
    • ember-moment/computeds/ago -> ember-moment/computeds/from-now
    • ember-moment/computeds/moment -> ember-moment/computeds/format
  • Removed EnumerableUtils.map
  • Updated ember-cli-moment-shim to 0.6.0

3.1.0

  • Conditionally include all locales if true is passed to includeLocales option

3.0.2

  • Smoke tests added
  • Fixing regression which broke 1.10.0
  • Added Ember 1.10.0 -> #release to the Travis CI matrix

3.0.1

  • Fixes regression in <= 1.12.0 where the helpers are not registered properly

3.0.0

  • Support to programmatically including moment i18n locale data via includeLocales
  • Removes support for Ember.Handlebars.helpers in favor of just supporting HTMLBars going forward
  • Removes ember-moment/computed. Explicit full path import paths to avoid naming conflicts.
    • ember-moment/computeds/duration
    • ember-moment/computeds/moment
    • ember-moment/computeds/from-now

2.0.1

2.0.0

  • 1.13.x support
  • moment and moment timezone are now pulled in from ember-cli-moment-shim instead of ember-moment
  • BREAKING: moved EmberApp's ember-moment configuration object to config/environment.js and renamed to moment.
// config/environment.js
module.exports = function(environment) {
  return {
    moment: {
      includeTimezone: 'all'
    }
  }
}

1.1.1

  • [BUGFIX] HTMLBars should use makeBoundHelper

1.1.0

  • [ENHANCEMENT] HTMLBars support (backwards compat. with Handlebars)

  • [ENHANCEMENT] Adding duration helper with examples in the dummy app

1.0.0

  • [BREAKING ENHANCEMENT] The full moment Handlebars helper signature is now

    `{{moment-format date outputFormat inputFormat}}`
    

    to better reflect common usage pattern. You are usually passing a date as the first argument, which does not require specifying an inputFormat, and at the same time, you usually do want to specify an output format. #12.

    Fixes case of passing both input and output formats, and changes default output format.

    Adds a few more usage examples to dummy app, and improves tests accordingly.

  • [BUGFIX] Passing a two arguments to the moment helper was not handled properly.

  • [ENHANCEMENT] Added more examples to the dummy app

0.2.0

Early versions, before this doc was maintained