-2

If we do this:

const d = new Date('2010-10-20');
console.log(d.getUTCDate());

The console will log 20.

However if we do:

const d = new Date('2010-10-20');
d.setHours(0, 0, 0, 0);
console.log(d.getUTCDate());

Then 19 is logged.

Is this correct? I was expecting 20 still. Thoughts?

This is a Stacblitz Demo

Another thing I noticed is when passing in time as all zeroes and then calling getUTCDate() the expected result is logged:

const d3 = new Date('2000-10-20T00:00:00Z');
console.log(`D3: ${d3.getUTCDate()}`);
Ole
  • 41,793
  • 59
  • 191
  • 359
  • 3
    it is because of the difference between your time zone and UTC. – Jafar Jabr Jan 04 '22 at 21:57
  • I thought getUTCDate() would always give the day the date is created with? So with `new Date("2010-10-20"), we will always get `20` when using the `getUTCDate()` method? – Ole Jan 04 '22 at 22:01
  • 1
    What _is_ the day that's created with? For a given point in time, which day it is depends on where you are. You'll get midnight _UTC_ on that day, but e.g. here in the UK that gives `Wed Oct 20 2010 01:00:00 GMT+0100 (British Summer Time)`. Then you `setHours` which is in _local_ time - from a UTC perspective, they were _already_ all zero, because you gave no time component. What are you actually trying to achieve? Why not just `new Date('2010-10-20').getUTCDate()` - what is the extra step for? – jonrsharpe Jan 04 '22 at 22:11
  • Perhaps you'd be interested in [Date.prototype.setUTCHours()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCHours) – Phil Jan 04 '22 at 22:22
  • As you were told here: https://stackoverflow.com/a/70482037/3001761. – jonrsharpe Jan 04 '22 at 22:25

1 Answers1

0

It is because of the difference between your time zone and UTC, getUTCDate() convert the time to UTC and then get the date of it. try:

const d = Date.UTC(2010, 10, 20, 0,0,0);
console.log(new Date(d).getUTCDate());

Also as @jonrsharpe pointed out in the comments, the real issue is that setHours instead of setUTCHours was called on the constructed date.

when you create a Date it will be created with the time zone from your env, nodejs read it from TZ if it is set in env. you can find the difference in minutes between the time on the local computer and Universal Coordinated Time (UTC) using: getTimezoneOffset()

Jafar Jabr
  • 642
  • 5
  • 11
  • So my original understanding [per this question](https://stackoverflow.com/questions/70585499/the-javascript-date-getutcdate-returns-different-number-when-time-component-se) is that `new Date('2010-10-20') and `const d3 = new Date('2000-10-20T00:00:00Z');` should be the same ... Is that not the case? – Ole Jan 04 '22 at 22:14
  • @Ole yes, that is the case. But that's _not_ all you do, you also call [`setHours`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setHours) on it. – jonrsharpe Jan 04 '22 at 22:16
  • @jonrsharpe I was expecting `setHours` to be redundant, since the time component should already be all zeroes? – Ole Jan 04 '22 at 22:19
  • 1
    @Ole then why did you call it? The time component _was_ already all zeros... _in UTC_. But then you set the _local_ time component, which gives a different _UTC_ date (because now you have midnight _local_ time on that date). – jonrsharpe Jan 04 '22 at 22:20
  • @jonrsharpe I call it in general on dates just to make sure the time component is all zeroes ... BUT IIUC, you are saying that I probably need to do this differently in order to get the result I want ... which is to keep the day the same and just have the time be all zeros ...? – Ole Jan 04 '22 at 22:21
  • @Ole it makes sure the time component is all zeros _locally_. It makes sure e.g. `.getHours()` returns 0, **not** `.getUTCHours()`. You already **had** the result you say you want, that's what `new Date("YYYY-MM-DD")` (or `new Date("YYYY-MM-DDT00:00:00Z")`, etc.) gives you. – jonrsharpe Jan 04 '22 at 22:23
  • 1
    @Ole _"the time component should be zero"_ - yes, _in UTC time_. _"I don't know exactly how the date is getting constructed"_ - you were told that [here](https://stackoverflow.com/a/70482037/3001761), it's `new Date(Date.parse("..."))` which _"is assumed you mean UTC"_. _"I also call setHours() to set the time component to zero as a precaution"_ - and that sets the _local_ time to zero and breaks it, not a good precaution. – jonrsharpe Jan 04 '22 at 22:28
  • @jonrsharpe OH got it. OK so by setting them to zero (Local time) I'm completely changing the date. Do you have any recommendations for setting them to zero so that I don't change the date? – Ole Jan 04 '22 at 22:28
  • 2
    @Ole I don't know how many different ways I can tell you _they're already all zero in UTC_. If you _really_ want to call a method just for the sake of doing so, as you were again told [here](https://stackoverflow.com/a/70482037/3001761), use `setUTCHours`, which is the name suggests sets the time component _in UTC_ (in this case to the value it already has). – jonrsharpe Jan 04 '22 at 22:29
  • @jonrsharpe OK cool!! I think I need `setUTCHours`. Thank you!! That's really what I was trying to get to :) – Ole Jan 04 '22 at 22:31
  • 1
    @Ole no, you **absolutely do not**, because `new Date("YYYY-MM-DD")` creates a `Date` that's _already in UTC_, so e.g. `getUTCHours` is _already `0`_. As you noted in your question, you got the right answer to start with, then decided to call another method and broke it. – jonrsharpe Jan 04 '22 at 22:32
  • @jonrsharpe I understand I broke it. And now I understand why it broke ... And I can go change the API from `setHours` to `setUTCHours` which is the part that was throwing me off ... Thanks for staying with me on this ... I was just confused about that part :) – Ole Jan 04 '22 at 22:35
  • 1
    @Ole or you could have read the dupe you were pointed to a fortnight ago: [_"That will set the time to 00:00:00.000 of your current timezone, if you want to work in UTC time, you can use the setUTCHours method."_](https://stackoverflow.com/a/3894087/3001761) Why you've accepted this answer covering none of that is not clear either - if you'd like to write an answer, it's better not to try to claim it's someone else's. – jonrsharpe Jan 04 '22 at 22:38
  • @jonrsharpe I updated the answer reflecting the feedback you gave about the `setUTCHours()` instead of `setHours()` which is what I needed to make sure the results are consistent. But if you like your answer better thats fine. – Ole Jan 04 '22 at 22:41
  • @jonrsharpe I will say though that the way the answer is framed now, does not really help with my. concern ... as I just wanted to ensure that the time component was all zeroes ... in the event that the date was constructed with a non zero time component ... – Ole Jan 04 '22 at 22:43
  • @Ole yes, it's not a very good answer (or mine, for that matter). The right thing to do is therefore not to upvote and accept and _completely change_ it, but to write a better one (or even better, go upvote the people who _already told you this_). – jonrsharpe Jan 04 '22 at 22:44
  • @jonrsharpe personally I think it's fine. He's a pretty new contributor and he gave it a shot and now he's on the board. Let him have the credit. The right information is there and it's a fairly complete picture now. Thanks for all your input BTW - I really appreciate it. – Ole Jan 04 '22 at 22:46