使用日期

以下是如何使用 Mongoose 模式声明类型为 Date 的路径

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
  name: String,
  // `lastActiveAt` is a date
  lastActiveAt: Date
});
const User = mongoose.model('User', userSchema);

当你创建用户 文档 时,Mongoose 会使用 原生 JavaScript 日期Date() 构造函数 将值转换为日期。

const user = new User({
  name: 'Jean-Luc Picard',
  lastActiveAt: '2002-12-09'
});
user.lastActiveAt instanceof Date; // true

无效的日期将在你 验证文档 时导致 CastError 错误。

const user = new User({
  name: 'Jean-Luc Picard',
  lastActiveAt: 'not a date'
});
user.lastActiveAt instanceof Date; // false
user.validateSync().errors['lastActiveAt']; // CastError

验证器

日期有两个内置验证器:minmax。如果给定的日期严格小于 min 或严格大于 max,这些验证器将报告 ValidatorError 错误。

const episodeSchema = new mongoose.Schema({
  title: String,
  airedAt: {
    type: Date,
    // The dates of the first and last episodes of
    // Star Trek: The Next Generation
    min: '1987-09-28',
    max: '1994-05-23'
  }
});
const Episode = mongoose.model('Episode', episodeSchema);

const ok = new Episode({
  title: 'Encounter at Farpoint',
  airedAt: '1987-09-28'
});
ok.validateSync(); // No error

const bad = new Episode({
  title: 'What You Leave Behind',
  airedAt: '1999-06-02'
});
bad.airedAt; // "1999-06-02T00:00:00.000Z"

// Path `airedAt` (Tue Jun 01 1999 20:00:00 GMT-0400 (EDT)) is after
// maximum allowed value (Sun May 22 1994 20:00:00 GMT-0400 (EDT)).
bad.validateSync();

查询

MongoDB 支持按日期范围查询和按日期排序。以下是按日期、日期范围查询和按日期排序的一些示例

// Find episodes that aired on this exact date
return Episode.find({ airedAt: new Date('1987-10-26') }).
  then(episodes => {
    episodes[0].title; // "Where No One Has Gone Before"
    // Find episodes within a range of dates, sorted by date ascending
    return Episode.
      find({ airedAt: { $gte: '1987-10-19', $lte: '1987-10-26' } }).
      sort({ airedAt: 1 });
  }).
  then(episodes => {
    episodes[0].title; // "The Last Outpost"
    episodes[1].title; // "Where No One Has Gone Before"
  });

转换边缘情况

日期转换在几个小案例中与 JavaScript 的原生日期解析有所不同。首先,Mongoose 会在给定对象上查找 valueOf() 函数,并在转换日期之前调用 valueOf()。这意味着 Mongoose 可以自动将 moment 对象 转换为日期。

const moment = require('moment');
const user = new User({
  name: 'Jean-Luc Picard',
  lastActiveAt: moment.utc('2002-12-09')
});
user.lastActiveAt; // "2002-12-09T00:00:00.000Z"

默认情况下,如果你将数字字符串传递给 Date 构造函数,JavaScript 将尝试将其转换为年份。

new Date(1552261496289); // "2019-03-10T23:44:56.289Z"
new Date('1552261496289'); // "Invalid Date"
new Date('2010'); // 2010-01-01T00:00:00.000Z

Mongoose 会将包含超出 JavaScript 可表示日期范围 的数字的数字字符串转换为数字,然后再将其传递给日期构造函数。

[require: Date Tutorial.*Example 1.4.3]

时区

MongoDB 将日期存储为 64 位整数,这意味着 Mongoose 默认情况下不存储时区信息。当你调用 Date#toString() 时,JavaScript 运行时将使用 你的操作系统的时区.