Vuepic / vue-datepicker

Datepicker component for Vue 3
https://vue3datepicker.com
MIT License
1.46k stars 144 forks source link

UTC + Daylight Saving Time adds 1 hour to input #173

Closed Marcel-Sass closed 1 year ago

Marcel-Sass commented 1 year ago

Describe the bug When i use the utc="preserve" property. All inputs will get 1 hour added after selecting a date in the wintertime.

To Reproduce Steps to reproduce the behavior: I use the following component:

<template>
    <div class="mt-1">
        <Datepicker
            utc="preserve"
            :id="id?id:name"
            :name="name"
            v-model="date"
            :locale="lang"
            :format="format"
            :range="range"
            :timePicker="timePicker"
            :clearable="!not_clearable"
            :startTime="range?[{ hours: 9, minutes: 0 }, { hours: 10, minutes: 0 }]:{ hours: 0, minutes: 0 }"
            :selectText="$t('Select')"
            :cancelText="$t('Cancel')"
            :nowButtonLabel="$t('Now')"
            :weekNumName="$t('W')"
            :placeholder="$t(placeholder)"
            autocomplete="off"
            :startDate="timePicker?'':startDate"
            :enable-time-picker="!onlyDate"
        ></Datepicker>
    </div>
</template>

<script>
import Datepicker from '@vuepic/vue-datepicker';
import '@vuepic/vue-datepicker/dist/main.css'
import {mapState} from "vuex";
import {dateFormatsUnicode} from "../../models/dateFormats";
import dayjs from "dayjs";
import utc from "dayjs/plugin/utc";
dayjs.extend(utc)

export default {
    name: "VDatepicker",
    components: { Datepicker },
    props: {
        modelValue: {},
        error: {},
        id: {},
        name: {},
        range: {
            type: Boolean
        },
        timePicker: {
            type: Boolean
        },
        onlyDate: {
            type: Boolean
        },
        not_clearable: {
            type: Boolean
        },
        placeholder: {
            default: 'Select Date'
        },
    },
    emits: ['update:modelValue', 'change'],
    data() {
        return {

        };
    },
    mounted() {
    },
    computed: {
        ...mapState(['lang']),
        date: {
            get() {
                if (Array.isArray(this.modelValue) && !this.modelValue[0] && !this.modelValue[1]) {
                    return null;
                }
                return this.modelValue;
            },
            set(newValue) {
                // fix for summertime/wintertime
                if (dayjs(newValue).utc().$d.getTimezoneOffset() > dayjs(newValue).utc().add(6, 'month').$d.getTimezoneOffset()) {
                    newValue = dayjs(newValue).utc().subtract(1, 'hour').toISOString();
                }
                this.$emit('update:modelValue', newValue);
                this.$emit('change', newValue);
            }
        },
        format: {
            get() {
                if (this.timePicker) {
                    if(dateFormatsUnicode[this.lang]) {
                        return dateFormatsUnicode[this.lang].time;
                    }
                    return dateFormatsUnicode['de'].time;
                }
                if (this.onlyDate) {
                    if(dateFormatsUnicode[this.lang]) {
                        return dateFormatsUnicode[this.lang].date;
                    }
                    return dateFormatsUnicode['de'].date;
                }
                if(dateFormatsUnicode[this.lang]) {
                    return dateFormatsUnicode[this.lang].datetime;
                }
                return dateFormatsUnicode['de'].datetime;
            },
        },
        startDate: {
            get() {
                if (Array.isArray(this.date) && this.date[0]) {
                  return this.date[0];
                } else if (!Array.isArray(this.date) && this.date) {
                    return this.date;
                }
                return new Date();
            },
        },
    },
}
</script>

<style scoped>

</style>

As you can see i have implemented a workaround in the computed property "date". Which you have to remove to reproduce the problem.

Expected behavior I want the time to be exactly what the user has selected as i want to calculate the timezone changes on a later time.

Desktop & mobile (please complete the following information):

Jasenkoo commented 1 year ago

In that case you want to use just a boolean, since preserve will convert local to utc, and true will convert UTC to local. You can always just work with local and convert it later when you process data.