code_dude
code_dude

Reputation: 1111

How can I define Date in my defined mongoose Schema such as to return a nicely formated date and time?

So I want to create a task/todo model for my app and for every task I want to have a nice looking date and time of creation in the footer. I have already achieved this successfuly on a similar client side only app,:

function getCurrentDateTime () {
    const date = new Date();

    let day = date.getDate().toString().length <= 1 ? '0' + date.getDate() : date.getDate();

    let month = date.getMonth().toString().length <= 1 ? `0${parseInt(date.getMonth() + 1)}` : date.getMonth();

    let year = date.getFullYear().toString().length <= 1 ? '0' + date.getFullYear() : date.getFullYear();
    let hours = date.getHours().toString().length <= 1 ? '0' + date.getHours() : date.getHours();
    let minutes = date.getMinutes().toString().length <= 1 ? '0' + date.getMinutes() : date.getMinutes();
    let seconds = date.getSeconds().toString().length <= 1 ? '0' + date.getSeconds() : date.getSeconds();

    return { day, month, year, hours, minutes, seconds };
}

function createTask (statePlaceholder, currentTaskText) {
    let newTask = {
        id: uuid(),
        text: currentTaskText,
        completed: false,
        creationDateTime: {
            date: `${getCurrentDateTime().day}/${getCurrentDateTime().month}/${getCurrentDateTime().year}`,
            time: `${getCurrentDateTime().hours}:${getCurrentDateTime().minutes}:${getCurrentDateTime().seconds}`
        }
    };

    ...
}

and it looks like this:

enter image description here

I want to save all the tasks elements(text, completed or not and date/time of creation) on MongoDB, and I don't know how to define the date and time so that I get what you see in the image, but comming from MongoDB.

const TaskSchema = new mongoose.Schema({
    text: { type: String, required: true },
    completed: Boolean,
    creationDateTime: {
        date: // day/month/year,
        time: // timestamp
    }
});

How can I properly define the date and time on the mongoose schema defined by me?

Upvotes: 1

Views: 213

Answers (1)

mickl
mickl

Reputation: 49945

What you're trying to store as creationDateTime should definitely be of type Date and you should not store it as string or object. It will make any future querying easier and will let you avoid some unexpected issues which may happen if you stored this value as string. You can take advantage of mongoose's default feature which will run Date.now any time you store a new document so your schema can look like this:

const TaskSchema = new mongoose.Schema({
    text: { type: String, required: true },
    completed: Boolean,
    creationDateTime: {
        type: Date,
        default: Date.now
    }
});

When it comes to formatting, mongoose offers a nice capability of defining virtual properties. Such field will not be stored in a database but will by dynamically evaluated and this is where you can reuse your formatting logic:

function dateTimeToParts(date) {
    let day = date.getDate().toString().length <= 1 ? '0' + date.getDate() : date.getDate();
    let month = date.getMonth().toString().length <= 1 ? `0${parseInt(date.getMonth() + 1)}`: date.getMonth();
    let year = date.getFullYear().toString().length <= 1 ? '0' + date.getFullYear() : date.getFullYear();
    let hours = date.getHours().toString().length <= 1 ? '0' + date.getHours() : date.getHours();
    let minutes = date.getMinutes().toString().length <= 1 ? '0' + date.getMinutes() : date.getMinutes();
    let seconds = date.getSeconds().toString().length <= 1 ? '0' + date.getSeconds() : date.getSeconds();
    return { day, month, year, hours, minutes, seconds };
}

TaskSchema.virtual('createdOn').get(function() {
    let { day, month, year, hours, minutes, seconds } = dateTimeToParts(
        this.creationDateTime
    );
    return {
        date: `${day}/${month}/${year}`,
        time: `${hours}:${minutes}:${seconds}`
    };
});

So having below document in your MongoDB database:

{ 
    "_id" : ObjectId("5e2e7c93397e8124b81dfcaa"), 
    "creationDateTime" : ISODate("2020-01-27T06:00:51.409Z"), 
    "text" : "abc", 
    "__v" : 0 
}

You can run following code:

let task = await Task.findOne({ _id: ObjectId("5e2e7c93397e8124b81dfcaa") });
console.log(task.createdOn);

To get following output:

{ date: '26/01/2020', time: '22:00:51' }

Upvotes: 1

Related Questions