1

In my vue/cli 4/vuex / bootstrap-vue project app I install date picker with custom format, like here https://dbrekalo.github.io/vue-date-pick/examples.html#custom-date-parser

I use moment/moment-timezone in my project, so I do not want to use fecha as in example I have to convert date value from mysql to datepicker format and I have a problem that my converted date for datepicker is 1 day bigger...

I have in my component:

                        <date-pick
                                v-model="editableAd.expire_date_formatted"
                                :format="date_picker_format"
                                :parseDate="parseDate"
                                :formatDate="formatDate"
                                :inputAttributes="{size: 32}"
                        ></date-pick>

...
    import moment from 'moment-timezone'

    console.log('settingsTimeZone::')
    console.log(settingsTimeZone) // it shows Europe/Kiev

    moment.tz.setDefault(settingsTimeZone)

...
    date_picker_format: 'Do MMMM, YYYY',

...
    // setting formated date for dapicker
    this.editableAd.expire_date_formatted = this.formatDate(this.editableAd.expire_date, this.date_picker_format)
...

            formatDate(dateObj) {

                console.log('typeof dateObj::')
                console.log(typeof dateObj)
                console.log(dateObj)  // it has ‘2023-01-19’ value

                if (typeof dateObj === 'string') {
                    dateObj = moment(dateObj, this.date_picker_format)
                }
                console.log('++typeof dateObj::')
                console.log(typeof dateObj)
                console.log(dateObj)

                console.log('RESULT moment(dateObj).format(this.date_picker_format)::')
                console.log(moment(dateObj).format(this.date_picker_format)) // BUT it has ‘20th January, 2023’ value

                return moment(dateObj).format(this.date_picker_format) // returns invalid ‘20th January, 2023’ value which I see in datepicker

What I see in console for dateObj var : https://i.stack.imgur.com/EuW39.jpg

"bootstrap-vue": "^2.1.0",
"font-awesome": "^4.7.0",
"moment": "^2.24.0",
"moment-timezone": "^0.5.27",
"vue": "^2.6.10",
"vue-date-pick": "^1.2.1",

Why error and how it can be fixed?


MODIFIED BLOCK 2:

I removed moment.tz from my project. In /etc/php/7.2/apache2/php.ini I changed

Timezone ='Europe/Uzhgorod'  // That it near my place I live
date.timezone = "Europe/Uzhgorod" 

So my phpinfo has this output:

"Olson" Timezone Database Version   0.system
Timezone Database   internal
Default timezone    Europe/Uzhgorod

I searched how to get a timezone from client browser and found this get client time zone from browser branch and checking :

var timedifference = new Date().getTimezoneOffset();
console.log('timedifference::')
console.log(timedifference)

var rightNow = new Date();
var jan1 = new Date(rightNow.getFullYear(), 0, 1, 0, 0, 0, 0);
var temp = jan1.toGMTString();
var jan2 = new Date(temp.substring(0, temp.lastIndexOf(" ") - 1));
var std_time_offset = (jan1 - jan2) / (1000 * 60 * 60);
console.log('std_time_offset::')
console.log(std_time_offset)


let jstz = require('jstimezonedetect')
let timezone = jstz.determine()
console.log('timezone::')
console.log(timezone)

console.log('===========================')

I have next output: https://i.stack.imgur.com/FUiRy.jpg and again running code when I see date is changed +1 day :

console.log('__')
console.log('__')

console.log('typeof dateObj::')
console.log(typeof dateObj)
console.log(dateObj)

if (typeof dateObj === 'string') {
    dateObj = moment(dateObj, this.date_picker_format)
}
console.log('++typeof dateObj::')
console.log(typeof dateObj)
console.log(dateObj) // it has ‘2023-01-19’ value


console.log('RESULT moment(dateObj).format(this.date_picker_format)::')
console.log(moment(dateObj).format(this.date_picker_format)) // BUT it has ‘20th January, 2023’ value

return moment(dateObj).format(this.date_picker_format)

and what I see in console: https://i.stack.imgur.com/dVQ0V.jpg That is strange that .d has 20 day. What is it? Some day zero based option?

Bernardo Duarte
  • 4,074
  • 4
  • 19
  • 34
Petro Gromovo
  • 1,755
  • 5
  • 33
  • 91

1 Answers1

1

The problem you're having is due to some automatic localization formatting. I too don't get why does this happens, since we are providing only dates, they should be treated as such regardless of our timezone. But to solve this issue we have to read it as UTC with moment.utc() and then format it using your desired format.

From vue-date-pick docs example I've worked out a solution using moment.

var app = new Vue({
  el: '#app',
  components: {
    'date-pick': VueDatePick,
  },
  data: () => ({
    format: 'Do MMMM, YYYY',
    date: '19th January, 2023',
  }),
  methods: {
    parseDate(value) {
      const m = moment.utc(value, this.format);
      return new Date(m.year(), m.month(), m.date());
    },
    formatDate(value) {
      return moment.utc(value).format(this.format);
    }
  }
});
<link href="https://cdn.jsdelivr.net/npm/vue-date-pick@1.2.1/dist/vueDatePick.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-date-pick@1.2.1/dist/vueDatePick.min.js"></script>
<script src="https://momentjs.com/downloads/moment.min.js"></script>
<script src="https://momentjs.com/downloads/moment-timezone.min.js"></script>

<div id='app'>
    <date-pick v-model="date" :format="format" :parse-date="parseDate" :format-date="formatDate"></date-pick>
    
</div>
Bernardo Duarte
  • 4,074
  • 4
  • 19
  • 34
  • I removed from my project and installeded "vue2-daterange-picker": "^0.4.4" and all works ok , not any problem. Maybe actually some automatic localization formatting. I did not add any localization . – Petro Gromovo Feb 16 '20 at 12:24
  • @PetroGromovo I've added a working example with the old package. Have a look at the snippet. – Bernardo Duarte Feb 16 '20 at 23:32
  • @PetroGromovo Your bounty has ended, but I think you can still manually award it though. It's up to you ;D – Bernardo Duarte Feb 17 '20 at 11:38
  • I awarded it. Did n't I ? – Petro Gromovo Feb 17 '20 at 11:43
  • 1
    @PetroGromovo I'm still seeing the bounty banner, don't know ;O, however to award I believe you must manually award now because [the docs](https://stackoverflow.com/help/privileges/set-bounties) "If you do not award the bounty within 24 hours of the bounty period ending, half the bounty value will be automatically awarded to the top voted answer posted after the bounty start, provided it has a score of at least 2." – Bernardo Duarte Feb 17 '20 at 11:52
  • @PetroGromovo Also this "The bounty period lasts 7 days. Bounties must have a minimum duration of at least 1 day. After the bounty ends, there is a grace period of 24 hours to manually award the bounty. **Simply click the bounty award icon next to each answer to permanently award your bounty to the answerer.** (You cannot award a bounty to your own answer.)" from [here](https://stackoverflow.com/help/bounty) – Bernardo Duarte Feb 17 '20 at 11:54
  • @PetroGromovo Done! Thanks for the trust, I'll be glad to help anytime ;D – Bernardo Duarte Feb 17 '20 at 11:55