今天延續昨天的主題,繼續講解日期時間相關操作符,但主要會專注在時區、時間資料格式的轉換部分。
昨天我們有講到$hour
這類的操作符,可以幫助我們取得特定的單位日期、時間是多少,其實他們還有第二種用法,透過帶入時區的設定,這時候就會針對不同的時區,轉換時間。
例如:現在標準時間是2022-09-16T02:00:00.000Z,如果我們想要轉換時區顯示時間,寫法是在date
後面寫入要轉換的時間資料,在timezone
寫入時區。
db.collection.aggregate([
{ $addFields: { date: new Date("2022-09-16T02:00:00.000Z") } },
{
$project: {
new_date_1: {
hour: { $hour: { date: "$date", timezone: "+0830" } },
min: { $minute: { date: "$date", timezone: "+0830" } }
},
new_date_2: {
hour: { $hour: { date: "$date", timezone: "Africa/Addis_Ababa" } },
min: { $minute: { date: "$date", timezone: "Africa/Addis_Ababa" } }
}
}
}
]);
// 最後回傳的結果
{
_id: 1,
new_date_1: { hour: 10, min: 30 },
new_date_2: { hour: 5, min: 0 }
}
時區的部分也有兩種寫法,第一種比如說要轉換時區到+08:30(比標準時間多8個半小時),那就直接帶入+08:30,這個方法個人覺得是最簡單的。
第二種方法是,改用地區的名稱帶入時區,MongoDB時區名稱主要參考這裡,可以找到目前所在地區的時區,並且填入。
例如:上面的範例填入的時區是"Africa/Addis_Ababa",這地方屬於+05:00,所以在做時間的轉換,才會從00:00轉成05:00。
接下來要介紹的$toDate
和$dateFromString
,這些操作符都可以將其他格式的資料型態,轉換成日期時間格式。
差別在於$toDate
可以接受任何型態的資料,不過轉變的格式,必須按照MongoDB的規定,而$dateFromString
限定只能從文字轉換成日期時間格式,但可以自行定義轉換的格式。
例如:我們現在有不同的資料,想要都轉換成date
const { ObjectId } = require("mongodb");
db.collection.aggregate([
{
$addFields: {
number: 1663293600000, // Timestamp資料型態
string: "2022-09-16",
string_timezone: "2022-09-16 05:00:00 +0500", // 有包含時區的寫法
objectId: ObjectId() // 建立ObjectId
}
},
{
$project: {
number: { $toDate: "$number" },
string: { $toDate: "$string" },
string_timezone: { $toDate: "$string_timezone" },
objectId: { $toDate: "$objectId" } // 也可以轉換objectId
}
}
]);
// 最後回傳的資料
{
_id: 1,
number: 2022-09-16T02:00:00.000Z,
string: 2022-09-16T00:00:00.000Z,
string_timezone: 2022-09-16T00:00:00.000Z,
objectId: 2022-09-20T13:35:13.000Z
}
這裡比較特別的是,objectId其實也可以轉換成時間,因為它本身有一段區塊是紀錄,建立objectId當下時間的timestamp。
另外一個$dateFromString
的語法使用的範例如下,其中比較特別的是,可以透過timezone來設定時區,例如:我設定時區是+08:00,而時間是2018-06-15",那轉換成標準時間,就會扣掉8小時,變成2018-06-14T16:00:00.000Z。
db.collection.aggregate([
{
$addFields: {
date: "06-15-2018" // 可以自己定義時間怎麼撰寫的順序
}
},
{
$project: {
date: {
$dateFromString: {
dateString: "$date", // 代入要轉換的文字
format: "%m-%d-%Y" // 寫入轉換規則
}
},
date_timezone: {
$dateFromString: {
dateString: "$date",
format: "%m-%d-%Y",
timezone: "+08:00" // 寫入時區
}
}
}
}
]);
// 最後回傳的資料
{
_id: 1,
date: 2018-06-15T00:00:00.000Z,
date_timezone: 2018-06-14T16:00:00.000Z
}
轉換的規則,會用%Y
代表年份、%m
代表月份、%d
代表日期,更詳細的轉換規則,請參考官方文件。
最後一個要介紹的操作符是$dateFromParts
,它可以藉由帶入各種參數,讓使用者自己建立一個時間資料,使用方法也很簡單,相信大家看範例也看得懂。
db.collection.aggregate([
{
$project: {
date: {
$dateFromParts: {
"year": 2022,
"month": 9,
"day": 20,
"hour": 22,
"minute": 12,
"second": 24,
"millisecond": 342,
"timezone": "+08:00"
}
}
}
}
]);
// 最後回傳的資料
{ _id: 1, date: 2022-09-20T14:12:24.342Z }
本篇文章同步放在我的部落格,大家有空可以進來逛逛