タグ : Moment.js

MongoDB shell で moment.js, moment-timezone を使う方法

MongoDB shell で moment.js, moment-timezone を load() して使う方法をご紹介します。

MongoDB

続きを読む

異なるバージョンの Moment.js と Moment Timezone で変数を使い回したら見事にバグった

最新バージョンの moment-timezone@0.5.5 で生成した moment object を、古いバージョンの moment@2.4.0 を使ってる method に引数で渡して、日付処理をおこなったら華麗にバグったというお話です。

前提

どちらも Thu Dec 01 2016 09:00:00 GMT+0900 (JST) の値が保存されていることを期待してます。

調査結果

古いバージョンの moment@2.4.0 で作成した変数を console.log した結果

期待通り _d: Thu Dec 01 2016 09:00:00 GMT+0900 (JST) が入っていることが確認できました。

  { [Number: 1480579200000]
  _i: [ 2016, 11, 1 ],
  _f: undefined,
  _l: undefined,
  _strict: undefined,
  _isUTC: true,
  _pf: 
   { empty: false,
     unusedTokens: [],
     unusedInput: [],
     overflow: -1,
     charsLeftOver: 0,
     nullInput: false,
     invalidMonth: null,
     invalidFormat: false,
     userInvalidated: false,
     iso: false },
  _a: [ 2016, 11, 1, 0, 0, 0, 0 ],
  _d: Thu Dec 01 2016 09:00:00 GMT+0900 (JST),
  _z: 
   { name: 'america_los_angeles',
     displayName: 'America/Los_Angeles',
     zones: [ [Object], [Object], [Object], [Object] ] },
  _offset: 480 }

最新バージョンの moment-timezone@0.5.5 で作成した変数を console.log した結果

_d: Fri Nov 25 2016 00:00:00 GMT+0900 (JST) には、期待している 2016/12/01 の値が入ってませんでした。

代わりに _i 以下に存在する _d: Thu Dec 01 2016 09:00:00 GMT+0900 (JST) の方に期待している 2016/12/01 の値が入ってました。

{ [Number: 1479999600000]
  _isAMomentObject: true,
  _i: 
   { [Number: 1480579200000]
     _i: [ 2016, 11, 1 ],
     _f: undefined,
     _l: undefined,
     _strict: undefined,
     _isUTC: true,
     _pf: 
      { empty: false,
        unusedTokens: [],
        unusedInput: [],
        overflow: -1,
        charsLeftOver: 0,
        nullInput: false,
        invalidMonth: null,
        invalidFormat: false,
        userInvalidated: false,
        iso: false },
     _a: [ 2016, 11, 1, 0, 0, 0, 0 ],
     _d: Thu Dec 01 2016 09:00:00 GMT+0900 (JST),
     _z: 
      { name: 'america_los_angeles',
        displayName: 'America/Los_Angeles',
        zones: [Object] },
     _offset: 480 },
  _isUTC: false,
  _pf: 
   { empty: false,
     unusedTokens: [],
     unusedInput: [],
     overflow: -1,
     charsLeftOver: 0,
     nullInput: false,
     invalidMonth: null,
     invalidFormat: false,
     userInvalidated: false,
     iso: false,
     parsedDateParts: [],
     meridiem: null },
  _locale: 
   Locale {
     _calendar: 
      { sameDay: '[Today at] LT',
        nextDay: '[Tomorrow at] LT',
        nextWeek: 'dddd [at] LT',
        lastDay: '[Yesterday at] LT',
        lastWeek: '[Last] dddd [at] LT',
        sameElse: 'L' },
     _longDateFormat: 
      { LTS: 'h:mm:ss A',
        LT: 'h:mm A',
        L: 'MM/DD/YYYY',
        LL: 'MMMM D, YYYY',
        LLL: 'MMMM D, YYYY h:mm A',
        LLLL: 'dddd, MMMM D, YYYY h:mm A' },
     _invalidDate: 'Invalid date',
     ordinal: [Function],
     _ordinalParse: /\d{1,2}(th|st|nd|rd)/,
     _relativeTime: 
      { future: 'in %s',
        past: '%s ago',
        s: 'a few seconds',
        m: 'a minute',
        mm: '%d minutes',
        h: 'an hour',
        hh: '%d hours',
        d: 'a day',
        dd: '%d days',
        M: 'a month',
        MM: '%d months',
        y: 'a year',
        yy: '%d years' },
     _months: 
      [ 'January',
        'February',
        'March',
        'April',
        'May',
        'June',
        'July',
        'August',
        'September',
        'October',
        'November',
        'December' ],
     _monthsShort: 
      [ 'Jan',
        'Feb',
        'Mar',
        'Apr',
        'May',
        'Jun',
        'Jul',
        'Aug',
        'Sep',
        'Oct',
        'Nov',
        'Dec' ],
     _week: { dow: 0, doy: 6 },
     _weekdays: 
      [ 'Sunday',
        'Monday',
        'Tuesday',
        'Wednesday',
        'Thursday',
        'Friday',
        'Saturday' ],
     _weekdaysMin: [ 'Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa' ],
     _weekdaysShort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ],
     _meridiemParse: /[ap]\.?m?\.?/i,
     _abbr: 'en',
     _config: 
      { calendar: [Object],
        longDateFormat: [Object],
        invalidDate: 'Invalid date',
        ordinal: [Function],
        ordinalParse: /\d{1,2}(th|st|nd|rd)/,
        relativeTime: [Object],
        months: [Object],
        monthsShort: [Object],
        week: [Object],
        weekdays: [Object],
        weekdaysMin: [Object],
        weekdaysShort: [Object],
        meridiemParse: /[ap]\.?m?\.?/i,
        abbr: 'en' },
     _ordinalParseLenient: /\d{1,2}(th|st|nd|rd)|\d{1,2}/ },
  _a: [ 2016, 10, 25, 0, 0, 0, 0 ],
  _d: Fri Nov 25 2016 00:00:00 GMT+0900 (JST),
  _z: null,
  _isValid: true }

まとめ

同じ _d というプロパティの扱いが異なっているのでバグったみたいでした。

ライブラリのバージョンの混在は本当に危険なので、絶対に真似しないでくださいね。

[Moment Timezone] moment.tz の使い方

Moment Timezone の moment.tz メソッドの使い方を紹介します。

moment.tz には 2 つのインターフェースが用意されていて公式ドキュメントに明記されているので、それを元に説明していきます。

There are two interfaces for using timezones with Moment.js.

moment.tz(…, String) is used to create a moment with a timezone, and moment().tz(String) is used to change the timezone on an existing moment.

直訳すると下記のような感じでしょうか。

Moment.js で timezone を使うために、

  • moment.tz(…, String) は moment instance を timezone 付きで作成する
  • moment().tz(String) は既存の moment instance の timezone を変換する

という 2 つインターフェースが用意されています。

moment.tz(…, String) の使用例

var a = moment.tz('2015-01-01 00:00:00', "America/Los_Angeles");
a.format();
// '2015-01-01T00:00:00-08:00'
 
a.utc().format();
// '2015-01-01T08:00:00+00:00'

moment().tz(String) の使用例

var b = moment.utc('2015-01-01 00:00:00').tz("America/Los_Angeles");
b.format();
// '2014-12-31T16:00:00-08:00'
 
b.utc().format();
// '2015-01-01T00:00:00+00:00'

よく理解して使わないと期待していたのと違う挙動になっているかもしれないので、よく理解して moment.tz を使うようにしましょう。

[JavaScript] moment.js で日付型 Date のタイムゾーンを JST に変更する

JavaScript で日付扱うライブラリ moment.js で日付型 Date のタイムゾーンを JST に変更するスニペットをメモ。

var current_date = new Date();
var timezone = "Asia/Tokyo";
var current_date_jst = moment(current_date).tz(timezone).format('YYYY/MM/DD HH:mm:ss');

参考情報

Timezone Offset – Moment.js | Documentation