From e725c85f984e7a8102dfc0a5e130205f793869c2 Mon Sep 17 00:00:00 2001 From: Henrique Melhado Date: Tue, 19 Feb 2019 17:18:22 -0300 Subject: [PATCH 1/2] fix DST (Daylight Saving Time) --- dev/package.json | 6 ++-- dev/src/app/home/home.page.html | 2 ++ dev/src/demos/demos.module.ts | 4 +++ .../components/calendar.component.ts | 4 +-- .../components/calendar.modal.ts | 2 +- .../components/month-picker.component.ts | 6 ++-- .../services/calendar.service.ts | 30 +++++++++++-------- src/components/calendar.component.ts | 4 +-- src/components/calendar.modal.ts | 2 +- src/components/month-picker.component.ts | 6 ++-- src/services/calendar.service.ts | 30 +++++++++++-------- 11 files changed, 58 insertions(+), 38 deletions(-) diff --git a/dev/package.json b/dev/package.json index a31ba75da..90e8b08f4 100644 --- a/dev/package.json +++ b/dev/package.json @@ -24,10 +24,12 @@ "@ionic-native/splash-screen": "5.0.0-beta.22", "@ionic-native/status-bar": "5.0.0-beta.22", "@ionic/angular": "4.0.0-rc.0", + "@types/moment-timezone": "^0.5.10", "core-js": "^2.5.7", + "moment": "^2.23.0", + "moment-timezone": "^0.5.23", "rxjs": "6.3.3", - "zone.js": "^0.8.26", - "moment": "^2.23.0" + "zone.js": "^0.8.26" }, "devDependencies": { "@angular/cli": "~7.1.4", diff --git a/dev/src/app/home/home.page.html b/dev/src/app/home/home.page.html index 737405549..1d80f4490 100644 --- a/dev/src/app/home/home.page.html +++ b/dev/src/app/home/home.page.html @@ -15,6 +15,7 @@

modal mode

+ @@ -25,4 +26,5 @@

component mode

+ \ No newline at end of file diff --git a/dev/src/demos/demos.module.ts b/dev/src/demos/demos.module.ts index 9ee01483d..628e6ea7b 100644 --- a/dev/src/demos/demos.module.ts +++ b/dev/src/demos/demos.module.ts @@ -8,10 +8,12 @@ import { DemoModalMultiComponent } from './demo-modal-multi'; import { DemoModalRangeComponent } from './demo-modal-range'; import { DemoModalDisableWeekComponent } from './demo-modal-disable-week'; import { DemoModalLocaleComponent } from './demo-modal-locale'; +import { DemoModalDstComponent } from './demo-modal-dst'; import { DemoModalCustomStyleComponent } from './demo-modal-custom-style'; import { DemoModalDefaultScrollComponent } from './demo-modal-default-scroll'; import { DemoModalConfigDaysComponent } from './demo-modal-config-days'; import { DemoBasicComponent } from './demo-basic'; +import { DemoDstComponent } from './demo-dst'; import { FormsModule } from '@angular/forms'; import { DemoMultiComponent } from './demo-multi'; import { DemoRangeComponent } from './demo-range'; @@ -30,10 +32,12 @@ const COMPONENTS = [ SubHeaderCalendarModal, DemoModalDisableWeekComponent, DemoModalLocaleComponent, + DemoModalDstComponent, DemoModalCustomStyleComponent, DemoModalDefaultScrollComponent, DemoModalConfigDaysComponent, DemoBasicComponent, + DemoDstComponent, DemoMultiComponent, DemoRangeComponent, DemoOptionsComponent, diff --git a/dev/src/ion2-calendar/components/calendar.component.ts b/dev/src/ion2-calendar/components/calendar.component.ts index c42123c2b..e6b101d9a 100755 --- a/dev/src/ion2-calendar/components/calendar.component.ts +++ b/dev/src/ion2-calendar/components/calendar.component.ts @@ -140,7 +140,7 @@ export class CalendarComponent implements ControlValueAccessor, OnInit { ngOnInit(): void { this.initOpt(); - this.monthOpt = this.createMonth(new Date().getTime()); + this.monthOpt = this.createMonth(moment().valueOf()); } getViewDate() { @@ -337,7 +337,7 @@ export class CalendarComponent implements ControlValueAccessor, OnInit { if (this._calendarMonthValue[0]) { this.monthOpt = this.createMonth(this._calendarMonthValue[0].time); } else { - this.monthOpt = this.createMonth(new Date().getTime()); + this.monthOpt = this.createMonth(moment().valueOf()); } } } diff --git a/dev/src/ion2-calendar/components/calendar.modal.ts b/dev/src/ion2-calendar/components/calendar.modal.ts index 2b52c7835..f4350b3aa 100755 --- a/dev/src/ion2-calendar/components/calendar.modal.ts +++ b/dev/src/ion2-calendar/components/calendar.modal.ts @@ -310,7 +310,7 @@ export class CalendarModal implements OnInit, AfterViewInit { if (!isAfter) return -1; if (this.showYearPicker) { - startDate = moment(new Date(this.year, 0, 1)); + startDate = moment([this.year, 0, 1]); } return defaultScrollTo.diff(startDate, 'month'); diff --git a/dev/src/ion2-calendar/components/month-picker.component.ts b/dev/src/ion2-calendar/components/month-picker.component.ts index c49dc5eee..f49ff1d4e 100644 --- a/dev/src/ion2-calendar/components/month-picker.component.ts +++ b/dev/src/ion2-calendar/components/month-picker.component.ts @@ -2,13 +2,15 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { CalendarMonth } from '../calendar.model'; import { defaults } from '../config'; +import * as moment from 'moment'; + @Component({ selector: 'ion-calendar-month-picker', styleUrls: ['./month-picker.component.scss'], template: `
@@ -22,7 +24,7 @@ export class MonthPickerComponent { color = defaults.COLOR; @Output() select: EventEmitter = new EventEmitter(); - _thisMonth = new Date(); + _thisMonth = moment(); _monthFormat = defaults.MONTH_FORMAT; @Input() diff --git a/dev/src/ion2-calendar/services/calendar.service.ts b/dev/src/ion2-calendar/services/calendar.service.ts index 0df20853c..e0cb1893b 100644 --- a/dev/src/ion2-calendar/services/calendar.service.ts +++ b/dev/src/ion2-calendar/services/calendar.service.ts @@ -10,6 +10,7 @@ import { DayConfig, } from '../calendar.model'; import { defaults, pickModes } from '../config'; +import { Moment } from "moment"; const isBoolean = (input: any) => input === true || input === false; @@ -84,17 +85,17 @@ export class CalendarService { } createOriginalCalendar(time: number): CalendarOriginal { - const date = new Date(time); - const year = date.getFullYear(); - const month = date.getMonth(); - const firstWeek = new Date(year, month, 1).getDay(); + const date = moment(time); + const year = date.year(); + const month = date.month(); + const firstWeek = moment([year, month, 1]).day(); const howManyDays = moment(time).daysInMonth(); return { year, month, firstWeek, howManyDays, - time: new Date(year, month, 1).getTime(), + time: moment([year, month, 1]).valueOf(), date: new Date(time), }; } @@ -121,7 +122,7 @@ export class CalendarService { } } else if (_rangeBeg > 0 && _rangeEnd === 0) { if (!opt.canBackwardsSelected) { - let _addTime = _time.add(1, 'day'); + let _addTime = this._momentDayModify(_time, 1); isBetween = !_addTime.isAfter(_rangeBeg); } else { isBetween = false; @@ -136,7 +137,7 @@ export class CalendarService { _disable = disableWee || isBetween; } - let title = new Date(time).getDate().toString(); + let title = date.date().toString(); if (dayConfig && dayConfig.title) { title = dayConfig.title; } else if (opt.defaultTitle) { @@ -169,7 +170,7 @@ export class CalendarService { let days: Array = new Array(6).fill(null); let len = original.howManyDays; for (let i = original.firstWeek; i < len + original.firstWeek; i++) { - let itemTime = new Date(original.year, original.month, i - original.firstWeek + 1).getTime(); + let itemTime = moment([original.year, original.month, i - original.firstWeek + 1]).valueOf(); days[i] = this.createCalendarDay(itemTime, opt); } @@ -197,9 +198,7 @@ export class CalendarService { if (!(_booleanMap.length % 7 === 0 && _booleanMap[_booleanMap.length - 1])) { for (endOffsetIndex; endOffsetIndex < days.length + (endOffsetIndex % 7); endOffsetIndex++) { - const dayAfter = moment(days[endOffsetIndex - 1].time) - .clone() - .add(1, 'd'); + const dayAfter = this._momentDayModify(moment(days[endOffsetIndex - 1].time).clone(), 1); days[endOffsetIndex] = this.createCalendarDay(dayAfter.valueOf(), opt, thisMonth); } } @@ -214,8 +213,8 @@ export class CalendarService { createMonthsByPeriod(startTime: number, monthsNum: number, opt: CalendarModalOptions): Array { let _array: Array = []; - let _start = new Date(startTime); - let _startMonth = new Date(_start.getFullYear(), _start.getMonth(), 1).getTime(); + let _start = moment(startTime); + let _startMonth = moment([_start.year(), _start.month(), 1]).valueOf(); for (let i = 0; i < monthsNum; i++) { let time = moment(_startMonth) @@ -261,4 +260,9 @@ export class CalendarService { date: _moment.date(), }; } + + // BUG fix: https://stackoverflow.com/a/24919934 + private _momentDayModify(date: Moment, days: number): Moment { + return moment.unix(date.unix() + (86400 * days)); + } } diff --git a/src/components/calendar.component.ts b/src/components/calendar.component.ts index c42123c2b..e6b101d9a 100755 --- a/src/components/calendar.component.ts +++ b/src/components/calendar.component.ts @@ -140,7 +140,7 @@ export class CalendarComponent implements ControlValueAccessor, OnInit { ngOnInit(): void { this.initOpt(); - this.monthOpt = this.createMonth(new Date().getTime()); + this.monthOpt = this.createMonth(moment().valueOf()); } getViewDate() { @@ -337,7 +337,7 @@ export class CalendarComponent implements ControlValueAccessor, OnInit { if (this._calendarMonthValue[0]) { this.monthOpt = this.createMonth(this._calendarMonthValue[0].time); } else { - this.monthOpt = this.createMonth(new Date().getTime()); + this.monthOpt = this.createMonth(moment().valueOf()); } } } diff --git a/src/components/calendar.modal.ts b/src/components/calendar.modal.ts index 2b52c7835..f4350b3aa 100755 --- a/src/components/calendar.modal.ts +++ b/src/components/calendar.modal.ts @@ -310,7 +310,7 @@ export class CalendarModal implements OnInit, AfterViewInit { if (!isAfter) return -1; if (this.showYearPicker) { - startDate = moment(new Date(this.year, 0, 1)); + startDate = moment([this.year, 0, 1]); } return defaultScrollTo.diff(startDate, 'month'); diff --git a/src/components/month-picker.component.ts b/src/components/month-picker.component.ts index c49dc5eee..f49ff1d4e 100644 --- a/src/components/month-picker.component.ts +++ b/src/components/month-picker.component.ts @@ -2,13 +2,15 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { CalendarMonth } from '../calendar.model'; import { defaults } from '../config'; +import * as moment from 'moment'; + @Component({ selector: 'ion-calendar-month-picker', styleUrls: ['./month-picker.component.scss'], template: `
@@ -22,7 +24,7 @@ export class MonthPickerComponent { color = defaults.COLOR; @Output() select: EventEmitter = new EventEmitter(); - _thisMonth = new Date(); + _thisMonth = moment(); _monthFormat = defaults.MONTH_FORMAT; @Input() diff --git a/src/services/calendar.service.ts b/src/services/calendar.service.ts index 0df20853c..e0cb1893b 100644 --- a/src/services/calendar.service.ts +++ b/src/services/calendar.service.ts @@ -10,6 +10,7 @@ import { DayConfig, } from '../calendar.model'; import { defaults, pickModes } from '../config'; +import { Moment } from "moment"; const isBoolean = (input: any) => input === true || input === false; @@ -84,17 +85,17 @@ export class CalendarService { } createOriginalCalendar(time: number): CalendarOriginal { - const date = new Date(time); - const year = date.getFullYear(); - const month = date.getMonth(); - const firstWeek = new Date(year, month, 1).getDay(); + const date = moment(time); + const year = date.year(); + const month = date.month(); + const firstWeek = moment([year, month, 1]).day(); const howManyDays = moment(time).daysInMonth(); return { year, month, firstWeek, howManyDays, - time: new Date(year, month, 1).getTime(), + time: moment([year, month, 1]).valueOf(), date: new Date(time), }; } @@ -121,7 +122,7 @@ export class CalendarService { } } else if (_rangeBeg > 0 && _rangeEnd === 0) { if (!opt.canBackwardsSelected) { - let _addTime = _time.add(1, 'day'); + let _addTime = this._momentDayModify(_time, 1); isBetween = !_addTime.isAfter(_rangeBeg); } else { isBetween = false; @@ -136,7 +137,7 @@ export class CalendarService { _disable = disableWee || isBetween; } - let title = new Date(time).getDate().toString(); + let title = date.date().toString(); if (dayConfig && dayConfig.title) { title = dayConfig.title; } else if (opt.defaultTitle) { @@ -169,7 +170,7 @@ export class CalendarService { let days: Array = new Array(6).fill(null); let len = original.howManyDays; for (let i = original.firstWeek; i < len + original.firstWeek; i++) { - let itemTime = new Date(original.year, original.month, i - original.firstWeek + 1).getTime(); + let itemTime = moment([original.year, original.month, i - original.firstWeek + 1]).valueOf(); days[i] = this.createCalendarDay(itemTime, opt); } @@ -197,9 +198,7 @@ export class CalendarService { if (!(_booleanMap.length % 7 === 0 && _booleanMap[_booleanMap.length - 1])) { for (endOffsetIndex; endOffsetIndex < days.length + (endOffsetIndex % 7); endOffsetIndex++) { - const dayAfter = moment(days[endOffsetIndex - 1].time) - .clone() - .add(1, 'd'); + const dayAfter = this._momentDayModify(moment(days[endOffsetIndex - 1].time).clone(), 1); days[endOffsetIndex] = this.createCalendarDay(dayAfter.valueOf(), opt, thisMonth); } } @@ -214,8 +213,8 @@ export class CalendarService { createMonthsByPeriod(startTime: number, monthsNum: number, opt: CalendarModalOptions): Array { let _array: Array = []; - let _start = new Date(startTime); - let _startMonth = new Date(_start.getFullYear(), _start.getMonth(), 1).getTime(); + let _start = moment(startTime); + let _startMonth = moment([_start.year(), _start.month(), 1]).valueOf(); for (let i = 0; i < monthsNum; i++) { let time = moment(_startMonth) @@ -261,4 +260,9 @@ export class CalendarService { date: _moment.date(), }; } + + // BUG fix: https://stackoverflow.com/a/24919934 + private _momentDayModify(date: Moment, days: number): Moment { + return moment.unix(date.unix() + (86400 * days)); + } } From 6150c9ea67caad53088d379258cb2def51f191a3 Mon Sep 17 00:00:00 2001 From: Henrique Melhado Date: Tue, 19 Feb 2019 17:20:22 -0300 Subject: [PATCH 2/2] demo file --- dev/src/demos/demo-dst.ts | 36 +++++++++++++++++++++++++++++++++ dev/src/demos/demo-modal-dst.ts | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 dev/src/demos/demo-dst.ts create mode 100644 dev/src/demos/demo-modal-dst.ts diff --git a/dev/src/demos/demo-dst.ts b/dev/src/demos/demo-dst.ts new file mode 100644 index 000000000..a05918939 --- /dev/null +++ b/dev/src/demos/demo-dst.ts @@ -0,0 +1,36 @@ +import { Component } from '@angular/core'; +import { ModalController } from '@ionic/angular'; + +import { CalendarComponentOptions } from '../ion2-calendar'; + +import * as moment from 'moment'; +import 'moment-timezone'; + +@Component({ + selector: 'demo-dst', + template: ` +
+

DST (Daylight Savings Time)

+ + + `, +}) +export class DemoDstComponent { + date: string = '2018-10-01'; + options: CalendarComponentOptions = { + from: new Date(2000, 9, 1), + weekStart: 1, + }; + + constructor(public modalCtrl: ModalController) { + moment.tz.setDefault(moment.tz.guess()); + } + + onChange($event) { + console.log($event); + } +} diff --git a/dev/src/demos/demo-modal-dst.ts b/dev/src/demos/demo-modal-dst.ts new file mode 100644 index 000000000..0fdc10876 --- /dev/null +++ b/dev/src/demos/demo-modal-dst.ts @@ -0,0 +1,36 @@ +import { Component } from '@angular/core'; +import { ModalController } from '@ionic/angular'; +import * as moment from 'moment'; +import 'moment-timezone'; + +import { CalendarModal, CalendarModalOptions } from '../ion2-calendar'; + +@Component({ + selector: 'demo-modal-dst', + template: ` + + DST (Daylight Savings Time) + + `, +}) +export class DemoModalDstComponent { + constructor(public modalCtrl: ModalController) { + moment.tz.setDefault(moment.tz.guess()); + moment.locale('en'); + } + + async openCalendar() { + const options: CalendarModalOptions = { + title: 'DST (Daylight Savings Time)', + weekStart: 1, + from: new Date(2018, 9, 1), + }; + + const myCalendar = await this.modalCtrl.create({ + component: CalendarModal, + componentProps: { options }, + }); + + myCalendar.present(); + } +}