questionbank
questionbank

Reputation: 440

"getDate is not a function" after adding the timezone

I am displaying a real-time date and time but I am getting the error getDate is not a function.

I am getting this error because I added timezone like this

var x = new Date().toLocaleString("en-US", {timeZone: "America/New_York"});

Would you help me out on this issue?

function calculateUSATime() {
  var refresh = 1000; // Refresh rate in milli seconds
  mytime = setTimeout('currentUSATime()', refresh)
}


function currentUSATime() {
  var x = new Date().toLocaleString("en-US", {
    timeZone: "America/New_York"
  });
  var date = x.getDate();
  var month = x.getMonth(); //Be careful! January is 0 not 1
  var year = x.getFullYear();
  document.getElementById('ct').innerHTML = date;
  calculateUSATime();
}
<body onload=currentUSATime();>
  <span id='ct'></span>

</body>

Upvotes: 3

Views: 2414

Answers (2)

Matt Johnson-Pint
Matt Johnson-Pint

Reputation: 241525

As others mentioned, toLocaleString returns a string, and thus you cannot treat it as a Date object. Since you appear to want to display it as a string anyway, then the correct approach is to simply pass all of the arguments that you need to get the string in the desired format.

For example:

var s = new Date().toLocaleString(undefined, { 
    timeZone: 'America/New_York',
    weekday: 'long',
    year: 'numeric',
    month: 'numeric',
    day: 'numeric',
    hour: 'numeric',
    minute: 'numeric',
    second: 'numeric'
})

This gives the current time in America/New_York (US Eastern Time), using the user's locale for formatting (undefined defaults to the user's locale), and specifies that the full name of the weekday should be given, along with the numeric format of the date and time.

Example outputs depending on the user's locale:

en-US    "Thursday, 4/11/2019, 1:13:14 PM"
en-GB    "Thursday, 11/04/2019, 13:13:14"
fr-FR    "jeudi 11/04/2019 à 13:13:14"
zh-CN    "2019年4月11日星期四 下午1:13:14"

You can read all of the options in the toLocaleString documentation.

It was also suggested in a different answer that you could take the output of toLocaleString and parse it with the Date object's constructor. That approach is not recommended, for the following reasons:

  • The ECMAScript specification does not require that these strings can be handled by the Date parser. It only requires parsing of ISO8601 compliant strings, such as "2019-04-11T13:13:14". Anything else at all (even if it looks simple like "4/11/2019, 1:13:14 PM") is implementation dependent. In other words, not all browsers will agree on how to parse these strings, and some will refuse to, giving Invalid Date.

  • The Date object's parser will always use the user's current locale. So if you did hardcode the locale to en-US in the toLocaleString call, then parsed it in the UK, you would erroneously flip the month and day components. April 11th would be treated as November 4th.

  • When you parse a string that looks like local time with the Date object, it will rightly assume that it is in the user's local time zone. There are consequences of that. Consider that you may be passing a date and time that are valid in America/New_York, but are invalid in the user's local time zone. For example, March 31st 2019 at 1:30 AM is valid in the US, but would be invalid in the UK because it falls into their spring-forward DST gap (the clocks in the UK advanced from 00:59 to 02:00, skipping over that hour). In this case, the behavior is undefined. You may get Invalid Date, or you may get 00:30 or 02:30, but you won't get 01:30.

  • If you did reconstruct a Date object, if the user's time zone is different than the one given, you're creating a very different point in time. If you then passed that Date object into something else, it would have no idea that you meant US Eastern Time. Ultimately, Date objects don't keep track of dates, but rather they keep a Unix Timestamp, which is related strictly to UTC. Indeed, the name Date is confusing and inappropriate (IMHO).

Upvotes: 2

Maheer Ali
Maheer Ali

Reputation: 36564

toLocaleString will return a String. You can pass it again to date constructor to get the instance of Date. According to MDN

The toLocaleString() method returns a string with a language sensitive representation of this date

var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];


function calculateUSATime() {
  var refresh = 1000; // Refresh rate in milli seconds
  mytime = setTimeout('currentUSATime()', refresh)
}


function currentUSATime() {
  let str = new Date().toLocaleString("en-US", {
    timeZone: "America/New_York"
  })
  var x = new Date(str);
  var date = x.getDate();
  var month = x.getMonth(); //Be careful! January is 0 not 1
  var year = x.getFullYear();
  document.getElementById('ct').innerHTML = days[x.getDay()]+ ' ' + x.toLocaleString();
  calculateUSATime();
}
<body onload=currentUSATime();>
  <span id='ct'></span>

</body>

Another thing you can improve it that remove calculateUSATime and use setTimeout inside currentUSATime.

function currentUSATime() {
  let str = new Date().toLocaleString("en-US", {
    timeZone: "America/New_York"
  })
  var x = new Date(str);
  var date = x.getDate();
  var month = x.getMonth(); //Be careful! January is 0 not 1
  var year = x.getFullYear();
  document.getElementById('ct').innerHTML = x;
  
  var refresh = 1000; // Refresh rate in milli seconds
  mytime = setTimeout(currentUSATime, refresh)
  
}
<body onload="currentUSATime();">
  <span id='ct'></span>

</body>

Upvotes: 5

Related Questions