从MongoDB中的日期获取一天的8种方法

发布于

从日期中提取日期时,我们使用的确切选项将取决于我们希望如何表示日期。

例如,我们想要星期几、月中的某一天还是一年中的某一天?或者也许我们想要ISO 8601格式?返回值通常会有所不同,具体取决于我们选择哪一个。

本文探讨了这些选项,因此提出了 8 种从 MongoDB 中的日期返回日期部分的方法。

示例数据

假设我们有一个包含以下文档的集合:cats

{ “_id” : 1, “name” : “Scratch”, “born” : ISODate(“2021-01-03T23:30:15.123Z”) } { “_id” : 2, “name” : “Meow”, “born” : ISODate(“2019-12-08T04:00:12Z”) } { “_id” : 3, “name” : “Fluffy”, “born” : ISODate(“2020-09-24T10:30:00Z”) }

以下示例演示了从这些文档的字段返回日部分的各种选项。born

运营商$dayOfWeek

顾名思义,运算符从日期返回星期几。[$dayOfWeek](https://database.guide/mongodb-dayofweek/ "MongoDB $dayOfWeek")

我们可以运行以下代码从上述文档中的字段中返回星期几。born

db.cats.aggregate(
  [
    {
      $project:
        {
          _id: 0,
          birthDayOfWeek: { $dayOfWeek: "$born" }
        }
    }
  ]
)

结果:

{ “birthDayOfWeek” : 1 } { “birthDayOfWeek” : 1 } { “birthDayOfWeek” : 5 }

使用运算符时也可以指定时区。$dayOfWeek

请参阅 MongoDB $dayOfWeek 了解更多信息和示例。

运营商$dayOfMonth

运算符从日期返回月份中的某天。$dayOfMonth

例:

db.cats.aggregate(
  [
    {
      $project:
        {
          _id: 0,
          birthDayOfMonth: { $dayOfMonth: "$born" }
        }
    }
  ]
)

结果:

{ “birthDayOfMonth” : 3 } { “birthDayOfMonth” : 8 } { “birthDayOfMonth” : 24 }

您还可以在使用运算符时指定时区。$dayOfMonth

请参阅 MongoDB $dayOfMonth 了解更多信息和示例。

运营商$dayOfYear

是的,你猜对了。运算符从日期返回一年中的某一天。$dayOfYear

例:

db.cats.aggregate(
  [
    {
      $project:
        {
          _id: 0,
          birthDayOfYear: { $dayOfYear: "$born" }
        }
    }
  ]
)

结果:

{ “birthDayOfYear” : 3 } { “birthDayOfYear” : 342 } { “birthDayOfYear” : 268 }

运算符还接受时区参数。$dayOfYear

请参阅 MongoDB $dayOfYear 了解更多信息和示例。

运营商$dateToString

运算符根据用户指定的格式将日期对象转换为字符串。因此,用户可以指定在需要时仅返回日期部分。[$dateToString](https://database.guide/mongodb-datetostring/ "MongoDB $dateToString")

每个日期部分都有格式说明符,当涉及到日期部分时,您可以选择格式说明符,具体取决于您是要以 ISO 8601 格式返回星期几、月中的某天、一年中的某一天还是星期几。

例:

db.cats.aggregate(
   [
     {
       $project: {
         _id: 0,
          birthDayOfWeek: { $dateToString: { format: "%w", date: "$born" } },
          birthDayOfMonth: { $dateToString: { format: "%d", date: "$born" } },
          birthDayOfYear: { $dateToString: { format: "%j", date: "$born" } },
          birthDayOfWeekISO: { $dateToString: { format: "%u", date: "$born" } }
       }
     }
   ]
).pretty()

结果:

{ “birthDayOfWeek” : “1”, “birthDayOfMonth” : “03”, “birthDayOfYear” : “003”, “birthDayOfWeekISO” : “7” } { “birthDayOfWeek” : “1”, “birthDayOfMonth” : “08”, “birthDayOfYear” : “342”, “birthDayOfWeekISO” : “7” } { “birthDayOfWeek” : “5”, “birthDayOfMonth” : “24”, “birthDayOfYear” : “268”, “birthDayOfWeekISO” : “4” }

我们本可以提供更多的格式说明符来在结果中包含其他日期部分,但由于我们只对本文中提取日期感兴趣,因此我们仅使用格式说明符来返回日期部分。

请参阅 MongoDB $dateToString 了解更多信息和示例。

另请参阅 MongoDB $dateToString格式说明符,了解可用于 的格式说明符列表。$dateToString

运营商$dateToParts

运算符返回一个文档,其中包含给定 BSON Date 值的组成部分作为单个属性。返回的属性为 、、、、 和 。[$dateToParts](https://database.guide/mongodb-datetoparts/ "MongoDB $dateToParts")``year``month``day``hour``minute``second``millisecond

因此,我们可以在一个流水线阶段中使用,然后根据需要添加另一个流水线阶段来提取零件。$dateToParts``day

以下是我们三个文档的回报:$dateToParts

db.cats.aggregate(
  [
    {
      $project:
        {
          _id: 0,
          dateParts: { $dateToParts: { date: "$born" } }
        }
    }
  ]
).pretty()

结果:

{ “dateParts” : { “year” : 2021, “month” : 1, “day” : 3, “hour” : 23, “minute” : 30, “second” : 15, “millisecond” : 123 } } { “dateParts” : { “year” : 2019, “month” : 12, “day” : 8, “hour” : 4, “minute” : 0, “second” : 12, “millisecond” : 0 } } { “dateParts” : { “year” : 2020, “month” : 9, “day” : 24, “hour” : 10, “minute” : 30, “second” : 0, “millisecond” : 0 } }

可以将此数据传递到管道中的下一阶段,以仅提取字段。day

如果我们只为字段添加另一个投影,会发生什么情况:day

db.cats.aggregate(
  [
    {
      $project:
        {
          _id: 0,
          dateParts: { $dateToParts: { date: "$born" } }
        }
    },
    {
      $project:
        {
          birthDay: "$dateParts.day"
        }
    }
  ]
)

结果:

{ “birthDay” : 3 } { “birthDay” : 8 } { “birthDay” : 24 }

这显然不如使用前面的选项简洁。但是,根据你在管道中执行的操作,此方法可能是一种选择。

还值得一提的是,它接受一个参数,该参数修改输出文档以使用 ISO 周日期字段。$dateToParts``iso8601

请参阅 MongoDB $dateToParts 了解更多信息和示例。

方法forEach()

您可以使用 循环访问游标,使用 JavaScript 方法仅返回 day 值。[cursor.forEach()](https://database.guide/mongodb-foreach/ "MongoDB forEach()")

db.cats.find().forEach(
  function(c) {
    print(
      c.born.getDay()
      );
  }
);

结果:

1 0 4

在这种情况下,我们使用 JavaScript 方法,该方法返回一个介于 0 和 6 之间的整数,对应于给定日期的星期几,根据当地时间。getDay()

另一种选择是使用该方法,该方法使用通用时间。我们将在下一个示例中使用此方法。getUTCDay()

或者,我们可以使用 JavaScript 方法,该方法返回一个介于 1 和 31 之间的整数,表示给定日期的月份日期。getDate()

此外,此选项仅返回实际的日期值,而不是整个文档,如前面的示例所示。

方法map()

该方法将函数应用于游标访问的每个文档,并将值合并到一个数组中。[cursor.map()](https://database.guide/mongodb-map/ "MongoDB map()")

例:

db.cats.find().map(
  function(c) {
    c = c.born.getUTCDay();
    return c;
  }
);

结果:

[ 0, 0, 4 ]

如前所述,JavaScript 方法使用通用时间返回其结果。在这种情况下,它导致为第一个文档返回不同的值(我们在本例中得到,与在前一个示例中得到)。getUTCDay()``0``1

运营商$isoDayOfWeek

如果需要以 ISO 8601 格式返回星期几,可以使用 .ISO 8601 年从第 1 周的星期一开始,到最后一周的星期日结束。$isoDayOfWeek

例:

db.cats.aggregate(
  [
    {
      $project:
        {
          _id: 0,
          birthIsoDayOfWeek: { $isoDayOfWeek: "$born" }
        }
    }
  ]
)

结果:

{ “birthIsoDayOfWeek” : 7 } { “birthIsoDayOfWeek” : 7 } { “birthIsoDayOfWeek” : 4 }

在这种情况下,由于ISO 8601计算日期的方式,我们得到的结果与使用运算符时的结果完全不同。$dayOfWeek

下面是演示此差异的示例:

db.cats.aggregate(
  [
    {
      $project:
        {
          _id: 0,
          birthDayOfWeek: { $dayOfWeek: "$born" },
          birthIsoDayOfWeek: { $isoDayOfWeek: "$born" }
        }
    }
  ]
)

结果:

{ “birthDayOfWeek” : 1, “birthIsoDayOfWeek” : 7 } { “birthDayOfWeek” : 1, “birthIsoDayOfWeek” : 7 } { “birthDayOfWeek” : 5, “birthIsoDayOfWeek” : 4 }