Safe (format independent) way to .slice() time substring out of ISOString - javascript

Is it safe to use slice like this on ISOString to extract time from it?
new Date().toISOString().slice(11, -8); //08:01

The toISOString() method returns a string in simplified extended ISO format (ISO 8601), which is always 24 or 27 characters long (YYYY-MM-DDTHH:mm:ss.sssZ or ±YYYYYY-MM-DDTHH:mm:ss.sssZ, respectively).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
So, no, that particular code is not safe. You'd need to use negative offsets for both to be safe.

If you need it to work regardless of time-substring position within output string, you may stick to : delimiter, using RegExp, though, it probably may be somewhat slower compared to slice() or split():
const [time] = new Date().toISOString().match(/\d{1,2}:\d{1,2}/g)
console.log(time)

I would think there are safer options since
The toISOString() method returns a string in simplified extended ISO format (ISO 8601), which is always 24 or 27 characters long
YYYY-MM-DDTHH:mm:ss.sssZ or
±YYYYYY-MM-DDTHH:mm:ss.sssZ,
respectively). The timezone is always zero UTC offset, as denoted by the suffix "Z".
Whereas toUTCString has only one type of output according to MDN. This may not be correct as seen in the ecma262 where there may be negative dates - the code below should still work
const t1 = new Date().toISOString().split("T")[1].slice(0, -8);
const t2 = new Date().toUTCString().split(" ")[4].slice(0, -3); // safer
const t3 = new Date().toLocaleTimeString("en-GB").slice(0, -3) // if you want user's time
console.log(t1,t2,t3)
// or as deceze suggested in his comment
const pad = num => ("0"+num).slice(-2);
const d = new Date();
const t4 = `${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}`;
console.log(t4)

Related

Invalid date when using a unix timestamp with letters in it in JavaScript

This is the timestamp I have: 5fb6995
When I do new Date('5fb6995') Invalid Date gets returned. But when I try converting it online in an online converter, everything works. Why doesn't this work and how can I make it work?
You can convert your hexadecimal timestamp to decimal with parseInt and radix 16.
However your timestamp is in hours or something
const ts = parseInt("5fb6995",16);
console.log(new Date(ts)); // 1970
console.log(new Date(ts*1000)); // still 1973 (Unix TSs are normally in seconds since Epoch - 1970/01/01)
// perhaps you want hh-mm-ss from that UNIX timestamp:
console.log(
new Date(ts * 1000).toISOString().slice(11,-5)
)
your string 5fb6995 is in hexadecimal base, you need to first convert it to decimal:
new Date(parseInt("5fb6995", 16));

Unexpected Javascript Date object implicit conversion

Why Javascript's Date object returns different value for implicit conversions?
Number conversion:
+new Date()
// returns 1456293356618 as expected
String conversion:
''+new Date()
// returns "Wed Feb 24 2016 09:26:28 GMT+0" but "1456293356618" as a string was expected
Where can I find the documentation on ECMAScript and the implementation on v8's source?
Edit: I'm not looking for the solution for the expected result. I want to find the documentation in the specs.
The + operator is overloaded. In:
+new Date()
it is treated as the unary + operator and coerces the value to Number. In:
'' + new Date() // note one value is a string
it is treated as the string concatenation operator and coerces the values to String. In:
5 + 6 // note both values are number
it is treated as the addition operator. Since the values are numbers, no coercion is necessary.
Note that whether + does addition or concatenation depends on the values and is described in ECMAScript 2015 §12.7.3.1 step 11.
I think you are refering to this Overview of Date Objects and Definitions of Abstract Operators, specifically Section 20.3.1.1
A Date object contains a Number indicating a particular instant in time to within a millisecond. Such a Number is called a time value. A time value may also be NaN, indicating that the Date object does not represent a specific instant of time.
This means that using math operations on a Date object will extract its Number value to work. That's why statements like +new Date() and Math.floor(new Date()) returns a Number.
As for '' + new Date(), the Date object returns its String value perhaps using its toString() function.

Why does 'new Date() * 1' produce a Javascript timestamp?

I have the following methods of obtaining a timestamp:
new Date().valueOf()
new Date().getTime()
Date.parse(new Date())
new Date() * 1
But I'm confused: why am I able to get a timestamp using the last method?
This is because the Date() object can be converted directly to a number (the timestamp), and when applying mathematical operators to it JavaScript converts this for us.
An even quicker way to get the timestamp is to use the Unary Plus:
+new Date();
The unary plus operator precedes its operand and evaluates to its operand but attempts to converts it into a number, if it isn't already. Although unary negation (-) also can convert non-numbers, unary plus is the fastest and preferred way of converting something into a number, because it does not perform any other operations on the number.
– MDN's Unary Plus documentation.
The same applies with strings "1" * 1 equals 1 because JavaScript automatically converts "1" to a number because of the presence of the multiplication operator (*).
One of the weird things about JavaScript is that if you try and perform an operation between two variables, it will try to convert them to a type where it can perform this operation. But this can happen in different ways, so for example "2" * 2 === 4 is true, but so is "2" + 2 === "22" because it goes to the string version of the + operator first.
When you take a Date and try to do multiply or divide it, JavaScript will understand that as converting the Date to it's numerical timestamp value. Consequently the surprising outcome you see above.
However:
new Date() + 1
Results in "Tue Jul 07 2015 15:20:17 GMT+0100 (GMT Daylight Time)1" because the date can also be treated as a string.
This is one of the many quirks of JavaScript that will be helpful to understand when you run into that weird bug, but you would be well advised to avoid using in your code if you want to be able to understand it at a glance later ( spoiler warning: You do! )

JavaScript regexp parse date/time to milliseconds

I need a little bit of help with a regular expression to convert a date into milliseconds using regular expressions.
I am not sure what regular expression I need to do this.
Here are a few example dates:
3 dagar, 12:00:46
2 dagar, 8:01:00
1 dag, 11:34:00
0 dagar, 0:04:00
Again, I'd like a regexp that will parse these dates into milliseconds.
Alternatively I could use a library like this, to parse the date. But I have not much experience with that either.
The following regex captures days, hours, minutes and seconds.
I asume that you want the number of milliseconds since 1 Jan 1970 (epoch).
We initialize a Date object with the captured info and extract the milliseconds:
var regexp = /([0-9]*) [a-z]*, ([0-9]*):([0-9]*):([0-9]*)/;
var match = regexp.exec('3 dagar, 12:00:46'); //insert your timespan as text here
var date = new Date(1970, 0, parseInt(match[1]) + 1, match[2], match[3], match[4]);
// var result = Math.floor(date.getTime()/1000); //seconds
var result = date.getTime() - date.getTimezoneOffset() * 60000; //milliseconds
We also need to consider the timezone. The date.getTimezoneOffset() returns the offset in minutes.
Maybe you want to test this in rubular and adjust because it may cause problems if the input does not comply with the format that you provided.

Does UTC date string require the format specifier "Z" even if that string includes time offset?

For instance,
const d = new Date("2012-08-20T15:00:00-07:00");
d here is a UTC time with time offset = 07:00. Does it still require Z like this 2012-08-20T15:00:00-07:00Z? Is this correct?
If I take this string with Z and parse it using Date.parse() method in JavaScript, it throws an error. Not sure what is wrong!
No, you should not include the "Z" with a time zone offset.
From rfc3339:
Z A suffix which, when applied to a time, denotes a UTC
offset of 00:00; often spoken "Zulu" from the ICAO
phonetic alphabet representation of the letter "Z".
The "Z" is a zero time offset, so including it with an explicit offset (especially a non-zero one) doesn't makes sense.
Quoting W3C note on Date and Time Formats:
YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
where:
[...]
TZD = time zone designator (Z or +hh:mm or -hh:mm)
Notice the or word above. You either specify time zone offset or Z for Zulu (no offset).

Categories