-1

I'm trying to host an app with a countdown timer that subtracts the current UTC date and time from a given UTC date and time in the future. But the issue is with new Date(), new Date(Date.now()), etc I keep getting local time which is several hours off. How can I create a new Date object with the current time in UTC?

let date = new Date()
date = date.toUTCString().slice(0, date.toUTCString().length - 13);
let time = "17:00:00"    
// this is the UTC time of the event, this works hosted
// locally this has to be "12:00:00"

const timeLeft = new Date(`${date} ${time}`) - new Date();
const hoursLeft = Math.floor((timeLeft / (1000 * 60 * 60)));
const minutesLeft = Math.ceil((timeLeft / 1000) / 60 % 60);
// I'm trying to get a consistent hoursLeft on both local and hosted machines

I'm probably going to just use moment.js to avoid the issue and simplify the code, but I'd still really like to know an answer.

arsy
  • 119
  • 12
  • Use [Date.UTC](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC)? – chazsolo Apr 02 '21 at 16:40
  • 1
    Date.UTC doesn't work because you have to give it the date in the arg, `Date.UTC()` is NaN. I need a `Date.now()` that will use UTC time. – arsy Apr 02 '21 at 16:43
  • Convert to epoch time? Convert to a GMT string and create a date from it? Without knowing what your inputs actually are (e.g., if you have a valid UTC string then it seems a matter of conversion) it's difficult to know what the specific issue is. – Dave Newton Apr 02 '21 at 16:49
  • The inputs have nothing to do with the problem, the `new Date(date, time)` works as expected, and is consistently in UTC. It's the `new Date()` that is the issue. That one gives a different date locally and hosted, I'd like it to always create the new Date with the current time in UTC. – arsy Apr 02 '21 at 16:55
  • ... and I'm saying this doesn't make a lot of sense--the *representation* of a date doesn't affect date math. It's the same underlying epoch time, hence I'm trying to understand what inputs you have, and what output you want. – Dave Newton Apr 02 '21 at 17:02
  • For example, `new Date(new Date().toGMTString()) - Date.now()` returns a small value since the dates are created almost immediately. – Dave Newton Apr 02 '21 at 17:03
  • Does this answer your question? [create javascript date UTC](https://stackoverflow.com/questions/13364036/create-javascript-date-utc) – Heretic Monkey Apr 02 '21 at 17:04
  • @DaveNewton added example inputs to the codeblock, and outputs that I'm wanting and getting – arsy Apr 02 '21 at 17:28
  • @HereticMonkey that does not answer my question, that answer requires you to have the date time available at creation – arsy Apr 02 '21 at 17:35
  • 3
    You're right. Because the answer is, `new Date()` ***is*** a "date object for the current time in UTC". See the answers to [get UTC date (not UTC string) in javascript](https://stackoverflow.com/q/57810435/215552) – Heretic Monkey Apr 02 '21 at 17:45

2 Answers2

0

How do you create a new javascript date object for the current time in UTC?

Either of these do exactly that and only that.

const d = new Date();

or

const d = new Date(Date.now());

Internally, the Date object only stores one value, which is the count of milliseconds since 1970-01-01T00:00:00.000Z (a Unix timestamp), which is in terms of UTC and thus the Date object itself is also in terms of UTC, and the idea of getting the current Date object from new Date() or the current Unix timestamp from Date.now() are also in terms of UTC.

You may be confused because you are seeing the equivalent local time when displaying the Date object as a string, such as when seeing the output from console.log(d.toString()) (or just from console.log(d) in some environments, though not in all because such behavior is undefined). The local time zone is coming from the runtime environment during the toString call - it is not stored within the Date object itself.

If you want to see the time in UTC, then do console.log(d.toISOString()) instead. The toISOString function always shows the UTC date and time, in the ISO 8601 format.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
-1

Do like this:

var i=new Date();
var d = new Date(i.getUTCFullYear(), i.getUTCMonth(), i.getUTCDate(), i.getUTCHours(), i.getUTCMinutes(), i.getUTCSeconds());

to create a new Date object with the current time in UTC.

Update
This also work:

  var d = new Date();
  var n = d.toUTCString();
zoldxk
  • 2,632
  • 1
  • 7
  • 29
  • 3
    This creates a Date object *in the current time zone* with the same values as those of the current time in UTC. However, the Date will obey any DST rules for the current time zone (so if the current time is in the "non-hour" some time zones experience when springing forward, it will show the wrong time), and using `getTimezoneOffset()` will show a value other than 0 (unless the current time zone is UTC or the offset is UTC+00:00). – Heretic Monkey Apr 02 '21 at 17:54
  • 1
    @HereticMonkey I'm still trying to get my head around why, but this solution works for both local and remotely hosted versions of the app. – arsy Apr 02 '21 at 18:00
  • 1
    This approach should almost never be used. You've changed the meaning of what a Date object is intended to be. If this is working for you, then you're doing something *else* wrong, such as how you are interpreting the output of a function using the resulting object. Perhaps also the clock and/or time zone is set incorrectly on your computer or server. – Matt Johnson-Pint Apr 02 '21 at 22:35
  • The exact same result can be achieved using `d.setMinutes(d.getMinutes() + d.getTimezoneOffset())`, i.e. it shifts the time value of the date by the applicable timezone offset so *local* values are the same as the previous UTC values. – RobG Apr 02 '21 at 23:41