diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js
index 45f41bd3..b6a267b2 100644
--- a/src/ng/directive/input.js
+++ b/src/ng/directive/input.js
@@ -113,6 +113,9 @@ var inputType = {
* modern browsers do not yet support this input type, it is important to provide cues to users on the
* expected input format via a placeholder or label. The model must always be a Date object.
*
+ * The timezone to be used to read/write the `Date` instance in the model can be defined using
+ * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
+ *
* @param {string} ngModel Assignable angular expression to data-bind to.
* @param {string=} name Property name of the form under which the control is published.
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be a
@@ -198,6 +201,9 @@ var inputType = {
* the HTML5 date input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
* local datetime format (yyyy-MM-ddTHH:mm), for example: `2010-12-28T14:57`. The model must be a Date object.
*
+ * The timezone to be used to read/write the `Date` instance in the model can be defined using
+ * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
+ *
* @param {string} ngModel Assignable angular expression to data-bind to.
* @param {string=} name Property name of the form under which the control is published.
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be a
@@ -284,6 +290,9 @@ var inputType = {
* local time format (HH:mm), for example: `14:57`. Model must be a Date object. This binding will always output a
* Date object to the model of January 1, 1970, or local date `new Date(1970, 0, 1, HH, mm)`.
*
+ * The timezone to be used to read/write the `Date` instance in the model can be defined using
+ * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
+ *
* @param {string} ngModel Assignable angular expression to data-bind to.
* @param {string=} name Property name of the form under which the control is published.
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be a
@@ -369,6 +378,9 @@ var inputType = {
* the HTML5 week input, a text element will be used. In that case, the text must be entered in a valid ISO-8601
* week format (yyyy-W##), for example: `2013-W02`. The model must always be a Date object.
*
+ * The timezone to be used to read/write the `Date` instance in the model can be defined using
+ * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
+ *
* @param {string} ngModel Assignable angular expression to data-bind to.
* @param {string=} name Property name of the form under which the control is published.
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be a
@@ -453,6 +465,9 @@ var inputType = {
* month format (yyyy-MM), for example: `2009-01`. The model must always be a Date object. In the event the model is
* not set to the first of the month, the first of that model's month is assumed.
*
+ * The timezone to be used to read/write the `Date` instance in the model can be defined using
+ * {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
+ *
* @param {string} ngModel Assignable angular expression to data-bind to.
* @param {string=} name Property name of the form under which the control is published.
* @param {string=} min Sets the `min` validation error key if the value entered is less than `min`. This must be
@@ -1061,6 +1076,7 @@ function createDateParser(regexp, mapping) {
function createDateInputType(type, regexp, parseDate, format) {
return function dynamicDateInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter) {
textInputType(scope, element, attr, ctrl, $sniffer, $browser);
+ var timezone = ctrl && ctrl.$options && ctrl.$options.timezone;
ctrl.$parsers.push(function(value) {
if(ctrl.$isEmpty(value)) {
@@ -1070,7 +1086,11 @@ function createDateInputType(type, regexp, parseDate, format) {
if(regexp.test(value)) {
ctrl.$setValidity(type, true);
- return parseDate(value);
+ var parsedDate = parseDate(value);
+ if (timezone === 'UTC') {
+ parsedDate.setMinutes(parsedDate.getMinutes() - parsedDate.getTimezoneOffset());
+ }
+ return parsedDate;
}
ctrl.$setValidity(type, false);
@@ -1079,7 +1099,7 @@ function createDateInputType(type, regexp, parseDate, format) {
ctrl.$formatters.push(function(value) {
if(isDate(value)) {
- return $filter('date')(value, format);
+ return $filter('date')(value, format, timezone);
}
return '';
});
@@ -2604,6 +2624,9 @@ var ngValueDirective = function() {
* `ngModelOptions="{ updateOn: 'default blur', debounce: {'default': 500, 'blur': 0} }"`
* - `getterSetter`: boolean value which determines whether or not to treat functions bound to
`ngModel` as getters/setters.
+ * - `timezone`: Defines the timezone to be used to read/write the `Date` instance in the model for
+ * ``, ``, ... . Right now, the only supported value is `'UTC'`,
+ * otherwise the default timezone of the browser will be used.
*
* @example
diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js
index 37b35dfc..a35b85b0 100644
--- a/test/ng/directive/inputSpec.js
+++ b/test/ng/directive/inputSpec.js
@@ -1627,6 +1627,18 @@ describe('input', function() {
expect(inputElm).toBeValid();
});
+ it('should use UTC if specified in the options', function() {
+ compileInput('');
+
+ changeInputValueTo('2013-07');
+ expect(+scope.value).toBe(Date.UTC(2013, 6, 1));
+
+ scope.$apply(function() {
+ scope.value = new Date(Date.UTC(2014, 6, 1));
+ });
+ expect(inputElm.val()).toBe('2014-07');
+ });
+
describe('min', function (){
beforeEach(function (){
@@ -1746,6 +1758,18 @@ describe('input', function() {
expect(inputElm).toBeValid();
});
+ it('should use UTC if specified in the options', function() {
+ compileInput('');
+
+ changeInputValueTo('2013-W03');
+ expect(+scope.value).toBe(Date.UTC(2013, 0, 17));
+
+ scope.$apply(function() {
+ scope.value = new Date(Date.UTC(2014, 0, 17));
+ });
+ expect(inputElm.val()).toBe('2014-W03');
+ });
+
describe('min', function (){
beforeEach(function (){
compileInput('');
@@ -1863,6 +1887,18 @@ describe('input', function() {
expect(inputElm).toBeValid();
});
+ it('should use UTC if specified in the options', function() {
+ compileInput('');
+
+ changeInputValueTo('2000-01-01T01:02');
+ expect(+scope.value).toBe(Date.UTC(2000, 0, 1, 1, 2));
+
+ scope.$apply(function() {
+ scope.value = new Date(Date.UTC(2001, 0, 1, 1, 2));
+ });
+ expect(inputElm.val()).toBe('2001-01-01T01:02');
+ });
+
describe('min', function (){
beforeEach(function (){
compileInput('');
@@ -2008,6 +2044,18 @@ describe('input', function() {
expect(inputElm).toBeValid();
});
+ it('should use UTC if specified in the options', function() {
+ compileInput('');
+
+ changeInputValueTo('23:02');
+ expect(+scope.value).toBe(Date.UTC(1970, 0, 1, 23, 2));
+
+ scope.$apply(function() {
+ scope.value = new Date(Date.UTC(1971, 0, 1, 23, 2));
+ });
+ expect(inputElm.val()).toBe('23:02');
+ });
+
describe('min', function (){
beforeEach(function (){
compileInput('');
@@ -2153,6 +2201,18 @@ describe('input', function() {
expect(inputElm).toBeValid();
});
+ it('should use UTC if specified in the options', function() {
+ compileInput('');
+
+ changeInputValueTo('2000-01-01');
+ expect(+scope.value).toBe(Date.UTC(2000, 0, 1));
+
+ scope.$apply(function() {
+ scope.value = new Date(Date.UTC(2001, 0, 1));
+ });
+ expect(inputElm.val()).toBe('2001-01-01');
+ });
+
describe('min', function (){
beforeEach(function (){
compileInput('');