Home > Net >  Is there a way to cast a string of only hh:mm to Date in Javascript
Is there a way to cast a string of only hh:mm to Date in Javascript

Time:05-11

I have a business hours object in a mongoose schema that represent a date. I'm passing a json object and retrieving the to parse to Date as string. I wonder if you can or if it will be better to represent it as another type of object. Error I get when passing like this is: validation failed: business.businessHours.monday.startTime: Cast to date failed for value "08:00" (type string)

A work around would be setters which will add current date with hours and minutes:

date.setHours(08);
date.setMinutes(30);

I feel like there is a better way to this. Is there a way to pass a date object in json?

my json is:

{
  ...,
  "businessHours":{
            "monday": {
                "startTime": "08:00",
                "endTime": "18:30"
            },
            "tuesday": {
                "startTime": "08:00",
                "endTime": "18:30"
            },
            "wednesday": {
                "startTime": "08:00",
                "endTime": "18:30"
            },
            "thursday": {
                "startTime": "08:00",
                "endTime": "18:30"
            },
            "friday": {
                "startTime": "08:00",
                "endTime": "18:30"
            },
            "saturday": {
                "startTime": null,
                "endTime": null
            },
            "sunday": {
                "startTime": null,
                "endTime": null
            }
        }
}

The schema looks like this:

const sellerSchema = new mongoose.Schema({
  user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User",
    unique: true,
  },
  ...,
business: {
  businessHours: {
    monday: {
      startTime: {
        type: Date,
      },
      endTime: {
        type: Date,
      },
    },
    tuesday: {
      startTime: {
        type: Date,
      },
      endTime: {
        type: Date,
      },
    },
    wednesday: {
      startTime: {
        type: Date,
      },
      endTime: {
        type: Date,
      },
    },
    thursday: {
      startTime: {
        type: Date,
      },
      endTime: {
        type: Date,
      },
    },
    friday: {
      startTime: {
        type: Date,
      },
      endTime: {
        type: Date,
      },
    },
    saturday: {
      startTime: {
        type: Date,
      },
      endTime: {
        type: Date,
      },
    },
    sunday: {
      startTime: {
        type: Date,
      },
      endTime: {
        type: Date,
      },
    },
  },
}

I know I can convert it before I save it, but is there a way to parse a string with only hh:mm to date? I can't seem to find a way, or would it be better to just represent it as a different object and what object would be the ideal for this occasion.

or should I have a schema like:

I need the hour and minutes for future logic.

const sellerSchema = new mongoose.Schema({
  ...,
  business: {
    businessHours: {
      monday: {
        startTime: Number, //which will be represented as HHMM
        endTime: Number, //which will be represented as HHMM
      },
    },
  },
});

Thank you

CodePudding user response:

It does not make a big difference whether you use values like "18:30" or 1830. One is a bad as the other one.

Values like "18:30" are strings, you cannot cast them into a Date. If you like to do this, then you must have a full date/time string, e.g. "2022-05-06T18:30:00". However, you should never store date values as string, it's a design flaw. Store always proper Date objects!

Using weekday names is also a bad idea, MongoDB does not support (localized) weekday names natively. It's also a poor design to have dynamic field names.

I would suggest this one:

{ 
   businessHours: [
      { dayOfWeek: 1, startHour: 8, startMinute: 0, endHour: 18, endMinute: 30 },
      { dayOfWeek: 2, startHour: 8, startMinute: 0, endHour: 18, endMinute: 30 },
      ...
      { dayOfWeek: 5, startHour: 8, startMinute: 0, endHour: 18, endMinute: 30 }
   ] 
}

According to ISO-8601 weeks start on Monday, thus dayOfWeek: 1 means Monday.

Then you can create easily Date values from it, for example like this:

{
    $dateFromParts : {
        'isoWeekYear': {$isoWeekYear: "$$NOW"}, 
        'isoWeek': {$isoWeek: "$$NOW"}, 
        'isoDayOfWeek': "$dayOfWeek",
        'hour': "$startHour", 
        'minute': "$startMinute"       
    }
}

If you use weekday names, then you would have to deal with $switch or you need a 3rd party library like moment.js, luxon or Day.js.

  • Related