0

var d = new Date("sep 01, 2020 01:59:59");
var c = d.toLocaleString('de-DE', {timeZone: 'CET'});
console.log(c); // 31.8.2020, 17:59:59

I need to convert variable c to milliseconds as the getTime() method does with Date object. How to make this possible?

RobG
  • 142,382
  • 31
  • 172
  • 209
Jessica
  • 19
  • 1
  • 6
  • getTime converts Date object into milliseconds not seconds – Krzysztof Krzeszewski Aug 14 '20 at 12:39
  • 1
    can you explain why can't you just call getTime() on variable d? – Marfee Aug 14 '20 at 12:44
  • You don't. You get milliseconds from a `Date` object, not a string. – Heretic Monkey Aug 14 '20 at 12:46
  • I have to change the timezone to CET – Jessica Aug 14 '20 at 12:46
  • Do not do that. The output of *toLocaleString* is implementation dependent, there's no requirement for the built–in parser to parse it correctly, e.g. in Safari `new Date('31.8.2020, 17:59:59')` produces an invalid date. Even the use of `new Date("sep 01, 2020 01:59:59")` is problematic, see [*Why does Date.parse give incorrect results?*](https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results) Also, the string has no associated offset so parsing will likely use whatever the host system is configured to for that date and time. – RobG Aug 15 '20 at 03:20

2 Answers2

3

Stay away from localeStrings if at all possible

They are ugly and hard to program with. Honestly, do all your processing on the underlying Date Object, and all your text storage with ISO date strings. Anyway, if someone forces you at gunpoint to receive a localeString, let Javascript interpret it for you as follows.

var d = new Date("sep 01, 2020 01:59:59");
var c = d.toLocaleString('de-DE', {timeZone: 'CET'});

var sensibleFormat = new Date(c)
var milliseconds = sensibleFormat.getTime()
console.log(milliseconds)

In light of your clarification above ("I have to change the timezone to CET"), did you mention CET because you want to count milliseconds from some fixed time defined in CET?

Your question would be much, much easier to answer if you specified an example of what numerical answer would be correct.

ProfDFrancis
  • 8,816
  • 1
  • 17
  • 26
  • 1
    "*if someone forces you at gunpoint to receive a localeString*" risky tactic. Bold of them to assume I place higher on value my life than I place on not messing around with random date formats. ;P – VLAZ Aug 14 '20 at 12:57
  • Agreed! A quick death by bullet might be preferable to an agonising death-by-a-thousand-edge-cases. – ProfDFrancis Aug 14 '20 at 13:01
  • I have fixed time defined with Date object (var d) which uses UTC and I converted that time to CET with toLocaleString() method. – Jessica Aug 14 '20 at 13:15
  • Yes, I can see that from the question. However, what number of milliseconds do you want to calculate? The number of milliseconds from WHEN, to the Sep 01, 2020 01:59:59 date? – ProfDFrancis Aug 14 '20 at 13:33
  • 2
    "*let Javascript interpret it for you…*", no, don't do that. Take the bullet. – RobG Aug 15 '20 at 03:14
2

Don't do this

There are a number of issues with what OP is attempting, firstly with new Date("sep 01, 2020 01:59:59"):

  1. The format is not supported by ECMA-262, so parsing is implementation dependent and it may or may not be parsed as expected
  2. Even if parsed correctly, the host system offset will be assumed so it will represent a different moment in time for each system with a different offset

Also see Why does Date.parse give incorrect results?

Problems with d.toLocaleString('de-DE', {timeZone: 'CET'}):

  1. The exact output format is not specified, so implementations are free to convert the language "de-DE" to whatever format they think matches
  2. Whatever format is produced is not required to be parsable by the implementation that generated it, much less other implementations. E.g. given new Date('31.8.2020, 17:59:59') Safari and Firefox return an invalid Date
  3. The timezone is likely not included in the string, so the same issue arrises as with #2 above.

Do this instead

A reasonable approach would be to use some other parser for the string and associate the required timezone (a library can help greatly with that, either by adding it to the string or specifying it as an option). That should generate a suitable Date and also provide a method to get the time value, which is milliseconds so can be converted to seconds by dividing by 1000.

The only way to do this without a library is to mess with Intl.DateTimeFormat to work out what the offset should be, then manually apply it (per this anwer). Much simpler to use a library like Luxon:

let DateTime = luxon.DateTime;

// Timestamp to parse
let s = 'sep 01, 2020 01:59:59';
// Format of input timestamp
let fIn = 'MMM dd, yyyy HH:mm:ss';
// Location to use to determine offset when parsing
let loc = 'Europe/Paris';
let d = DateTime.fromFormat(s, fIn, {zone: loc});
// Show date using Luxon default format
console.log(d); // "2020-09-01T01:59:59.000+02:00"

// Show date in set format
let fOut = 'dd.MM.yyyy, HH:mm:ss ZZ'; 
console.log(d.toFormat(fOut)); // 01.09.2020, 01:59:59 +02:00

// UNIX timestamp in seconds
console.log(d.toFormat('X'));  // 1598918399
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/1.24.1/luxon.min.js"></script>

You can do the same thing with other libraries, Luxon is just a convenient example. Note that with Luxon, once a location is associated with the object, it keeps using that location for offset and timezone data, which might be handy or annoying, depending on what you're trying to do.

RobG
  • 142,382
  • 31
  • 172
  • 209