-2

Iam creating a time stamping api that gets date_strings from clients. Resource is GET /api/timestamp/:date_string and the date string is either a dateString [yyyy-mm-dd] or a unix timestamp in seconds ['2764800000']. I need a way to check whether the passed string is a valid unix time stamp.

Below is my function for validating the supplied date_string

function createDate(date_string) {
  const regexp = /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/;
  const regexp2 = /^(\d{13})?$/;
  let date;
  switch (typeof date_string) {
    case "string":
      if (regexp2.test(date_string)) {
        date = new Date(Number(date_string));
      }

      if (regexp.test(date_string)) {
        date = new Date(date_string);
      } else {
        return console.log("Invalid Date String");
      }
      break;
    case "undefined":
      date = new Date();
    default:
      return console.log("Unknown Date String");
  }
  return date;
}

Whenever i hit the api with a unix time stamp, it returns undefined i.e GET /api/timestamp/2764800000. i don't know where the problem is, is it with the RegExpression? I need Help

Herman Ceaser
  • 90
  • 2
  • 12
  • Why would the type of `date_string` ever ben anything _but_ string here? GET parameters are always strings. So unless you modified the type of the value before you pass it into that function - don’t expect the type to ever be anything _but_ string. – CBroe Sep 04 '20 at 08:52
  • Plus, what even is your definition of _“valid unix time stamp”_? _Any_ integer value is technically a valid unix timestamp. You seem to apply a rather arbitrary restriction of exactly 13 digits here. Which makes rather little sense in general, and even less when the example value you have given was ten digits long only. – CBroe Sep 04 '20 at 08:54
  • I didnt really understand what a "unix time stamp was". I thought it was constant i.e 13 digits but after experimentation with various dates, i discovered that it is just an integer of abitraly length. @c – Herman Ceaser Sep 04 '20 at 09:23
  • Any numeric value from -8.64e12 to +8.64e12 is a valid UNIX timestamp in seconds as far as ECMAScript Date objects are concerned, see [*ECMA-262*](http://ecma-international.org/ecma-262/10.0/#sec-time-values-and-time-range). So 2764800000 is valid based on that criterion (12 Aug 2057), however you might have other criteria such as a valid date range. – RobG Sep 04 '20 at 21:49

2 Answers2

1

I'd recommend Moment.js for everything date related in JS

Especially the isValid() method is of interest

console.log("12-12-1212", moment("12-12-1212", 'YYYY-MM-DD', true).format(), moment("12-12-1212", 'YYYY-MM-DD', true).isValid())
console.log("1212-12-12", moment("1212-12-12", 'YYYY-MM-DD', true).format(), moment("1212-12-12", 'YYYY-MM-DD', true).isValid())
console.log("1212-12-1212", moment("1212-12-1212", 'YYYY-MM-DD', true).format(), moment("1212-12-1212", 'YYYY-MM-DD', true).isValid())
console.log('1318874398', moment('1318874398', 'X', true).format(), moment('1318874398', 'X', true).isValid())
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>

In your special case for the code you've written, there are some issues.
The major issue is, that you don't break the switch after successfully testing the regexp2

Then the Date constructor needs the parameter to be in milliseconds, not in seconds.

And of course your regexp2 quantifier is not correct. {13} means exactly 13 appearances of the before. You need {0,13} (or {0,16} if milliseconds are allowed) [Maybe /\d{0,13}(\.\d{0,3)?/]

function createDate(date_string) {
  const regexp = /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/;
  const regexp2 = /^(\d{0,13})?$/; // {0,13} instead of {13}
  let date;
  switch (typeof date_string) {
    case "string":
      if (regexp2.test(date_string)) {
        date = new Date(Number(date_string * 1e3)); // Date constructor need milliseconds
        break; // You forget this break
      }
      if (regexp.test(date_string)) {
        date = new Date(date_string);
      } else {
        return console.log("Invalid Date String");
      }
      break;
    case "undefined":
      date = new Date();
    default:
      return console.log("Unknown Date String");
  }
  return date;
}

console.log(createDate("2020-12-12"))
console.log(createDate("3661"))
yunzen
  • 32,854
  • 11
  • 73
  • 106
  • Thanks so much: Though `date = new Date(Number(date_string * 1e3)); // Milliseconds are not needed ` as it leads to a funny year `Sat, 09 Jan 52647 09:19:08 GMT` when i call `date.toUTCString` – Herman Ceaser Sep 04 '20 at 09:47
  • See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date `An integer value representing the number of milliseconds since January 1, 1970, 00:00:00 UTC` – yunzen Sep 04 '20 at 09:51
  • `moment("12-12-1212").isValid()` is itself not a valid way to test if a Date is valid. It's relying on the built–in parser, so will likely have different results in different implementations, Safari at least treats it as invalid but others may treat it as valid. You should always pass the parse format and include the [*strict* flag](https://momentjs.com/docs/#/parsing/string-format/) if validating strictly: `moment("12-12-1212", 'YYYY-MM-DD', true).isValid()` returns false. – RobG Sep 05 '20 at 00:35
0

There are many questions and answers on how to validate a date.

A "UNIX timestamp" is generally regarded as a number that is seconds since the UNIX epoch, 1970-01-01T00:00:00Z. Javascript has the same epoch, so to convert to an ECMAScript time value, just multiply by 1,000:

let ecmascriptTimeValue = unixTimestamp * 1000;

The Date constructor can be passed a time value to create a Date:

let ecmascritpDate = new Date(unixTimestamp * 1000);

ECMAScript time values can be any number from -8.64e15 to +8.64e15 (as milliseconds, about ±285,426 years), so a simple test of a UNIX timestamp range in seconds is:

let isValid = (value >= -8.64e12 && value <= +8.64e12);

This method will coerce strings to number, so "123123" == 123123. If you want to also ensure it's a number type, then include a typeof test:

let isValid = (typeof value == 'number' && value >= -8.64e12 && value <= +8.64e12);

You might also want to limit the date range using maximum and minimum values.

RobG
  • 142,382
  • 31
  • 172
  • 209