charliekassel / vuejs-datepicker

A simple Vue.js datepicker component. Supports disabling of dates, inline mode, translations
MIT License
2.61k stars 732 forks source link

Date is off by one day #23

Closed IstvanLovas closed 7 years ago

IstvanLovas commented 7 years ago

Hi!

When i select the date, the output is off by 1 day. I assume it is a timezone issue however i am unable to find any solution. Here is the code:

// In template <datepicker placeholder="Select date of shoot" :value.sync="formInputs.date" :format="format" name="date"

// The data

data() { return { formInputs: { date: new Date() }, format: 'd MMMM yyyy', } }

And the screenshot:

screen shot 2016-10-23 at 15 24 37

I appreciate any help i can get :) Thank You!

skbogner commented 7 years ago

I belive that is midnight your time (but displayed in UTC).

LasseRafn commented 7 years ago

I have this too, one day off.

"2016-12-06T23:00:00.000Z" should be 2016-12-07

skbogner commented 7 years ago

As per my previous comment. If you're in UTC+1 I believe the timestamp:

'2016-12-06T23:00:00.000Z'

corresponds to midnight YOUR TIME: 2016-12-07 24:00:00

mailnike commented 7 years ago

how to address this issue? I am facing same problem. Is there anyway to get client date? also, any suggestions on how to process returned value in VUE.JS (I will be storing that in laravel). I can't store as it is and not sure if string formatting is a good idea.

LasseRafn commented 7 years ago

I discovered that (After reading @skbogner's comment) that this is not really a problem.

How I decided to handle the data (I needed to post it to a url, in Y-m-d format) was this:

const date = new Date(formInputs.date);
let date_for_request = date.getFullYear() + '-'
                                          + ('0' + (date.getMonth()+1)).slice(-2) + '-'
                                          + ('0' + date.getDate()).slice(-2);

HOWEVER I imagine that you do not even need to reformat it, as the outputted format is fine (as skbogner's comment states; it's simply because of timezones)

sjmarve commented 7 years ago

Also having this issue when using v-model attribute. The date is off by one day. And the date is not following the format passed in

charliekassel commented 7 years ago

@sjmarve - The date is output as a Date object - format is only a visual representation in the text input.

mailnike commented 7 years ago

@all - hey guys, I am using this as it is with laravel 5.3 and it doesn't causes any issue. So don't worry if it looks like date is off by a day.

SDJeff commented 7 years ago

It is a bug. The Input shows the correct value but saved at the model is Day minus 1 hour. So if you take your example:

selectedDate: {
                    date: new Date(2016, 9,  16)
                }

<datepicker input-class="input" name="booking_date" :value="selectedDate.date" language="de" placeholder="Buchungsdatum"></datepicker>

Box will Show 16 Okt 2016 and the model is (if inspect it)

selectedDate:Object date:"2016-10-15T22:00:00.000Z"

mailnike commented 7 years ago

@SDJeff try

moment().format('YYYY-MM-DD'),

and have you tried to save this date in the backend? because I agree model shows a different value but once you store this in the backend, correct value will be stored.

I initialized this date to todays date using below code:

invoice_date = moment().format('YYYY-MM-DD');

You can also add or reduce it using moment library.

eg.

moment().add(15, 'days').format('YYYY-MM-DD')
SDJeff commented 7 years ago

The problem is, that javascript returns a date Object as UTC. So you have first to convert it back to your local timezone like it is at the browser if you work with it in the console.

So i added a vuejs2 watch for the v-model field of the DatePicker and format it new with moment like so in my destination field:

watch: { // whenever dateValue in booking_date changes, this function will run booking_date: function (date) { let d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds())); this.currentStamp.booking_date = moment(d).format("YYYY-MM-DD") } },

be sure to import moment.js before: import moment from 'moment';

adrianmejias commented 7 years ago

I came across this issue and ended up setting the date to YYYY/MM/DD instead of YYYY-MM-DD, which corrected the issue

more info here http://stackoverflow.com/a/31732581/221830

raphcadiz commented 7 years ago

I have this the same issue. I formatted it to yyyy-MM-dd. I tried 2012-12-13 I get this instead "2012-12-12T16:00:00.000Z" . I need it to be just '2012-12-13' any fix for this?

javisperez commented 7 years ago

@raphcadiz how are you formatting the date?

raphcadiz commented 7 years ago

@javisperez, I did it like this :format="'yyyy-MM-dd'" I did get the correct format to show but when I bind it to the data I get the other long format I mention above

julesjanssen commented 7 years ago

Another option is adjust the resulting date object with the outcome of (new Date).getTimezoneOffset() (by using setMinutes)

charliekassel commented 7 years ago

@raphcadiz you are recieving the javascript Date object, not a formatted string. With the Date object you can format as you wish.

I am closing this issue as I think this is due to timezones.

hkmsadek commented 3 years ago

this is shit bug and these guys never updated it.. such a shame

ogmo0n commented 11 months ago

I switched to vue-datetime and the fix for that was using the value-zone prop and passing in timezone. :value-zone="Intl.DateTimeFormat().resolvedOptions().timeZone" https://www.npmjs.com/package/vue-datetime Not sure if this is what you want, but it worked for me.