@@ -17,12 +17,15 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
17
17
yearRange : 20 ,
18
18
minDate : null ,
19
19
maxDate : null ,
20
- shortcutPropagation : false
20
+ shortcutPropagation : false ,
21
+ ngModelOptions : { }
21
22
} )
22
23
23
- . controller ( 'UibDatepickerController' , [ '$scope' , '$attrs' , '$parse' , '$interpolate' , '$log' , 'dateFilter' , 'uibDatepickerConfig' , '$datepickerSuppressError' , function ( $scope , $attrs , $parse , $interpolate , $log , dateFilter , datepickerConfig , $datepickerSuppressError ) {
24
+ . controller ( 'UibDatepickerController' , [ '$scope' , '$attrs' , '$parse' , '$interpolate' , '$log' , 'dateFilter' , 'uibDatepickerConfig' , '$datepickerSuppressError' , 'uibDateParser' ,
25
+ function ( $scope , $attrs , $parse , $interpolate , $log , dateFilter , datepickerConfig , $datepickerSuppressError , dateParser ) {
24
26
var self = this ,
25
- ngModelCtrl = { $setViewValue : angular . noop } ; // nullModelCtrl;
27
+ ngModelCtrl = { $setViewValue : angular . noop } , // nullModelCtrl;
28
+ ngModelOptions = { } ;
26
29
27
30
// Modes chain
28
31
this . modes = [ 'day' , 'month' , 'year' ] ;
@@ -41,11 +44,11 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
41
44
angular . forEach ( [ 'minDate' , 'maxDate' ] , function ( key ) {
42
45
if ( $attrs [ key ] ) {
43
46
$scope . $parent . $watch ( $attrs [ key ] , function ( value ) {
44
- self [ key ] = value ? new Date ( value ) : null ;
47
+ self [ key ] = value ? dateParser . fromTimezone ( new Date ( value ) , ngModelOptions . timezone ) : null ;
45
48
self . refreshView ( ) ;
46
49
} ) ;
47
50
} else {
48
- self [ key ] = datepickerConfig [ key ] ? new Date ( datepickerConfig [ key ] ) : null ;
51
+ self [ key ] = datepickerConfig [ key ] ? dateParser . fromTimezone ( new Date ( datepickerConfig [ key ] ) , ngModelOptions . timezone ) : null ;
49
52
}
50
53
} ) ;
51
54
@@ -67,10 +70,10 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
67
70
$scope . uniqueId = 'datepicker-' + $scope . $id + '-' + Math . floor ( Math . random ( ) * 10000 ) ;
68
71
69
72
if ( angular . isDefined ( $attrs . initDate ) ) {
70
- this . activeDate = $scope . $parent . $eval ( $attrs . initDate ) || new Date ( ) ;
73
+ this . activeDate = dateParser . fromTimezone ( $scope . $parent . $eval ( $attrs . initDate ) , ngModelOptions . timezone ) || new Date ( ) ;
71
74
$scope . $parent . $watch ( $attrs . initDate , function ( initDate ) {
72
75
if ( initDate && ( ngModelCtrl . $isEmpty ( ngModelCtrl . $modelValue ) || ngModelCtrl . $invalid ) ) {
73
- self . activeDate = initDate ;
76
+ self . activeDate = dateParser . fromTimezone ( initDate , ngModelOptions . timezone ) ;
74
77
self . refreshView ( ) ;
75
78
}
76
79
} ) ;
@@ -96,6 +99,7 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
96
99
97
100
this . init = function ( ngModelCtrl_ ) {
98
101
ngModelCtrl = ngModelCtrl_ ;
102
+ ngModelOptions = ngModelCtrl_ . $options || datepickerConfig . ngModelOptions ;
99
103
100
104
ngModelCtrl . $render = function ( ) {
101
105
self . render ( ) ;
@@ -108,7 +112,7 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
108
112
isValid = ! isNaN ( date ) ;
109
113
110
114
if ( isValid ) {
111
- this . activeDate = date ;
115
+ this . activeDate = dateParser . fromTimezone ( date , ngModelOptions . timezone ) ;
112
116
} else if ( ! $datepickerSuppressError ) {
113
117
$log . error ( 'Datepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.' ) ;
114
118
}
@@ -121,13 +125,15 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
121
125
this . _refreshView ( ) ;
122
126
123
127
var date = ngModelCtrl . $viewValue ? new Date ( ngModelCtrl . $viewValue ) : null ;
128
+ date = dateParser . fromTimezone ( date , ngModelOptions . timezone ) ;
124
129
ngModelCtrl . $setValidity ( 'dateDisabled' , ! date ||
125
130
this . element && ! this . isDisabled ( date ) ) ;
126
131
}
127
132
} ;
128
133
129
134
this . createDateObject = function ( date , format ) {
130
135
var model = ngModelCtrl . $viewValue ? new Date ( ngModelCtrl . $viewValue ) : null ;
136
+ model = dateParser . fromTimezone ( model , ngModelOptions . timezone ) ;
131
137
return {
132
138
date : date ,
133
139
label : dateFilter ( date , format ) ,
@@ -160,8 +166,9 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
160
166
161
167
$scope . select = function ( date ) {
162
168
if ( $scope . datepickerMode === self . minMode ) {
163
- var dt = ngModelCtrl . $viewValue ? new Date ( ngModelCtrl . $viewValue ) : new Date ( 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ;
169
+ var dt = ngModelCtrl . $viewValue ? dateParser . fromTimezone ( new Date ( ngModelCtrl . $viewValue ) , ngModelOptions . timezone ) : new Date ( 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ;
164
170
dt . setFullYear ( date . getFullYear ( ) , date . getMonth ( ) , date . getDate ( ) ) ;
171
+ dt = dateParser . toTimezone ( dt , ngModelOptions . timezone ) ;
165
172
ngModelCtrl . $setViewValue ( dt ) ;
166
173
ngModelCtrl . $render ( ) ;
167
174
} else {
@@ -543,19 +550,20 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
543
550
altInputFormats : [ ]
544
551
} )
545
552
546
- . controller ( 'UibDatepickerPopupController' , [ '$scope' , '$element' , '$attrs' , '$compile' , '$parse' , '$document' , '$rootScope' , '$uibPosition' , 'dateFilter' , 'uibDateParser' , 'uibDatepickerPopupConfig' , '$timeout' ,
547
- function ( scope , element , attrs , $compile , $parse , $document , $rootScope , $position , dateFilter , dateParser , datepickerPopupConfig , $timeout ) {
553
+ . controller ( 'UibDatepickerPopupController' , [ '$scope' , '$element' , '$attrs' , '$compile' , '$parse' , '$document' , '$rootScope' , '$uibPosition' , 'dateFilter' , 'uibDateParser' , 'uibDatepickerPopupConfig' , '$timeout' , 'uibDatepickerConfig' ,
554
+ function ( scope , element , attrs , $compile , $parse , $document , $rootScope , $position , dateFilter , dateParser , datepickerPopupConfig , $timeout , datepickerConfig ) {
548
555
var self = this ;
549
556
var cache = { } ,
550
557
isHtml5DateInput = false ;
551
558
var dateFormat , closeOnDateSelection , appendToBody , onOpenFocus ,
552
559
datepickerPopupTemplateUrl , datepickerTemplateUrl , popupEl , datepickerEl ,
553
- ngModel , $popup , altInputFormats ;
560
+ ngModel , ngModelOptions , $popup , altInputFormats ;
554
561
555
562
scope . watchData = { } ;
556
563
557
564
this . init = function ( _ngModel_ ) {
558
565
ngModel = _ngModel_ ;
566
+ ngModelOptions = _ngModel_ . $options || datepickerConfig . ngModelOptions ;
559
567
closeOnDateSelection = angular . isDefined ( attrs . closeOnDateSelection ) ? scope . $parent . $eval ( attrs . closeOnDateSelection ) : datepickerPopupConfig . closeOnDateSelection ;
560
568
appendToBody = angular . isDefined ( attrs . datepickerAppendToBody ) ? scope . $parent . $eval ( attrs . datepickerAppendToBody ) : datepickerPopupConfig . appendToBody ;
561
569
onOpenFocus = angular . isDefined ( attrs . onOpenFocus ) ? scope . $parent . $eval ( attrs . onOpenFocus ) : datepickerPopupConfig . onOpenFocus ;
@@ -568,6 +576,8 @@ function(scope, element, attrs, $compile, $parse, $document, $rootScope, $positi
568
576
if ( datepickerPopupConfig . html5Types [ attrs . type ] ) {
569
577
dateFormat = datepickerPopupConfig . html5Types [ attrs . type ] ;
570
578
isHtml5DateInput = true ;
579
+ ngModelOptions . timezoneHtml5 = ngModelOptions . timezone ;
580
+ ngModelOptions . timezone = null ;
571
581
} else {
572
582
dateFormat = attrs . uibDatepickerPopup || datepickerPopupConfig . datepickerPopup ;
573
583
attrs . $observe ( 'uibDatepickerPopup' , function ( value , oldValue ) {
@@ -595,8 +605,11 @@ function(scope, element, attrs, $compile, $parse, $document, $rootScope, $positi
595
605
596
606
// popup element used to display calendar
597
607
popupEl = angular . element ( '<div uib-datepicker-popup-wrap><div uib-datepicker></div></div>' ) ;
608
+ scope . ngModelOptions = angular . copy ( ngModelOptions ) ;
609
+ scope . ngModelOptions . timezone = null ;
598
610
popupEl . attr ( {
599
611
'ng-model' : 'date' ,
612
+ 'ng-model-options' : 'ngModelOptions' ,
600
613
'ng-change' : 'dateSelection(date)' ,
601
614
'template-url' : datepickerPopupTemplateUrl
602
615
} ) ;
@@ -615,7 +628,7 @@ function(scope, element, attrs, $compile, $parse, $document, $rootScope, $positi
615
628
if ( attrs . datepickerOptions ) {
616
629
var options = scope . $parent . $eval ( attrs . datepickerOptions ) ;
617
630
if ( options && options . initDate ) {
618
- scope . initDate = options . initDate ;
631
+ scope . initDate = dateParser . fromTimezone ( options . initDate , ngModelOptions . timezone || ngModelOptions . timezoneHtml5 ) ;
619
632
datepickerEl . attr ( 'init-date' , 'initDate' ) ;
620
633
delete options . initDate ;
621
634
}
@@ -628,9 +641,12 @@ function(scope, element, attrs, $compile, $parse, $document, $rootScope, $positi
628
641
if ( attrs [ key ] ) {
629
642
var getAttribute = $parse ( attrs [ key ] ) ;
630
643
scope . $parent . $watch ( getAttribute , function ( value ) {
631
- scope . watchData [ key ] = value ;
632
644
if ( key === 'minDate' || key === 'maxDate' ) {
633
- cache [ key ] = new Date ( value ) ;
645
+ cache [ key ] = dateParser . fromTimezone ( new Date ( value ) , ngModelOptions . timezone ) ;
646
+ }
647
+ scope . watchData [ key ] = cache [ key ] || value ;
648
+ if ( key === 'initDate' ) {
649
+ scope . watchData [ key ] = dateParser . fromTimezone ( new Date ( value ) , ngModelOptions . timezone || ngModelOptions . timezoneHtml5 ) ;
634
650
}
635
651
} ) ;
636
652
datepickerEl . attr ( cameltoDash ( key ) , 'watchData.' + key ) ;
@@ -667,12 +683,16 @@ function(scope, element, attrs, $compile, $parse, $document, $rootScope, $positi
667
683
ngModel . $validators . date = validator ;
668
684
ngModel . $parsers . unshift ( parseDate ) ;
669
685
ngModel . $formatters . push ( function ( value ) {
670
- scope . date = value ;
671
- return ngModel . $isEmpty ( value ) ? value : dateFilter ( value , dateFormat ) ;
686
+ if ( ngModel . $isEmpty ( value ) ) {
687
+ scope . date = value ;
688
+ return value ;
689
+ }
690
+ scope . date = dateParser . fromTimezone ( value , ngModelOptions . timezone ) ;
691
+ return dateFilter ( scope . date , dateFormat ) ;
672
692
} ) ;
673
693
} else {
674
694
ngModel . $formatters . push ( function ( value ) {
675
- scope . date = value ;
695
+ scope . date = dateParser . fromTimezone ( value , ngModelOptions . timezoneHtml5 ) ;
676
696
return value ;
677
697
} ) ;
678
698
}
@@ -827,7 +847,7 @@ function(scope, element, attrs, $compile, $parse, $document, $rootScope, $positi
827
847
if ( angular . isString ( viewValue ) ) {
828
848
var date = parseDateString ( viewValue ) ;
829
849
if ( ! isNaN ( date ) ) {
830
- return date ;
850
+ return dateParser . toTimezone ( date , ngModelOptions . timezone ) ;
831
851
}
832
852
}
833
853
0 commit comments