Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

moment.utc drops time part when used default #11233

Closed
ErikaA4 opened this issue Jan 17, 2022 · 6 comments · Fixed by #11245
Closed

moment.utc drops time part when used default #11233

ErikaA4 opened this issue Jan 17, 2022 · 6 comments · Fixed by #11245
Labels
docs This issue is due to a mistake or omission in the mongoosejs.com documentation

Comments

@ErikaA4
Copy link

ErikaA4 commented Jan 17, 2022

Describe the bug
When we create a date field and default it to moment.utc, when it gets populated the date part of the timestamp is correct, but the time part gets lost and defaulted to midnight.

To Reproduce
Steps to reproduce the behavior:
Run the attached script.

const mongoose = require('mongoose');
const moment = require('moment');

main().catch(err => console.log(err)).then();

async function main() {
  await mongoose.connect('mongodb://localhost:27017/test');

  const kittySchema = new mongoose.Schema({
    birthday: {default: moment.utc, type: Date}
  });

  const Kitten = mongoose.model('Kitten', kittySchema);

  const cat = new Kitten({});
  console.log(cat);
 }

Expected behavior
Timestamp to be set to now with hour, minute and second correctly displayed (not zero).
Got this:

Erikas-Macbook:BUG erikaarnocki$ ts-node bug.ts
{
  _id: new ObjectId("61e5471c712520a0f39ebbef"),
  birthday: 2022-01-17T00:00:00.000Z
}

Expected:

Erikas-Macbook:BUG erikaarnocki$ ts-node bug.ts
{
  _id: new ObjectId("61e5471c712520a0f39ebbef"),
  birthday: 2022-01-17T10:39:40.000Z
}

Desktop:

  • ts-node v8.10.2

Moment-specific environment

  • The time zone setting of the machine the code is running on
Erikas-Macbook:BUG erikaarnocki$ locale
LANG="en_GB.UTF-8"
LC_COLLATE="en_GB.UTF-8"
LC_CTYPE="en_GB.UTF-8"
LC_MESSAGES="en_GB.UTF-8"
LC_MONETARY="en_GB.UTF-8"
LC_NUMERIC="en_GB.UTF-8"
LC_TIME="en_GB.UTF-8"
LC_ALL=
  • The time and date at which the code was run
    Mon 17 Jan 2022 10:32:37 GMT
  • Other libraries in use (TypeScript, Immutable.js, etc)
{
  "devDependencies": {
    "@types/node": "^17.0.9",
    "cypress-wait-until": "^1.7.1"
  },
  "dependencies": {
    "moment": "^2.29.1",
    "mongoose": "^6.1.6",
    "typescript": "^4.5.4"
  }
}

Please run the following code in your environment and include the output:

console.log((new Date()).toString())
console.log((new Date()).toLocaleString())
console.log((new Date()).getTimezoneOffset())
console.log(navigator.userAgent)
console.log(moment.version)
Erikas-Macbook:BUG erikaarnocki$ ts-node
> console.log((new Date()).toString())
Mon Jan 17 2022 10:33:56 GMT+0000 (Greenwich Mean Time)
undefined
> console.log((new Date()).toLocaleString())
17/01/2022, 10:33:56
undefined
> console.log((new Date()).getTimezoneOffset())
0
undefined
> console.log(navigator.userAgent)
/Users/erikaarnocki/BUG/[eval].ts:1
console.log(navigator.userAgent);
            ^

Uncaught ReferenceError: navigator is not defined
    at /Users/erikaarnocki/BUG/[eval].ts:1:13
    at Script.runInThisContext (vm.js:133:18)
    at exec (/usr/local/lib/node_modules/ts-node/src/bin.ts:347:17)
    at /usr/local/lib/node_modules/ts-node/src/bin.ts:337:27
    at Array.reduce (<anonymous>)
    at _eval (/usr/local/lib/node_modules/ts-node/src/bin.ts:336:18)
    at REPLServer.replEval (/usr/local/lib/node_modules/ts-node/src/bin.ts:387:16)
    at bound (domain.js:413:15)
    at REPLServer.runBound [as eval] (domain.js:424:12)
    at REPLServer.onLine (repl.js:817:10)
@ErikaA4
Copy link
Author

ErikaA4 commented Jan 17, 2022

Opened ticket to moment as well.
moment/moment#5966

@Maximusya
Copy link

Just a guess:

  1. you are using default: moment.utc in your schema: that's a function accepting some doc object (as per https://mongoosejs.com/docs/migrating_to_6.html#document-parameter-to-default-functions)
  2. moment.utc(obj) expects year, month etc fields in an object argument (per https://momentjs.com/docs/#/parsing/object/). Omitted units default to 0 or the current date, month, and year.

So this schema definition might work for you:

  const kittySchema = new mongoose.Schema({
    birthday: {default: () => moment.utc(), type: Date}
  });

@Uzlopak
Copy link
Collaborator

Uzlopak commented Jan 17, 2022

@Maximusya
Semantically it is imho no difference.

Maybe there is a conversion issue. Probably it does a .toString, of the Moment-Object, which results in loss of milliseconds.Then it should be actually

birthday: {default: () => moment.utc().toDate(), type: Date}

@Maximusya
Copy link

What I meant is here: https://jsfiddle.net/n3vj01ax/:

console.log(moment.utc().toString());
console.log(moment.utc({ foo: 1 }).toString());

"Mon Jan 17 2022 15:17:25 GMT+0000"
"Mon Jan 17 2022 00:00:00 GMT+0000"

@AbdelrahmanHafez
Copy link
Collaborator

As the comments have pointed out, you need to change default: moment.utc to default: () => moment.utc(), that's a breaking change in mongoose v6.

  const kittySchema = new mongoose.Schema({
    birthday: { default: moment.utc, type: Date }
  });
  //   birthday: 2022-01-18T00:00:00.000Z

  const kittySchema = new mongoose.Schema({
    birthday: { default: () => moment.utc(), type: Date }
  });
  //   birthday: 2022-01-18T12:41:43.889Z

@AbdelrahmanHafez AbdelrahmanHafez added the help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary label Jan 18, 2022
@AbdelrahmanHafez AbdelrahmanHafez added docs This issue is due to a mistake or omission in the mongoosejs.com documentation and removed help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary labels Jan 19, 2022
@ErikaA4
Copy link
Author

ErikaA4 commented Jan 19, 2022

Thanks all for the help!
This worked perfectly:
birthday: {default: (): Date => moment.utc().toDate(), type: Date}

vkarpov15 added a commit that referenced this issue Jan 21, 2022
docs(migration): add note to change default functions to schema
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs This issue is due to a mistake or omission in the mongoosejs.com documentation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants