-2

I have an ISO date which is stored as a string. I want to get only the hours part as is. The below code does not work. So, how do I make it work using dayjs?

function getHours(date:string){
 const hour : dayjs(date).hour();
 console.log(hour);
}

getHours("2023-05-06T08:00:00Z");//Expected 8, but got 1.
MasterJoe
  • 2,103
  • 5
  • 32
  • 58
  • 7
    Why don't you just `new Date("2023-05-06T08:00:00Z").getUTCHours()`? – Chang Alex May 09 '23 at 22:47
  • @ChangAlex - That works too. But, in my codebase it is preferred to use Dayjs whenever possible. – MasterJoe May 09 '23 at 22:56
  • 1
    Looks like that preference is making your life harder. – Aurast May 09 '23 at 23:07
  • 4
    I understand wanting to be consistent within the codebase, and certainly wouldn't recommend mixing in something like moment alongside dayjs, but for this particular task dayjs seems like simultaneously overkill and more complicated, since it requires a plugin to do the time zone conversion. – Mark Reed May 09 '23 at 23:08

2 Answers2

2

In dayjs you need to use the utc plugin:

var dayjs = require("dayjs")
var utc   = require("dayjs/plugin/utc")

dayjs.extend(utc);

function getHours(date){
 const hour = dayjs.utc(date).hour();
 return hour;
}

getHours("2023-05-06T08:00:00Z"); // 8
Jeffrey Mixon
  • 12,846
  • 4
  • 32
  • 55
0

You have a string with a specific format and you want a substring. Using a date library like dayjs or even built-in Date would be overkill. Get the substring and optionally convert it to a number:

function getHours(date){
  console.log(date.substr(11, 2));
  console.log(+date.substr(11, 2));
}

getHours("2023-05-06T08:00:00Z");

No plugins, no external libraries and only one conversion from string to number required.

jabaa
  • 5,844
  • 3
  • 9
  • 30
  • 1
    Try using that to parse "20230506T080000Z", which is a [valid ISO date time string](https://en.wikipedia.org/wiki/ISO_8601). – meriton May 09 '23 at 23:25
  • 1
    @meriton javascript Date (and dayjs) only accepts a simplified ISO 8601 [date time string format](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date#date_time_string_format) so "20230506T080000Z" would also fail if passed to `new Date`. Also the OP has specified the format they are expecting to be `"2023-05-06T08:00:00Z"` – pilchard May 09 '23 at 23:33
  • Yes, but the Date constructor would fail cleanly (by returning an "invalid date") rather than silently returning the wrong number of hours. – meriton May 09 '23 at 23:40
  • @meriton If you want format validation and error handling, you can add it, but you probably have to add it to all different approaches. The `Date` object is allowed to handle your string as local timestamp and also return a wrong value, because the format is not specified in the specification and therefore implementation defined. The other answer using dayjs returns `NaN` which should also be considered as returning silently the wrong "number" since `NaN` is a IEEE 768 number value. – jabaa May 09 '23 at 23:54
  • js-joda throws an exception, for instance. And while I agree that returning NaN is not great, I'd still prefer it to returning 0 - at least, NaN gives you an indication something is wrong! – meriton May 10 '23 at 02:45
  • @meriton I would add a regex and an exception to avoid wrong formats if necessary, but that wasn't part of the question. `if (!date.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/)) throw new Error('Wrong format');` – jabaa May 10 '23 at 09:02