0

I have a string like 20221004093142Z which I need to convert into a datetime format in JavaScript. Can someone help me on this?

ThS
  • 4,597
  • 2
  • 15
  • 27
Akshat
  • 1
  • 1
  • 1
    Have you tried `Date("20221004093142Z")` ? – mnikley Oct 04 '22 at 12:08
  • @mnikley the date/format that the OP has is not valid thus `Date("20221004093142Z")` will simply be ignored and the current date will be returned (you may test it in the console). – ThS Oct 04 '22 at 12:09
  • You're date format is invalid. Could you elaborate more on how you get or generate this date/format ? – ThS Oct 04 '22 at 12:11
  • @ths interesting - my browser returns `'Tue Oct 04 2022 14:14:22 GMT+0200 (Central European Summer Time)'` – mnikley Oct 04 '22 at 12:14
  • @mnikley maybe the docs on MDN have some clues but at first glance, a wrong format/date is simply ignored. – ThS Oct 04 '22 at 12:23
  • This date I'm getting as an LDAP response for a newly created profile. It's today's day and time in UTC/GMT format. I'm uncertain how it's getting populated cause it's being internally being done by LDAP. – Akshat Oct 04 '22 at 12:28
  • @Akshat what is the the output format you are aiming for? Date("20221004093142Z") literally returns Tue Oct 04 2022 09:31:42 GMT+0200 (Central European Summer Time) in console. – Deniz Karadağ Oct 04 '22 at 13:08
  • @DenizKaradağ if I try to print previous day or future day then it's not working like if I try to print 3rd Oct then I have Date("20221003093142Z") but it's not working – Akshat Oct 04 '22 at 13:38
  • @Akshat fair point. I missed that. I think easiest solution is to use string.substring so you can split and join substrings in a way you want. – Deniz Karadağ Oct 05 '22 at 07:36

2 Answers2

1

Maybe you can use a RegExp to convert your input string to an ISO date formatted string (which is the closest to your input string) and then create a date from that formatted string. Something like:

const inputStr = '20221004093142Z'
const re = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\.\d{0,3})?/g;
const formattedStr = inputStr.replace(re, '$1-$2-$3T$4:$5:$6$7');
const outputDate = new Date(formattedStr);

console.log(`inputStr: ${inputStr}`);
console.log(`formattedStr: ${formattedStr}`);
console.log(`outputDate: ${outputDate}`);
console.log(`outputDate.toLocaleString(): ${outputDate.toLocaleString()}`);

The Regular Expression (RegExp) explained:

  • parentheses (()) delimit what is called a "capturing group", which can then be referred to by its position (e.g. $1 is the content of the first capturing group, $2 of the second, etc.)
  • \d matches any digit (0-9)
  • the curly brackets ({}) mark a quantifier: how many occurrences of the preceding character or group should I look for? You can provide an exact quantity ({4} -> exact 4) or a range ({0,3} -> from 0 up to 3)
  • the question mark (?) indicates that the preceding character or group is optional (there can be zero or exactly one occurrence, but no more than one)

So what the RegExp proposed does is to look for

  1. a group of four digits ((\d{4})), which will be referenced as $1, followed by
  2. a group of two digits ((\d{2})), which will be referenced as $2, followed by
  3. a group of two digits ((\d{2})), which will be referenced as $3, followed by
  4. a group of two digits ((\d{2})), which will be referenced as $4, followed by
  5. a group of two digits ((\d{2})), which will be referenced as $5, followed by
  6. a group of two digits ((\d{2})), which will be referenced as $6, followed by
  7. an optional group formed by a dot (\.) and 0-to-3 digits (\d{0,3}), which will be referenced as $7

Now we have:

  • the year (4 digits) in $1
  • the month (2 digits) in $2
  • the day (2 digits) in $3
  • the hours (2 digits) in $4
  • the minutes (2 digits) in $5
  • the seconds (2 digits) in $6
  • the milliseconds (a dot followed by up to 3 digits) - if present - in $7

and we can use those substrings in the second argument of the String.prototype.replace() function, in order to transform the original string as we need.

For more on RegExp you can refer to: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp

I also find this website useful as a quick reference and to test my RegExp: https://regexr.com/

secan
  • 2,622
  • 1
  • 7
  • 24
  • just for those who are "reg-ex-challenged" like me, the `re` regular-expression identifies 7 groups. First 4 `\d` (ie, digit/numeric/0..9) characters (`$1`), next 2 each (`$2`, to `$6`) and the last group `\d{0,3}` is identified as `$7`. One can search regex to learn more, if interested. – jsN00b Oct 04 '22 at 12:23
  • 1
    maybe adding some explanation especially for that *hieroglyphic* `RegExp` should make your answer even better and helpful for anyone having a basic knowledge (or none) about regular expressions. – ThS Oct 04 '22 at 12:25
  • 1
    @jsN00b to be 100% precise, in the version I posted the last group (`$7`) includes the dot too and is marked as optional: `(\.\d{0,3})?` so a dot followed by 0-to-3 digits and the entire group can be present or not. It should be easy to understand how to change it to make it work in case the dot i snot part of the input string, I think – secan Oct 04 '22 at 12:31
  • @ths, I will try to add some clarification but probably explaining how RegExp work here would be out of the scope and a link to further resources would work better. – secan Oct 04 '22 at 12:33
  • If `RegExp`s are a way to solve the issue, explaining the *parts* found in your `RegExp` would actually make sense and should give us, as readers, an idea on why you chose this specific `RegExp`. – ThS Oct 04 '22 at 12:37
  • @ths, if you like, please have a look at the edit and let me know whether you find it clear and complete enough (English is not my native language) or if it needs improvements. Thank you very much in advance. – secan Oct 04 '22 at 13:05
  • @secan yes, that looks good enough to me. Thanks for having taking into consideration my request. – ThS Oct 04 '22 at 13:14
1

If the timestring format never changes, you could build your datetime variable like the following:

let timestring = "20221004093142Z"

timestring = 
timestring.substring(0, 4) + "-" + 
timestring.substring(4, 6) + "-" + 
timestring.substring(6, 8) + " " + 
timestring.substring(8, 10) + ":" + 
timestring.substring(10, 12) + ":" + 
timestring.substring(12, timestring.length - 1)

let datetime = new Date(timestring)

console.log(datetime)

You could also build it the same way creating the single year, month etc. values with substring and then set it together.

Pretty sure there is a way to simplify the substring thing with splicing the ":" and "-" chars into the timestring.

Mauli999
  • 26
  • 5