V-calendar: Properly setting date format

Created on 26 Feb 2019  Â·  36Comments  Â·  Source: nathanreyes/v-calendar

I am using version 0.9.7.

I've been struggling to set the date format correctly in my date range picker. Currently this is what I get as values:

date:Object
end:Thu Feb 14 2019 00:00:00 GMT+0100 (Midden-Europese standaardtijd)
start:Tue Feb 12 2019 00:00:00 GMT+0100 (Midden-Europese standaardtijd)

This is way too extensive, I just need YYYY-MM-DD, but how do I go about this? I have tried the date formatter, input formatter, it all does not seem to work.

Most helpful comment

It very easy. You can use like this ---->
:masks="{ input: ['DD/MM/YY']}" in tag v-date-picker. It make change format date for date picker.

All 36 comments

Same problem here, need to get the value as YYYY-MM-DD before sending it to the server

This works for me. V-model the datepicker to a data value and deconstruct it using a computed property.

formattedDate() { return ( this.date.year + "." + this.date.month + "." + this.date.day ); },

It looks like this broke in the newer version. This example uses 0.6.1 and it works

There should just be a format property on the component, nothing with computed/models or anything hacky-like.

Having this issue too.

Hi guys! You can use the libray moment.
moment(string).format('YYYY-MM-DD h:mm:ss');

Right but where? How do we properly initialize the data?

On Jun 4, 2019, at 2:28 PM, George Chaves Pacheco notifications@github.com wrote:

Hi guys! You can use the libray moment.
moment(string).format('YYYY-MM-DD h:mm:ss');

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

@jackmcdade before you send your data.
SendData: function () {
var form = new FormData();
this.formattedDate();
form.append('datainicio', moment(this.selectedDateInicio).format('YYYY-MM-DD h:mm:ss'));
form.append('datafim', moment(this.selectedDateFim).format('YYYY-MM-DD h:mm:ss'));
//Complete your function
}

@georgecpacheco I'm sorry but I have no idea where that is coming from. What's FormData()? What are you appending? This doesn't seem to be related to v-calendar at all.

After more than a month, I'm still stumped how to initialize a date format correctly. Is there anyone I can pay to help sort this out?

Here's a CodePen that shows what @georgecpacheco is talking about.

By the way, @jackmcdade looking forward to Statamic V3 =D

I have the same problem. I tried using computed property in @grantholle's example to format the input as YYYY-MM-DD. Check it out here.

But, in the above example, v-date-picker is unable to display the formatted date in the UI.
I tried nesting a HTML input inside v-date-picker. Now, I see the browser's inbuilt date picker as well.

It would be great if we can get the desired format by using the locale prop.

Is this issue fixed? Because I am still not able to set the desired date formats as property on v-calendar

I found this in the documentation.
https://vcalendar.io/api/defaults.html#masks

They want you to pass in a "masks" attribute which is an object like the following

{
        title: "MMMM YYYY",
        weekdays: "W",
        navMonths: "MMM",
        input: ["L", "YYYY-MM-DD", "YYYY/MM/DD"],
        dayPopover: "WWW, MMM D, YYYY",
        data: ["L", "YYYY-MM-DD", "YYYY/MM/DD"]
}

I would assume that the data or input attribute would be what formats the v-model bind value, but it doesn't work for me.
Formatting the title and navMonths work just fine however.

Any guidance would be greatly appreciated.

It very easy. You can use like this ---->
:masks="{ input: ['DD/MM/YY']}" in tag v-date-picker. It make change format date for date picker.

It very easy. You can use like this ---->
:masks="{ input: ['DD/MM/YY']}" in tag v-date-picker. It make change format date for date picker.

This worked for me, thanks!

For me, not working, I am still getting this when outputting "field.calendar"
Thu Mar 12 2020 00:00:00 GMT+0100 (Central European Standard Time)

 <v-date-picker :masks="{ input: ['DD/MM/YY']}"  mode="single" v-model="field.calendar" ref="picker" is-inline></v-date-picker>

I'm having the same issue.
We don't seem to have control on how the data is formatted.

Looking at documentation, the natural props to control this would be:

<date-picker title-position="right" mode='range' v-model="dateRange" :masks="{ input: ['YYYY-MM-DD'], data: ['YYYY-MM-DD']}"/>

the property input of masks prop works but data has no effect.

As mentioned above by @georgecpacheco the work around is to add a computed prop and use an external library like moment.js or date-fns.

This is strange to me, why not keep the data as javascript date objects and allow us to parse them easily using DateObject.day, DateObject.month+1 , DateObject.year etc?

I am using vue.js with Laravel, I ended up using Moment.js like this:

Edit pages(when you load back the data into the calendar from Mysql)

this.calendar = this.$moment(this.whatever).toDate();

And using this to send the date back to Laravel from vue.js:
formData.append('fieldName', this.$moment(this.field.fieldName).format('YYYY-MM-DD'));

It works fine with this. I had to do this for all my CRUDs.

Hope this helps,

@FreddyCrugger yes, it is a solution but IMHO opinion, we're increasing overhead for something that really should be built in by default.
(having said that, this is a great package and I do appreciate all the hard work gone into it)

Also, FYI, check out date-fns substantially smaller than moment.js

I know what you mean...... I had to, unfortunately, move ahead with my project and found a solution quickly :-) But yes this should work from the calendar itself for sure.

Here is my work around without external library, however because dates are such a PITA to work with in any language, please use with caution :) I'm using the date range picker but would work for the date picker too.

data () {
    return {
        dateRange: {
            start: new Date('04-01-2020'),
            end: new Date()
        }
    }
},
computed: {
    formattedStart: function(){
        let parsed = new Date(Date.parse(this.dateRange.start));
        let year = parsed.getFullYear();
        let month = ('0' + (parsed.getMonth()+1)).slice(-2); //force leading zero for month
        let day = ('0' + parsed.getDate()).slice(-2); //force leading zero for day
        return `${year}-${month}-${day}`;
    },
    formattedEnd: function(){
        let parsed = new Date(Date.parse(this.dateRange.end));
        let year = parsed.getFullYear();
        let month = ('0' + (parsed.getMonth()+1)).slice(-2); //force leading zero for month
        let day = ('0' + parsed.getDate()).slice(-2); //force leading zero for day
        return `${year}-${month}-${day}`;
    }
},

Thanks for sharing, I will save your code and refactor my current project. thanks again!

I'm trying to understand what the root issue/request is here. The masks prop should properly handle formatting the dates for the title, weekdays and dayPopovers. It also parses input by the user in the input field for v-date-picker and also parses dates that are specified for attributes.

v-date-picker will always emit Javascript dates as the value (mode = 'single'), as an object with start and end dates (mode = 'range') or as an array of dates (mode = 'multiple'). All of these dates are Javascript dates. Is the request to be able to pass a string as the value and also emit formatted string in the input event? Effectively this would allow you to v-model to a string.

Also, here is an example for a way you can accomplish the v-model using a string using only what v-calendar provides. No need for moment.

It utilizes the Locale object that the plugin uses for formatting and parsing dates. Obviously this is more difficult than just having the plugin manage it itself so I will consider the best way to accomplish that.

Note: this only works for 1.0.5 and later using the new Locale class that gets exported. Before that you need to get the $locale property on the date picker component itself, but that is bit more verbose.

Hey @nathanreyes
When inspecting the value of the bound data prop the date (or dates) are represented in string format of a Javascript date, we were after away of formatting it.

Your example provided does exactly that, thank you.

Would it not make sense that providing a prop as such:

:masks="{ input: ['YYYY-MM-DD'], data: ['YYYY-MM-DD']}"

Would then format the date (on the data property) as your example does when accessing it?

Thanks for the example, from my side I feel like this issue has a resolution.

If we use v-model like v-model="meeting.date" and then when we want to send the whole meeting object to the server as it is, the suggested solution doesn't seem to work.

For example, if I select 2020-01-01 for a date picker, it sends meeting object with a datetime "2019-12-31T17:00:00.000Z" instead.

And if we edit the meeting.date value, the datepicker itself could break, since it is linked to that value.

Therefore, it would be really convenient if we could define the output format for it, so when I would change the date in the datepicker, it would set the model's value based on the format supplied.

One way currently to surround that is to do like

let sendMeeting = clone(this.meeting);
sendMeeting.date = moment(sendMeeting.date).format('YYYY-MM-DD');
axios.post('xxx', { meeting: sendMeeting })

But then we need to change the output date format everywhere where it is needed like that.
Note that we can't edit the this.meeting.date value straight, since it will then break the whole date input.

@nviitala this code below is enough
locale.format(val, mask)

I have solution:
write function format:
formatDate (date) { let newDate = date return ( newDate.getFullYear() + '-' + ('0' + (newDate.getMonth() + 1)).slice(-2) + '-' + ('0' + newDate.getDate()).slice(-2) ) } }
// return YYYY-MM-DD
then:
let timeUTC = new Date(this.formatDate(this.birthDt) + ' UTC')

in v-date-picker use <v-date-picker v-model="birthDt" :locale="{ id: 'vi'}" />

I tried and succeeded
sorry, I not good English :(

Hey guys !

Anyone succeed to obtain a correct date format (YYYY-MM-DD) ? I tried all possibility of the documentation and my v-model is always formatted like this : "Fri May 15 2020 00:00:00 GMT+0200 (heure d’été d’Europe centrale)" ...

Also, i need to set a date when my v-model is fill by an API call, but i just can't. I don't understand why is it so hard to do this simple operation ...

Please help me :)

Did you try my solution

Doesn't work for what i want to do. I can format the output of the v-date-picker, with library such as MomentJS.

But my problem is that i fetch a date from an API with 'YYYY-MM-DD' format and i want to set the v-date-picker with this date. I don't understand why using locale with mask doesn't work ...

EDIT : the solution give by @nathanreyes seems to be the right one. Now my problem is that my v-calendar is in version "1.0.0-beta.22". If i try to upgrade the version (using yarn), i have an error with the import. So i will need to "get the $locale property on the date picker component itself", but i don't know how to do this ...

EDIT 2: I found how to get the $locale property from date picker, but it can't be use in a computed property ... so i'm stuck, i need to find how to get 1.0.6 version of the component with yarn. The problem i have when i install the last version of plugin is the same that is described in this issue #502

Someone has a better fix for this problem ?
I use datepicker many times in my application and I prefer to set a default configuration for all inputs.

There should just be a format property on the component, nothing with computed/models or anything hacky-like.
I am absolutely accord with that

https://vcalendar.io/api/defaults.html#masks
I tried the property masks in default and input configuration, but data doesn't work.
:masks="{ data: ['DD/MM/YY']}"
The v-model always retains this format Thu Jul 02 2020 00:00:00 GMT+0200 (heure d’été d’Europe centrale)

https://codesandbox.io/s/date-picker-parse-format-4nx9r?file=/src/App.vue
This solution is perfect for single datepicker but isn't suitable for many datepicker, is WET coding.

_Version 1.0.8_

@rifton007
I solve it just useing moment js

1- In your template you should use v-model to save the date from v-date-picker component

2- Import moment js to give the format that you want:
import moment from 'moment'

3- Define a filter like this:

filters: {
date_format (date) {
return moment(String(date)).format('DD-MM-YYYY')
}
},

3- Print your date:
yourDate | date_format

Let me know if works for you

Based on Nathan example (thanks a lot for it!), i ended up to succeed to solve the problem. I just changed a bit to suit to my needs (maybe it will help some people).

I create 2 masks:
const mask = "YYYY-MM-DD";
const mask_DISPLAY = "L";
One to display nicely in the locale, one to register (to mysql in my case).

Then i do this in the data:
masks: {
input: mask_DISPLAY,
data: mask,
}

and for the computed property:
value: {
get() {
return this.myvalue ? locale.parse(this.myvalue, mask_DISPLAY) : null;
},
set(val) {
this.myvalue = val ? locale.format(val, mask) : "";
}
}

And it seems to work perfectly well, thanks a lot for your work @nathanreyes !

For anyone still interested, 2.0 introduces the model-config prop for binding directly to strings with a given format.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hanhtv204 picture hanhtv204  Â·  4Comments

rcascante picture rcascante  Â·  3Comments

eafomi4ev picture eafomi4ev  Â·  3Comments

chrisnetonline picture chrisnetonline  Â·  3Comments

octaviangrozman picture octaviangrozman  Â·  4Comments