Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VueJS: How to bind a datetime?

Tags:

vuejs2

I receive from a WebAPI a JSON object that has this property:

"BirthDate": "2018-02-14T15:24:17.8177428-03:00",

the HTML:

<input type="date" v-model="BirthDate" />

I bind that object using VueJS, but VueJS give this message in the console:

The specified value "2018-02-14T15:24:17.8177428-03:00" does not conform to the required format, "yyyy-MM-dd".

On this case the only relevant part is 2018-02-14, I can discard the other information.

I tried to create a Two Way filter to convert that Date Time to the required format but did not have success. See VueJS two way filter

How can I convert and bind that Date/Time format to the required Date Format of the HTML date input ?

like image 916
Tony Avatar asked Feb 14 '18 18:02

Tony


3 Answers

Considering myDate is your property, you can use:

<input type="date" :value="myDate && myDate.toISOString().split('T')[0]"
                   @input="myDate = $event.target.valueAsDate">

Since v-model is only syntactic sugar to :value and @input, you can use them instead. In this case, we used and changed them a little (to format the String that is the output of the date input to a Date object and vice-versa).

Check demo and caveats below.

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!',
    myDate: new Date('2011-04-11T10:20:30Z')
  },
  methods: {
    setMyDateToToday() {
        this.myDate = new Date();
    },
    addADayToMyDate() {
      if (this.myDate) // as myDate can be null
        // you have to set the this.myDate again, so vue can detect it changed
        // this is not a caveat of this specific solution, but of any binding of dates
        this.myDate = new Date(this.myDate.setDate(this.myDate.getDate() + 1));
    },
  }
});
// Notes:
// We use `myDate && myDate.toISOString().split('T')[0]` instead
// of just `myDate.toISOString().split('T')[0]` because `myDate` can be null.

// the date to string conversion myDate.toISOString().split('T')[0] may
// have timezone caveats. See: https://stackoverflow.com/a/29774197/1850609
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <p>{{ message }}</p>

  <input type="date" :value="myDate && myDate.toISOString().split('T')[0]"
                     @input="myDate = $event.target.valueAsDate">

  <p>
  <code>
  myDate: {{ myDate }}</code>
  </p>

  <button @click="setMyDateToToday">Set date one to today</button>
  <button @click="addADayToMyDate">Add a day to my date</button>
</div>
like image 124
acdcjunior Avatar answered Oct 18 '22 18:10

acdcjunior


i think this not related to vueJs , the input type="date" expected a date in YYYY-MM-DD format, or empty see here : https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date,

it would be better if you split date object as date and time field

like image 43
Taha Azzabi Avatar answered Oct 18 '22 20:10

Taha Azzabi


Correction to @acdcjunior in that this shouldn't be off by one day

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!',
    myDate: new Date('2011-04-11T10:20:30Z')
  },
  methods: {
    setMyDateToToday() {
        this.myDate = new Date();
    },
    addADayToMyDate() {
      if (this.myDate) // as myDate can be null
        // you have to set the this.myDate again, so vue can detect it changed
        // this is not a caveat of this specific solution, but of any binding of dates
        this.myDate = new Date(this.myDate.setDate(this.myDate.getDate() + 1));
    },
    getDateClean(currDate) {
        // need to convert to UTC to get working input filter
        console.log(currDate);
        let month = currDate.getUTCMonth() + 1;
        if (month < 10) month = "0" + month;
        let day = currDate.getUTCDate();
        if (day < 10) day = "0" + day;
        const dateStr =
            currDate.getUTCFullYear() + "-" + month + "-" + day + "T00:00:00";
        console.log(dateStr);
        const d = new Date(dateStr);
        console.log(d);
        return d;
    }
  }
});
// Notes:
// We use `myDate && myDate.toISOString().split('T')[0]` instead
// of just `myDate.toISOString().split('T')[0]` because `myDate` can be null.

// the date to string conversion myDate.toISOString().split('T')[0] may
// have timezone caveats. See: https://stackoverflow.com/a/29774197/1850609
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <p>{{ message }}</p>

  <input type="date" :value="myDate && myDate.toISOString().split('T')[0]"
                     @input="myDate = getDateClean($event.target.valueAsDate)">

  <p>
  <code>
  myDate: {{ myDate }}</code>
  </p>

  <button @click="setMyDateToToday">Set date one to today</button>
  <button @click="addADayToMyDate">Add a day to my date</button>
</div>
like image 1
lastlink Avatar answered Oct 18 '22 20:10

lastlink