Format date within $project in aggregate function nodejs

Viewed 437

I am looking to format a date within aggregate $project pipeline in 12 hour format.

 $project: {
                  
                    UpdateDt:
                    { 
                     $dateToString: { format: "%m/%d/%Y ,%H:%M:%S", date: "$UpdateDt", timezone: "GMT" } 
                    },                  
            }
                

I tried using above code but this does not seem to work,also I want the date format as : 8/31/2017, 10:30:00 AM GMT With the code above ,I get the output as 09/14/2017,15:07:10 the requirement is for the date to be in 12 hour format with GMT appended,same as achieved with .toLocaleString() function.

Please suggest any way/workaround for same.

3 Answers

Demo - https://mongoplayground.net/p/fIlimwXuOWK

In 1st pipeline - $addFields add a new field UpdateNewDt with {date, hour, time} details in GMT.

2nd pipeline - $set UpdateNewDt.hour convert to 12 hour clock and add AM and PM eg:- 12 - 12 PM, 02- 02 AM, 23- 11 PM

3rd pipeline - $set combine data back to a string

4th pipeline - $project - UpdateDt

db.collection.aggregate([
  {
    "$addFields": {
      UpdateNewDt: {
        date: { $dateToString: { format: "%m/%d/%Y ,", date: "$UpdateDt", timezone: "GMT" }},
        hour: { $dateToString: { format: "%H", date: "$UpdateDt", timezone: "GMT" }},
        time: { $dateToString: { format: ":%M:%S", date: "$UpdateDt", timezone: "GMT" }}
      }
    }
  },
  {
    $set: {
      "UpdateNewDt.hour": {
        $cond: {
          "if": { $gt: [ { "$toInt": "$UpdateNewDt.hour" }, 11 ] },
          "then": {
            "$concat": [
                {
                    $cond: [
                        { $eq: [{  "$toInt": "$UpdateNewDt.hour"},12 ] },
                        "12",
                        { $toString: {"$subtract": [ { "$toInt": "$UpdateNewDt.hour"  }, 12 ] }}
                    ] 
                },
                " PM" ] 
            },
          "else": { "$concat": [ "$UpdateNewDt.hour", " AM" ] }
        }
      }
    }
  },
  {
    $set: {
      "UpdateNewDt": {
        "$concat": [
          "$UpdateNewDt.date",
          { "$arrayElemAt": [{ "$split": [ "$UpdateNewDt.hour", " " ] }, 0 ] },
          "$UpdateNewDt.time",
          " ",
          { "$arrayElemAt": [{ "$split": [ "$UpdateNewDt.hour", " " ] }, 1 ] }
        ]
      }
    }
  },
   {
    $project: { UpdateDt: "$UpdateNewDt" }
  }
])

Input -

[
  {
    "key": 1,
    UpdateDt: ISODate("2021-04-06T02:07:47.231Z")
  },
  {
    "key": 2,
    UpdateDt: ISODate("2021-04-06T22:07:47.231Z")
  },
  {
    "key": 3,
    UpdateDt: ISODate("2021-04-06T12:07:47.231Z")
  }
]

Output -

[
  {
    "UpdateDt": "04/06/2021 ,02:07:47 AM",
    "_id": ObjectId("5a934e000102030405000000")
  },
  {
    "UpdateDt": "04/06/2021 ,10:07:47 PM",
    "_id": ObjectId("5a934e000102030405000001")
  },
  {
    "UpdateDt": "04/06/2021 ,12:07:47 PM",
    "_id": ObjectId("5a934e000102030405000002")
  }
]

I think that is not supported.

Here is the official Docs for $dateToString: https://docs.mongodb.com/manual/reference/operator/aggregation/dateToString/

For the specified available formats, there is only 24-hour clock.

If it isn't necessary for you to format that in the aggregate step, I would suggest you date-fns package. You can import only the format function and you can format the Date in format that you need.

Here is the package: https://www.npmjs.com/package/date-fns

Here is the Docs: https://date-fns.org/v2.19.0/docs/format

Hi As I understood your concern you can use below script

Collection "users": [ { "_id": 3, "ts": ISODate("2016-06-18T18:30:00.288Z") } ]

Query

db.users.aggregate([
  {
    $project: {
      "date": {
        "$dateToString": {
          "format": "%m/%d/%Y ,%H:%M:%S",
          "date": "$ts",
          "timezone": "GMT"
        }
      }
    }
  }
])

Output

[
  {
    "_id": 3,
    "date": "06/18/2016 ,18:30:00"
  }
]
Related