[Feature] Implementation changed to be more clear and easier to maintain.
[Verification] Code compiles without errors.
TCT passrate: Time, Calendar, Alarm and Exif is 100%.
Change-Id: Id222df420a0296b2763c1d828c02dc4f7f3e07ea
Signed-off-by: Piotr Kosko <p.kosko@samsung.com>
'time_extension.h',
'time_instance.cc',
'time_instance.h',
+ 'time_manager.cc',
+ 'time_manager.h',
+ 'time_utils.cc',
+ 'time_utils.h',
],
'conditions': [
[ 'tizen == 1', {
-// Copyright (c) 2013 Intel Corporation. All rights reserved.
-// Copyright (c) 2015 Samsung Electronics Co, Ltd. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var _minuteInMilliseconds = 60 * 1000;
-var _hourInMilliseconds = _minuteInMilliseconds * 60;
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
var utils_ = xwalk.utils;
var validator_ = utils_.validator;
var types_ = validator_.Types;
var native_ = new utils_.NativeManager(extension);
+var converter_ = utils_.converter;
+var T = utils_.type;
-exports.getCurrentDateTime = function() {
- return new tizen.TZDate();
-};
-
-exports.getLocalTimezone = function() {
- var result = native_.callSync('Time_getLocalTimeZone');
- if (native_.isFailure(result)) {
- throw native_.getErrorObject(result);
- }
-
- return native_.getResultObject(result);
-};
-
-var _availableTimezonesCache = [];
-
-exports.getAvailableTimezones = function() {
- if (_availableTimezonesCache.length)
- return _availableTimezonesCache;
-
- var result = native_.callSync('Time_getAvailableTimeZones');
- if (native_.isFailure(result)) {
- throw native_.getErrorObject(result);
- }
-
- _availableTimezonesCache = native_.getResultObject(result);
- return _availableTimezonesCache;
-};
-
-exports.getDateFormat = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'shortformat',
- type: types_.BOOLEAN,
- optional: true,
- nullable: true
- }]);
-
- if (!args.has.shortformat) {
- args.shortformat = false;
- }
-
- var result = native_.callSync('Time_getDateFormat', {shortformat: args.shortformat});
- if (native_.isFailure(result)) {
- throw native_.getErrorObject(result);
- }
- return native_.getResultObject(result);
-};
-
-exports.getTimeFormat = function() {
- var result = native_.callSync('Time_getTimeFormat');
- if (native_.isFailure(result)) {
- throw native_.getErrorObject(result);
- }
-
- return native_.getResultObject(result);
-};
-
-exports.isLeapYear = function(year) {
- if (year === undefined)
- throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR);
-
- return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0);
-};
-
-var _timeUtilDateTimeChangeListener;
+var _GMT_ID = 'GMT';
+var _LOCAL_ID = '__local__';
-function _timeUtilDateTimeChangeListenerCallback() {
- native_.callIfPossible(_timeUtilDateTimeChangeListener);
+function _createShiftedDate(tzDate) {
+ return new Date(tzDate._shiftedTimestamp);
}
-exports.setDateTimeChangeListener = function() {
- var args = validator_.validateArgs(arguments, [
- {
- name: 'changeCallback',
- type: types_.FUNCTION
- }
- ]);
- _timeUtilDateTimeChangeListener = args.changeCallback;
- native_.addListener('DateTimeChangeListener',
- _timeUtilDateTimeChangeListenerCallback);
- var result = native_.callSync('Time_setDateTimeChangeListener', {});
- if (native_.isFailure(result)) {
- throw native_.getErrorObject(result);
- }
-};
-
-exports.unsetDateTimeChangeListener = function() {
- native_.removeListener('DateTimeChangeListener',
- _timeUtilDateTimeChangeListenerCallback);
- var result = native_.callSync('Time_unsetDateTimeChangeListener', {});
- _timeUtilDateTimeChangeListener = undefined;
- if (native_.isFailure(result)) {
- throw native_.getErrorObject(result);
- }
-};
-
-var _timeUtilTimezoneChangeListener;
-
-function _timeUtilTimezoneChangeListenerCallback() {
- native_.callIfPossible(_timeUtilTimezoneChangeListener);
+function _createUTCDate(tzDate) {
+ return new Date(tzDate._utcTimestamp);
}
-exports.setTimezoneChangeListener = function() {
- var args = validator_.validateArgs(arguments, [
- {
- name: 'changeCallback',
- type: types_.FUNCTION
- }
- ]);
-
- _timeUtilTimezoneChangeListener = args.changeCallback;
- native_.addListener('TimezoneChangeListener',
- _timeUtilTimezoneChangeListenerCallback);
- var result = native_.callSync('Time_setTimezoneChangeListener', {});
- if (native_.isFailure(result)) {
- throw native_.getErrorObject(result);
- }
-};
-
-exports.unsetTimezoneChangeListener = function() {
- native_.removeListener('TimezoneChangeListener',
- _timeUtilTimezoneChangeListenerCallback);
- var result = native_.callSync('Time_unsetTimezoneChangeListener', {});
- _timeUtilTimezoneChangeListener = undefined;
- if (native_.isFailure(result)) {
- throw native_.getErrorObject(result);
- }
-};
-
-function _throwProperTizenException(e) {
- if (e instanceof TypeError)
- throw new WebAPIException(WebAPIException.TYPE_MISMATCH_ERR);
- else if (e instanceof RangeError)
- throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR);
- else
- throw new WebAPIException(WebAPIException.UNKNOWN_ERR);
+function _fill(date, tzDate) {
+ tzDate._shiftedTimestamp = date.getTime();
+ tzDate._utcTimestamp = Number(tzDate._shiftedTimestamp) - Number(tzDate._timezoneOffset);
}
-var TimeDurationUnit = {
- MSECS: 'MSECS',
- SECS: 'SECS',
- MINS: 'MINS',
- HOURS: 'HOURS',
- DAYS: 'DAYS'
-};
-
-tizen.TimeDuration = function(length, unit) {
- validator_.isConstructorCall(this, tizen.TimeDuration);
-
- var length_ = length !== null ? Math.floor(length) : 0;
- var unit_ = Object.keys(TimeDurationUnit).indexOf(unit) >= 0 ? unit : TimeDurationUnit.MSECS;
+function _fillWithUTC(date, tzDate) {
+ tzDate._utcTimestamp = date.getTime();
+ tzDate._shiftedTimestamp = Number(tzDate._utcTimestamp) + Number(tzDate._timezoneOffset);
+}
+function PrivateTZDate(timestamp, timezone, offset) {
Object.defineProperties(this, {
- length: {
- get: function() {
- return length_;
- },
- set: function(v) {
- if (v !== null) {
- length_ = Math.floor(v);
- }
- },
- enumerable: true
- },
- unit: {
- get: function() {
- return unit_;
- },
- set: function(v) {
- if (Object.keys(TimeDurationUnit).indexOf(v) >= 0) {
- unit_ = v;
- }
- },
- enumerable: true
- }
+ ts : {value: timestamp, writable: false, enumerable: false},
+ tzId : {value: timezone, writable: false, enumerable: false},
+ o : {value: offset, writable: false, enumerable: false}
});
-};
-
-function makeMillisecondsDurationObject(length) {
- var dayInMsecs = _hourInMilliseconds * 24;
- length = Math.floor(length);
-
- if ((length % dayInMsecs) === 0)
- return new tizen.TimeDuration(length / dayInMsecs, TimeDurationUnit.DAYS);
-
- return new tizen.TimeDuration(length, TimeDurationUnit.MSECS);
}
-tizen.TimeDuration.prototype.getMilliseconds = function() {
- var m;
- switch (this.unit) {
- case TimeDurationUnit.MSECS:
- m = 1;
- break;
- case TimeDurationUnit.SECS:
- m = 1000;
- break;
- case TimeDurationUnit.MINS:
- m = 60 * 1000;
- break;
- case TimeDurationUnit.HOURS:
- m = 3600 * 1000;
- break;
- case TimeDurationUnit.DAYS:
- m = 86400 * 1000;
- break;
- }
- return m * this.length;
-};
-
-tizen.TimeDuration.prototype.difference = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'other',
- type: types_.PLATFORM_OBJECT,
- values: tizen.TimeDuration
- }]);
-
- try {
- return makeMillisecondsDurationObject(this.getMilliseconds() -
- args.other.getMilliseconds());
- } catch (e) {
- _throwProperTizenException(e);
- }
-};
-
-tizen.TimeDuration.prototype.equalsTo = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'other',
- type: types_.PLATFORM_OBJECT,
- values: tizen.TimeDuration
- }]);
-
- try {
- return this.getMilliseconds() === args.other.getMilliseconds();
- } catch (e) {
- _throwProperTizenException(e);
+function _getTimezoneOffset(timestamp, tzName) {
+ var callArgs = {
+ timezone : converter_.toString(tzName),
+ timestamp : converter_.toString(timestamp)
+ };
+ var result = native_.callSync('TZDate_getTimezoneOffset', callArgs);
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
}
-};
-
-tizen.TimeDuration.prototype.lessThan = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'other',
- type: types_.PLATFORM_OBJECT,
- values: tizen.TimeDuration
- }]);
+ var res = {
+ offset : converter_.toLong(native_.getResultObject(result).offset),
+ modifier : converter_.toLong(native_.getResultObject(result).modifier)
+ };
+ return res;
+}
- try {
- return this.getMilliseconds() < args.other.getMilliseconds();
- } catch (e) {
- _throwProperTizenException(e);
- }
-};
+function _getLocalTimezoneOffset() {
+ return -1 * (new Date().getTimezoneOffset()) * 60 * 1000; // cast to milliseconds
+}
-tizen.TimeDuration.prototype.greaterThan = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'other',
- type: types_.PLATFORM_OBJECT,
- values: tizen.TimeDuration
- }]);
+function _constructTZDate(obj, privateTZDate) {
+ var utcTimestamp = privateTZDate.ts;
+ var tzName = privateTZDate.tzId;
+ var offset = privateTZDate.o;
- try {
- return this.getMilliseconds() > args.other.getMilliseconds();
- } catch (e) {
- _throwProperTizenException(e);
- }
-};
+ switch (tzName) {
+ case _LOCAL_ID:
+ console.log('Entered _constructTZDate for local timezone');
-tizen.TimeDuration.prototype.toString = function() {
- return this.length + ' ' + this.unit;
-};
+ tzName = tizen.time.getLocalTimezone();
-function getTimezoneOffset(_timezone, _timeInMs) {
- var result = native_.callSync('Time_getTimeZoneOffset', {
- timezone: _timezone,
- value: _timeInMs
- });
- if (native_.isFailure(result)) {
- throw native_.getErrorObject(result);
- }
+ if (T.isNullOrUndefined(offset)) {
+ offset = _getLocalTimezoneOffset();
+ }
+ break;
- return native_.getResultObject(result);
-}
+ case _GMT_ID:
+ console.log('Entered _constructTZDate for GMT');
-function getMsUTC(date, timezone) {
- var ms_utc = Date.UTC(date.getUTCFullYear(),
- date.getUTCMonth(),
- date.getUTCDate(),
- date.getUTCHours(),
- date.getUTCMinutes(),
- date.getUTCSeconds(),
- date.getUTCMilliseconds());
- if (arguments.length === 2) {
- var result = native_.callSync('Time_getMsUTC', {
- timezone: timezone,
- value: ms_utc
- });
- if (native_.isFailure(result)) {
- throw native_.getErrorObject(result);
+ if (T.isNullOrUndefined(offset)) {
+ offset = 0;
}
+ break;
- ms_utc = native_.getResultObject(result);
+ default:
+ console.log('Entered _constructTZDate for: ' + tzName);
+ if (T.isNullOrUndefined(offset)) {
+ // throws if tzName is invalid
+ offset = _getTimezoneOffset(utcTimestamp, tzName).offset;
+ }
+ break;
}
- return ms_utc;
+ Object.defineProperties(obj, {
+ _utcTimestamp : {value: utcTimestamp, writable: true, enumerable: false},
+ _shiftedTimestamp : {value: utcTimestamp + offset, writable: true, enumerable: false},
+ _timezoneName : {value: tzName, writable: true, enumerable: false},
+ _timezoneOffset : {value: offset, writable: true, enumerable: false}
+ });
}
-tizen.TZDate = function(year, month, day, hours, minutes, seconds, milliseconds, timezone) {
- validator_.isConstructorCall(this, tizen.TZDate);
+//class TZDate ////////////////////////////////////////////////////
+tizen.TZDate = function(p1, p2, day, hours, minutes, seconds, milliseconds, timezone) {
+ console.log("Entered tizen.TZDate");
+ validator_.validateConstructorCall(this, tizen.TZDate);
- if (timezone) {
- if (tizen.time.getAvailableTimezones().indexOf(timezone) < 0) {
- throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR);
- }
-
- this.timezone_ = timezone;
+ var priv;
+ //copy constructor section (should be only for private usage)
+ if (p1 instanceof PrivateTZDate) {
+ priv = p1;
} else {
- this.timezone_ = tizen.time.getLocalTimezone();
- }
+ //Public constructor section
+ console.log('Entered TZDate constructor with: ' + arguments.length + ' attributes');
- var hours = hours || 0;
- var minutes = minutes || 0;
- var seconds = seconds || 0;
- var milliseconds = milliseconds || 0;
+ var date;
- if (!arguments.length) {
- this.date_ = new Date();
- } else if (arguments.length === 1 || arguments.length === 2) {
- if (arguments[0] instanceof Date) {
- this.date_ = arguments[0];
+ if (arguments.length < 3) {
+ if (T.isDate(p1)) {
+ date = p1;
+ } else {
+ date = new Date();
+ }
+ timezone = p2;
} else {
- this.date_ = new Date();
+ p1 = p1 ? p1 : 0;
+ p2 = p2 ? p2 : 0;
+ day = day ? day : 0;
+ hours = hours ? hours : 0;
+ minutes = minutes ? minutes : 0;
+ seconds = seconds ? seconds : 0;
+ milliseconds = milliseconds ? milliseconds : 0;
+
+ date = new Date(p1, p2, day, hours, minutes, seconds, milliseconds);
}
- if (arguments[1]) {
- if (tizen.time.getAvailableTimezones().indexOf(arguments[1]) < 0) {
- throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR);
+
+ var offset = _getLocalTimezoneOffset();
+ var utcTimestamp = date.getTime();
+ var tzName = _LOCAL_ID;
+
+ if (!T.isNullOrUndefined(timezone)) {
+ timezone = converter_.toString(timezone);
+ var timezoneTimestamp = new Date(Date.UTC(date.getFullYear(),
+ date.getMonth(),
+ date.getDate(),
+ date.getHours(),
+ date.getMinutes(),
+ date.getSeconds(),
+ date.getMilliseconds())).getTime();
+ try {
+ var offsetObject = _getTimezoneOffset(timezoneTimestamp, timezone);
+ offset = offsetObject.offset;
+ utcTimestamp = timezoneTimestamp - offset;
+ //correction of missing/extra hour on DST change
+ var modifier = offsetObject.modifier;
+ if (modifier > 0) {
+ //this is for case when 2AM becomes 3AM (but offset must be corrected -
+ //missing one hour)
+ offset += modifier;
+ } else {
+ //this is for case when extra hour appers - prevents error of
+ //unnecessary shift of hour when timezone changes
+ offset -= modifier;
+ utcTimestamp += modifier;
+ }
+ tzName = timezone;
+ } catch(e) {
+ // in case of exception we fall back to local time zone
}
- this.timezone_ = arguments[1];
- }
- } else {
- this.date_ = {};
- if (timezone) {
- var d = new Date();
- d.setUTCFullYear(year);
- d.setUTCMonth(month);
- d.setUTCDate(day);
- d.setUTCHours(hours);
- d.setUTCMinutes(minutes);
- d.setUTCSeconds(seconds);
- d.setUTCMilliseconds(milliseconds);
- this.date_ = new Date(getMsUTC(d, timezone));
- } else {
- this.date_ = new Date(year, month, day, hours, minutes, seconds, milliseconds);
}
+
+ priv = new PrivateTZDate(utcTimestamp, tzName, offset);
}
+
+ _constructTZDate(this, priv);
};
tizen.TZDate.prototype.getDate = function() {
- var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
- getMsUTC(this.date_))));
- return d.date_.getUTCDate();
-};
+ console.log('Entered TZDate.getDate');
+ //getters realized with pattern
+ //---> use _shiftedTimestamp (_utcTimestamp (UTC) with added _timezoneOffset)
+ //---> create Date instance
+ //---> return d.getUTCDate() --- to avoid locale timezone impact of JS Date object
+ return _createShiftedDate(this).getUTCDate();
+};
+
+function _updateTZDate(tzdate, args, param, func) {
+ var a = validator_.validateMethod(args, [
+ {
+ name : param,
+ type : validator_.Types.LONG
+ }
+ ]);
+
+ //setters realized with pattern
+ //---> use _shiftedTimestamp (_utcTimestamp (UTC) with added _timezoneOffset)
+ //---> create Date instance
+ //---> setUTCDate of JS Date object
+ //---> getTime of object to set _shiftedTimestmp (avoiding timezone of JS Date)
+ //---> fix _utcTimestamp with subtraction of _timezoneOffset
+ var date = _createShiftedDate(tzdate);
+ date[func](a[param]);
+ _fill(date, tzdate);
+}
-tizen.TZDate.prototype.setDate = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'date',
- type: types_.LONG
- }]);
+function _updateTZDateUTC(tzdate, args, param, func) {
+ var a = validator_.validateMethod(args, [
+ {
+ name : param,
+ type : validator_.Types.LONG
+ }
+ ]);
+ var date = _createUTCDate(tzdate);
+ date[func](a[param]);
+ _fillWithUTC(date, tzdate);
+}
- this.date_.setDate(args.date);
+tizen.TZDate.prototype.setDate = function() {
+ console.log('Entered TZDate.setDate');
+ _updateTZDate(this, arguments, 'date', 'setUTCDate');
};
tizen.TZDate.prototype.getDay = function() {
- return this.date_.getDay();
+ console.log('Entered TZDate.getDay');
+ return _createShiftedDate(this).getUTCDay();
};
tizen.TZDate.prototype.getFullYear = function() {
- return this.date_.getFullYear();
+ console.log('Entered TZDate.getFullYear');
+ return _createShiftedDate(this).getUTCFullYear();
};
tizen.TZDate.prototype.setFullYear = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'year',
- type: types_.LONG
- }]);
-
- this.date_.setFullYear(args.year);
+ console.log('Entered TZDate.setFullYear');
+ _updateTZDate(this, arguments, 'year', 'setUTCFullYear');
};
tizen.TZDate.prototype.getHours = function() {
- var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
- getMsUTC(this.date_))));
- return d.date_.getUTCHours();
+ console.log('Entered TZDate.getHours');
+ return _createShiftedDate(this).getUTCHours();
};
tizen.TZDate.prototype.setHours = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'hours',
- type: types_.LONG
- }]);
-
- this.date_.setHours(args.hours);
+ console.log('Entered TZDate.setHours');
+ _updateTZDate(this, arguments, 'hours', 'setUTCHours');
};
tizen.TZDate.prototype.getMilliseconds = function() {
- return this.date_.getMilliseconds();
+ console.log('Entered TZDate.getMilliseconds');
+ return _createShiftedDate(this).getUTCMilliseconds();
};
tizen.TZDate.prototype.setMilliseconds = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'ms',
- type: types_.LONG
- }]);
-
- this.date_.setMilliseconds(args.ms);
+ console.log('Entered TZDate.setMilliseconds');
+ _updateTZDate(this, arguments, 'ms', 'setUTCMilliseconds');
};
-tizen.TZDate.prototype.getMonth = function() {
- return this.date_.getMonth();
+tizen.TZDate.prototype.getMinutes = function() {
+ console.log('Entered TZDate.getMinutes');
+ return _createShiftedDate(this).getUTCMinutes();
};
-tizen.TZDate.prototype.setMonth = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'month',
- type: types_.LONG
- }]);
-
- this.date_.setMonth(args.month);
+tizen.TZDate.prototype.setMinutes = function() {
+ console.log('Entered TZDate.setMinutes');
+ _updateTZDate(this, arguments, 'minutes', 'setUTCMinutes');
};
-tizen.TZDate.prototype.getMinutes = function() {
- return this.date_.getMinutes();
+tizen.TZDate.prototype.getMonth = function() {
+ console.log('Entered TZDate.getMonth');
+ return _createShiftedDate(this).getUTCMonth();
};
-tizen.TZDate.prototype.setMinutes = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'minutes',
- type: types_.LONG
- }]);
-
- this.date_.setMinutes(args.minutes);
+tizen.TZDate.prototype.setMonth = function() {
+ console.log('Entered TZDate.setMonth');
+ _updateTZDate(this, arguments, 'month', 'setUTCMonth');
};
tizen.TZDate.prototype.getSeconds = function() {
- return this.date_.getSeconds();
+ console.log('Entered TZDate.getSeconds');
+ return _createShiftedDate(this).getUTCSeconds();
};
tizen.TZDate.prototype.setSeconds = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'seconds',
- type: types_.LONG
- }]);
-
- this.date_.setSeconds(args.seconds);
+ console.log('Entered TZDate.setSeconds');
+ _updateTZDate(this, arguments, 'seconds', 'setUTCSeconds');
};
tizen.TZDate.prototype.getUTCDate = function() {
- return this.date_.getUTCDate();
+ console.log('Entered TZDate.getUTCDate');
+ return _createUTCDate(this).getUTCDate();
};
tizen.TZDate.prototype.setUTCDate = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'date',
- type: types_.LONG
- }]);
-
- this.date_.setUTCDate(args.date);
+ console.log('Entered TZDate.setUTCDate');
+ _updateTZDateUTC(this, arguments, 'date', 'setUTCDate');
};
tizen.TZDate.prototype.getUTCDay = function() {
- var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
- getMsUTC(this.date_)) * -1));
- return d.getDay();
+ console.log('Entered TZDate.getUTCDay');
+ return _createUTCDate(this).getUTCDay();
};
tizen.TZDate.prototype.getUTCFullYear = function() {
- var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
- getMsUTC(this.date_)) * -1));
- return d.getFullYear();
+ console.log('Entered TZDate.getUTCFullYear');
+ return _createUTCDate(this).getUTCFullYear();
};
tizen.TZDate.prototype.setUTCFullYear = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'year',
- type: types_.LONG
- }]);
-
- this.date_.setUTCFullYear(args.year);
+ console.log('Entered TZDate.setUTCFullYear');
+ _updateTZDateUTC(this, arguments, 'year', 'setUTCFullYear');
};
tizen.TZDate.prototype.getUTCHours = function() {
- return this.date_.getUTCHours();
+ console.log('Entered TZDate.getUTCHours');
+ return _createUTCDate(this).getUTCHours();
};
tizen.TZDate.prototype.setUTCHours = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'hours',
- type: types_.LONG
- }]);
-
- var offset_hours = getTimezoneOffset(this.timezone_, getMsUTC(this.date_)) /
- _hourInMilliseconds;
- this.date_.setHours(args.hours + offset_hours);
+ console.log('Entered TZDate.setUTCHours');
+ _updateTZDateUTC(this, arguments, 'hours', 'setUTCHours');
};
tizen.TZDate.prototype.getUTCMilliseconds = function() {
- var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
- getMsUTC(this.date_)) * -1));
- return d.getMilliseconds();
+ console.log('Entered TZDate.getUTCMilliseconds');
+ return _createUTCDate(this).getUTCMilliseconds();
};
tizen.TZDate.prototype.setUTCMilliseconds = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'ms',
- type: types_.LONG
- }]);
-
- this.date_.setUTCMilliseconds(args.ms);
+ console.log('Entered TZDate.setUTCMilliseconds');
+ _updateTZDateUTC(this, arguments, 'ms', 'setUTCMilliseconds');
};
tizen.TZDate.prototype.getUTCMinutes = function() {
- var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
- getMsUTC(this.date_)) * -1));
- return d.getMinutes();
+ console.log('Entered TZDate.getUTCMinutes');
+ return _createUTCDate(this).getUTCMinutes();
};
tizen.TZDate.prototype.setUTCMinutes = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'minutes',
- type: types_.LONG
- }]);
-
- this.date_.setUTCMinutes(args.minutes);
+ console.log('Entered TZDate.setUTCMinutes');
+ _updateTZDateUTC(this, arguments, 'minutes', 'setUTCMinutes');
};
tizen.TZDate.prototype.getUTCMonth = function() {
- var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
- getMsUTC(this.date_)) * -1));
- return d.getMonth();
+ console.log('Entered TZDate.getUTCMonth');
+ return _createUTCDate(this).getUTCMonth();
};
tizen.TZDate.prototype.setUTCMonth = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'month',
- type: types_.LONG
- }]);
-
- this.date_.setUTCMonth(args.month);
+ console.log('Entered TZDate.setUTCMonth');
+ _updateTZDateUTC(this, arguments, 'month', 'setUTCMonth');
};
tizen.TZDate.prototype.getUTCSeconds = function() {
- var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
- getMsUTC(this.date_)) * -1));
- return d.getSeconds();
+ console.log('Entered TZDate.getUTCSeconds');
+ return _createUTCDate(this).getUTCSeconds();
};
tizen.TZDate.prototype.setUTCSeconds = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'secs',
- type: types_.LONG
- }]);
-
- this.date_.setUTCSeconds(args.secs);
-};
-
-tizen.TZDate.prototype.getTime = function() {
- return this.date_.getTime();
+ console.log('Entered TZDate.setUTCSeconds');
+ _updateTZDateUTC(this, arguments, 'seconds', 'setUTCSeconds');
};
tizen.TZDate.prototype.getTimezone = function() {
- return this.timezone_;
+ console.log('Entered TZDate.getTimezone');
+ return this._timezoneName;
};
tizen.TZDate.prototype.toTimezone = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'timezone',
- type: types_.STRING
- }]);
-
- if (!args.timezone)
- throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR);
-
- return new tizen.TZDate(new Date(this.date_.getTime()), args.timezone);
+ console.log('Entered TZDate.toTimezone');
+ var args = validator_.validateMethod(arguments, [
+ {
+ name : 'timezone',
+ type : validator_.Types.STRING
+ }
+ ]);
+ return new tizen.TZDate(new PrivateTZDate(this._utcTimestamp, args.timezone));
};
tizen.TZDate.prototype.toLocalTimezone = function() {
- return this.toTimezone(tizen.time.getLocalTimezone());
+ console.log('Entered TZDate.toLocalTimezone');
+ return new tizen.TZDate(new PrivateTZDate(this._utcTimestamp, _LOCAL_ID));
};
tizen.TZDate.prototype.toUTC = function() {
- return this.toTimezone('GMT');
+ console.log('Entered TZDate.toUTC');
+ return new tizen.TZDate(new PrivateTZDate(this._utcTimestamp, _GMT_ID));
};
tizen.TZDate.prototype.difference = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'other',
- type: types_.PLATFORM_OBJECT,
- values: tizen.TZDate
- }]);
-
- try {
- return makeMillisecondsDurationObject(this.getTime() - args.other.getTime());
- } catch (e) {
- _throwProperTizenException(e);
- }
+ console.log('Entered TZDate.difference');
+ var args = validator_.validateMethod(arguments, [
+ {
+ name : 'other',
+ type : validator_.Types.PLATFORM_OBJECT,
+ values : tizen.TZDate
+ }
+ ]);
+ var length = this._utcTimestamp - args.other._utcTimestamp;
+ var type = _timeDurationUnit.MSECS;
+ if (length % _timeDurationUnitValue.DAYS === 0) {
+ length /= _timeDurationUnitValue.DAYS;
+ type = _timeDurationUnit.DAYS;
+ }
+ return new tizen.TimeDuration(length, type);
};
tizen.TZDate.prototype.equalsTo = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'other',
- type: types_.PLATFORM_OBJECT,
- values: tizen.TZDate
- }]);
-
- try {
- return this.getTime() === args.other.getTime();
- } catch (e) {
- _throwProperTizenException(e);
- }
+ console.log('Entered TZDate.equalsTo');
+ var args = validator_.validateMethod(arguments, [
+ {
+ name : 'other',
+ type : validator_.Types.PLATFORM_OBJECT,
+ values : tizen.TZDate
+ }
+ ]);
+ return this._utcTimestamp === args.other._utcTimestamp;
};
tizen.TZDate.prototype.earlierThan = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'other',
- type: types_.PLATFORM_OBJECT,
- values: tizen.TZDate
- }]);
+ console.log('Entered TZDate.earlierThan');
+ var args = validator_.validateMethod(arguments, [
+ {
+ name : 'other',
+ type : validator_.Types.PLATFORM_OBJECT,
+ values : tizen.TZDate
+ }
+ ]);
+ return this._utcTimestamp < args.other._utcTimestamp;
+};
+
+tizen.TZDate.prototype.laterThan = function() {
+ console.log('Entered TZDate.laterThan');
+ var args = validator_.validateMethod(arguments, [
+ {
+ name : 'other',
+ type : validator_.Types.PLATFORM_OBJECT,
+ values : tizen.TZDate
+ }
+ ]);
+ return this._utcTimestamp > args.other._utcTimestamp;
+};
- try {
- return this.getTime() < args.other.getTime();
- } catch (e) {
- _throwProperTizenException(e);
- }
+tizen.TZDate.prototype.addDuration = function() {
+ console.log('Entered TZDate.addDuration');
+ var args = validator_.validateMethod(arguments, [
+ {
+ name : 'duration',
+ type : validator_.Types.PLATFORM_OBJECT,
+ values : tizen.TimeDuration
+ }
+ ]);
+ return new tizen.TZDate(new PrivateTZDate(this._utcTimestamp +
+ _getLengthInMsecsUnit(args.duration.length, args.duration.unit),
+ this._timezoneName));
};
-tizen.TZDate.prototype.laterThan = function(other) {
- var args = validator_.validateArgs(arguments, [{
- name: 'other',
- type: types_.PLATFORM_OBJECT,
- values: tizen.TZDate
- }]);
+tizen.TZDate.prototype.toLocaleDateString = function() {
+ console.log('Entered TZDate.toLocaleDateString');
+ var result = native_.callSync('TZDate_toLocaleDateString',
+ {timezone: String(this._timezoneName),
+ timestamp: String(this._utcTimestamp)});
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+ return native_.getResultObject(result).string;
+};
- try {
- return this.getTime() > args.other.getTime();
- } catch (e) {
- _throwProperTizenException(e);
+tizen.TZDate.prototype.toLocaleTimeString = function() {
+ console.log('Entered TZDate.toLocaleTimeString');
+ var result = native_.callSync('TZDate_toLocaleTimeString',
+ {timezone: String(this._timezoneName),
+ timestamp: String(this._utcTimestamp)});
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
}
+ return native_.getResultObject(result).string;
};
-tizen.TZDate.prototype.addDuration = function() {
- var args = validator_.validateArgs(arguments, [{
- name: 'duration',
- type: types_.PLATFORM_OBJECT,
- values: tizen.TimeDuration
- }]);
+tizen.TZDate.prototype.toLocaleString = function() {
+ console.log('Entered TZDate.toLocaleString');
+ var result = native_.callSync('TZDate_toLocaleString',
+ {timezone: String(this._timezoneName),
+ timestamp: String(this._utcTimestamp)});
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+ return native_.getResultObject(result).string;
+};
- try {
- var date = new tizen.TZDate(new Date(this.date_.getTime()), this.timezone_);
- date.setMilliseconds(args.duration.getMilliseconds() + date.getMilliseconds());
- return date;
- } catch (e) {
- _throwProperTizenException(e);
+tizen.TZDate.prototype.toDateString = function() {
+ console.log('Entered TZDate.toDateString');
+ var result = native_.callSync('TZDate_toDateString',
+ {timezone: String(this._timezoneName),
+ timestamp: String(this._utcTimestamp)});
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
}
+ return native_.getResultObject(result).string;
};
-tizen.TZDate.prototype.toLocaleDateString = function() {
- var result = native_.callSync('Time_toDateString', {
- timezone: this.timezone_,
- value: this.date_.getTime(),
- trans: '',
- locale: true
- });
+tizen.TZDate.prototype.toTimeString = function() {
+ console.log('Entered TZDate.toTimeString');
+ var result = native_.callSync('TZDate_toTimeString',
+ {timezone: String(this._timezoneName),
+ timestamp: String(this._utcTimestamp)});
if (native_.isFailure(result)) {
- return '';
+ throw native_.getErrorObject(result);
}
+ return native_.getResultObject(result).string;
+};
- return native_.getResultObject(result);
+tizen.TZDate.prototype.toString = function() {
+ console.log('Entered TZDate.toString');
+ var result = native_.callSync('TZDate_toString',
+ {timezone: String(this._timezoneName),
+ timestamp: String(this._utcTimestamp)});
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+ return native_.getResultObject(result).string;
};
-tizen.TZDate.prototype.toLocaleTimeString = function() {
- var result = native_.callSync('Time_toTimeString', {
- timezone: this.timezone_,
- value: this.date_.getTime(),
- trans: '',
- locale: true
- });
+tizen.TZDate.prototype.getTimezoneAbbreviation = function() {
+ console.log('Entered TZDate.getTimezoneAbbreviation');
+ var result = native_.callSync('TZDate_getTimezoneAbbreviation',
+ {timezone: String(this._timezoneName),
+ timestamp: String(this._utcTimestamp)});
if (native_.isFailure(result)) {
- return '';
+ throw native_.getErrorObject(result);
}
+ return native_.getResultObject(result).abbreviation;
+};
- return native_.getResultObject(result);
+tizen.TZDate.prototype.secondsFromUTC = function() {
+ console.log('Entered TZDate.secondsFromUTC');
+ return -this._timezoneOffset/1000;
};
-tizen.TZDate.prototype.toLocaleString = function() {
- var result = native_.callSync('Time_toString', {
- timezone: this.timezone_,
- value: this.date_.getTime(),
- trans: '',
- locale: true
- });
+tizen.TZDate.prototype.isDST = function() {
+ console.log('Entered TZDate.isDST');
+ var result = native_.callSync('TZDate_isDST',
+ {timezone: String(this._timezoneName),
+ timestamp: String(this._utcTimestamp)});
if (native_.isFailure(result)) {
- return '';
+ throw native_.getErrorObject(result);
}
-
- return native_.getResultObject(result);
+ return native_.getResultObject(result).isDST;
};
-tizen.TZDate.prototype.toDateString = function() {
- var result = native_.callSync('Time_toDateString', {
- timezone: this.timezone_,
- value: this.date_.getTime(),
- trans: '',
- locale: false
- });
+tizen.TZDate.prototype.getPreviousDSTTransition = function() {
+ console.log('Entered TZDate.getPreviousDSTTransition');
+ var result = native_.callSync('TZDate_getPreviousDSTTransition',
+ {timezone: String(this._timezoneName),
+ timestamp: String(this._utcTimestamp)});
if (native_.isFailure(result)) {
- return '';
+ throw native_.getErrorObject(result);
}
- return native_.getResultObject(result);
+ return new tizen.TZDate(new PrivateTZDate(native_.getResultObject(result).prevDSTDate,
+ this._timezoneName));
};
-tizen.TZDate.prototype.toTimeString = function() {
- var result = native_.callSync('Time_toTimeString', {
- timezone: this.timezone_,
- value: this.date_.getTime(),
- trans: '',
- locale: false
- });
+tizen.TZDate.prototype.getNextDSTTransition = function() {
+ console.log('Entered TZDate.getNextDSTTransition');
+ var result = native_.callSync('TZDate_getNextDSTTransition',
+ {timezone: String(this._timezoneName),
+ timestamp: String(this._utcTimestamp)});
if (native_.isFailure(result)) {
- return '';
+ throw native_.getErrorObject(result);
}
- return native_.getResultObject(result);
+ return new tizen.TZDate(new PrivateTZDate(native_.getResultObject(result).nextDSTDate,
+ this._timezoneName));
};
-tizen.TZDate.prototype.toString = function() {
- var result = native_.callSync('Time_toString', {
- timezone: this.timezone_,
- value: this.date_.getTime(),
- trans: '',
- locale: false
+//TimeUtil helpers ///////////////////////////////////////////////////
+var _timeDurationUnit = {
+ MSECS: 'MSECS',
+ SECS : 'SECS',
+ MINS : 'MINS',
+ HOURS: 'HOURS',
+ DAYS : 'DAYS'
+};
+
+var _timeDurationUnitValue = {
+ MSECS: Number(1),
+ SECS : Number(1000),
+ MINS : Number(60*1000),
+ HOURS: Number(60*60*1000),
+ DAYS : Number(24*60*60*1000)
+};
+
+function _getLengthInMsecsUnit(length, unit) {
+ if (unit === _timeDurationUnit.MSECS) {
+ return length;
+ } else if (unit === _timeDurationUnit.SECS) {
+ return length * _timeDurationUnitValue.SECS;
+ } else if (unit === _timeDurationUnit.MINS) {
+ return length * _timeDurationUnitValue.MINS;
+ } else if (unit === _timeDurationUnit.HOURS) {
+ return length * _timeDurationUnitValue.HOURS;
+ } else if (unit === _timeDurationUnit.DAYS) {
+ return length * _timeDurationUnitValue.DAYS;
+ } else {
+ native_.throwTypeMismatch();
+ }
+}
+
+function _convertMsecsToBiggestPossibleUnit(len) {
+ var length;
+ var unit;
+ if (len % _timeDurationUnitValue.DAYS === 0) {
+ length = len / _timeDurationUnitValue.DAYS;
+ unit = _timeDurationUnit.DAYS;
+ } else if (len % _timeDurationUnitValue.HOURS === 0) {
+ length = len / _timeDurationUnitValue.HOURS;
+ unit = _timeDurationUnit.HOURS;
+ } else if (len % _timeDurationUnitValue.MINS === 0) {
+ length = len / _timeDurationUnitValue.MINS;
+ unit = _timeDurationUnit.MINS;
+ } else if (len % _timeDurationUnitValue.SECS === 0) {
+ length = len / _timeDurationUnitValue.SECS;
+ unit = _timeDurationUnit.SECS;
+ } else {
+ length = len;
+ unit = _timeDurationUnit.MSECS;
+ }
+ return new tizen.TimeDuration(length, unit);
+}
+
+//class tizen.TimeDuration ////////////////////////////////////////////////////
+tizen.TimeDuration = function(length, unit) {
+ console.log('Entered TimeDuration constructor');
+ validator_.validateConstructorCall(this, tizen.TimeDuration);
+ var l, u;
+ if (arguments.length >= 2) {
+ l = converter_.toLongLong(length);
+ unit = converter_.toString(unit);
+ if (T.hasProperty(_timeDurationUnit, unit)) {
+ u = unit;
+ } else {
+ u = _timeDurationUnit.MSECS;
+ }
+ } else if (arguments.length === 1) {
+ l = converter_.toLongLong(length);
+ u = _timeDurationUnit.MSECS;
+ } else {
+ l = undefined;
+ u = undefined;
+ }
+ function lengthSetter(val) {
+ if (!T.isNullOrUndefined(val)) {
+ l = val;
+ }
+ }
+ function unitSetter(val) {
+ if (!T.isNullOrUndefined(val)) {
+ u = val;
+ }
+ }
+ Object.defineProperties(this, {
+ length : {
+ enumerable : true,
+ set : lengthSetter,
+ get : function() {
+ return l;
+ }
+ },
+ unit : {
+ enumerable : true,
+ set : unitSetter,
+ get : function() {
+ return u;
+ }
+ }
});
- if (native_.isFailure(result)) {
- return '';
+}
+
+tizen.TimeDuration.prototype.difference = function() {
+ console.log('Entered TimeDuration.difference');
+
+ var args = validator_.validateMethod(arguments, [
+ {
+ name : 'other',
+ type : validator_.Types.PLATFORM_OBJECT,
+ values : tizen.TimeDuration
+ }
+ ]);
+
+ if (this.unit === args.other.unit) {
+ return new tizen.TimeDuration(this.length - args.other.length, this.unit);
+ } else {
+ var l1 = _getLengthInMsecsUnit(this.length, this.unit);
+ var l2 = _getLengthInMsecsUnit(args.other.length, args.other.unit);
+ return _convertMsecsToBiggestPossibleUnit(l1 - l2);
}
+};
- return native_.getResultObject(result);
+tizen.TimeDuration.prototype.equalsTo = function() {
+ console.log('Entered TimeDuration.equalsTo');
+
+ var args = validator_.validateMethod(arguments, [
+ {
+ name : 'other',
+ type : validator_.Types.PLATFORM_OBJECT,
+ values : tizen.TimeDuration
+ }
+ ]);
+
+ if (this.unit === args.other.unit) {
+ return (this.length === args.other.length) ? true : false;
+ } else {
+ var l1 = _getLengthInMsecsUnit(this.length, this.unit);
+ var l2 = _getLengthInMsecsUnit(args.other.length, args.other.unit);
+ return (l1 === l2) ? true : false;
+ }
};
-tizen.TZDate.prototype.getTimezoneAbbreviation = function() {
- var result = native_.callSync('Time_getTimeZoneAbbreviation', {
- timezone: this.timezone_,
- value: this.date_.getTime()
- });
+tizen.TimeDuration.prototype.lessThan = function() {
+ console.log('Entered TimeDuration.lessThan');
+
+ var args = validator_.validateMethod(arguments, [
+ {
+ name : 'other',
+ type : validator_.Types.PLATFORM_OBJECT,
+ values : tizen.TimeDuration
+ }
+ ]);
+
+ if (this.unit === args.other.unit) {
+ return (this.length < args.other.length) ? true : false;
+ } else {
+ var l1 = _getLengthInMsecsUnit(this.length, this.unit);
+ var l2 = _getLengthInMsecsUnit(args.other.length, args.other.unit);
+ return (l1 < l2) ? true : false;
+ }
+};
+
+tizen.TimeDuration.prototype.greaterThan = function() {
+ console.log('Entered TimeDuration.greaterThan');
+
+ var args = validator_.validateMethod(arguments, [
+ {
+ name : 'other',
+ type : validator_.Types.PLATFORM_OBJECT,
+ values : tizen.TimeDuration
+ }
+ ]);
+
+ if (this.unit === args.other.unit) {
+ return (this.length > args.other.length) ? true : false;
+ } else {
+ var l1 = _getLengthInMsecsUnit(this.length, this.unit);
+ var l2 = _getLengthInMsecsUnit(args.other.length, args.other.unit);
+ return (l1 > l2) ? true : false;
+ }
+};
+
+
+//class TimeUtil ////////////////////////////////////////////////////
+exports.getCurrentDateTime = function() {
+ console.log('Entered TimeUtil.getCurrentDateTime');
+ return new tizen.TZDate();
+};
+
+exports.getLocalTimezone = function() {
+ console.log('Entered TimeUtil.getLocalTimezone');
+ var result = native_.callSync('TZDate_getTimezone', {});
if (native_.isFailure(result)) {
- return '';
+ throw native_.getErrorObject(result);
+ }
+ return native_.getResultObject(result).timezoneId;
+};
+
+var _availableTimezones = []; //an array for holding available timezones
+
+exports.getAvailableTimezones = function() {
+ console.log('Entered TimeUtil.getAvailableTimezones');
+ if (_availableTimezones.length === 0) {
+ var result = native_.callSync('TimeUtil_getAvailableTimezones', {});
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+ _availableTimezones = native_.getResultObject(result).availableTimezones;
}
- return native_.getResultObject(result);
+ return _availableTimezones.slice(0);
};
-tizen.TZDate.prototype.secondsFromUTC = function() {
- return this.date_.getTimezoneOffset() * 60;
+exports.getDateFormat = function() {
+ console.log('Entered TimeUtil.getDateFormat');
+
+ var args = validator_.validateMethod(arguments, [
+ {
+ name : 'shortformat',
+ type : validator_.Types.BOOLEAN,
+ optional : true,
+ nullable : true
+ }
+ ]);
+
+ if (!args.has.shortformat || T.isNull(args.shortformat)) {
+ args.shortformat = false;
+ }
+
+ var result = native_.callSync('TimeUtil_getDateFormat', {shortformat: args.shortformat});
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+ return native_.getResultObject(result).format;
};
-tizen.TZDate.prototype.isDST = function() {
- var result = native_.callSync('Time_isDST', {
- timezone: this.timezone_,
- value: getMsUTC(this.date_)
- });
+exports.getTimeFormat = function() {
+ console.log('Entered TimeUtil.getTimeFormat');
+ var result = native_.callSync('TimeUtil_getTimeFormat', {});
if (native_.isFailure(result)) {
- return false;
+ throw native_.getErrorObject(result);
}
+ return native_.getResultObject(result).format;
+};
+
+exports.isLeapYear = function() {
+ console.log('Entered TimeUtil.isLeapYear');
+
+ var args = validator_.validateMethod(arguments, [
+ {
+ name : 'year',
+ type : validator_.Types.LONG
+ }
+ ]);
- return native_.getResultObject(result);
+ // new Date(year, 1, 29).getMonth() === 1 <-- does not work for years 0-99
+ return ((args.year % 4 === 0) && (args.year % 100 !== 0)) || (args.year % 400 === 0);
};
-tizen.TZDate.prototype.getPreviousDSTTransition = function() {
- var result = native_.callSync('Time_getDSTTransition', {
- 'timezone': this.timezone_,
- 'value': getMsUTC(this.date_),
- 'trans': 'NEXT_TRANSITION'
- });
+
+var _timeUtilDateTimeChangeListener;
+function _timeChangedListenerCallback(eventObj) {
+ console.log("_timeChangedListenerCallback");
+ native_.callIfPossible(_timeUtilDateTimeChangeListener);
+}
+
+exports.setDateTimeChangeListener = function() {
+ console.log('Entered TimeUtil.setDateTimeChangeListener');
+ var args = validator_.validateMethod(arguments, [
+ {
+ name : 'changeCallback',
+ type : validator_.Types.FUNCTION
+ }
+ ]);
+ var result = native_.callSync('TimeUtil_setDateTimeChangeListener', {});
if (native_.isFailure(result)) {
- return null;
+ throw native_.getErrorObject(result);
}
- var _result = native_.getResultObject(result);
- if (result.error || _result === 0)
- return null;
+ _timeUtilDateTimeChangeListener = args.changeCallback;
+ native_.addListener("DateTimeChangeListener", _timeChangedListenerCallback);
+};
- var utc_time = getMsUTC(new Date(_result), this.timezone_);
- return new tizen.TZDate(new Date(utc_time)).toTimezone(this.timezone_);
+exports.unsetDateTimeChangeListener = function() {
+ console.log('Entered TimeUtil.unsetDateTimeChangeListener');
+ var result = native_.callSync('TimeUtil_unsetDateTimeChangeListener', {});
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+ native_.removeListener('DateTimeChangeListener');
+ _timeUtilDateTimeChangeListener = undefined;
};
-tizen.TZDate.prototype.getNextDSTTransition = function() {
- var result = native_.callSync('Time_getDSTTransition', {
- timezone: this.timezone_,
- value: getMsUTC(this.date_),
- trans: 'PREV_TRANSITION'
- });
+var _timeUtilTimezoneChangeListener;
+function _timezoneListenerCallback(eventObj) {
+ console.log("_timezoneListenerCallback");
+ native_.callIfPossible(_timeUtilTimezoneChangeListener);
+}
+
+exports.setTimezoneChangeListener = function() {
+ console.log('Entered TimeUtil.setTimezoneChangeListener');
+ var args = validator_.validateMethod(arguments, [
+ {
+ name : 'changeCallback',
+ type : validator_.Types.FUNCTION
+ }
+ ]);
+ var result = native_.callSync('TimeUtil_setTimezoneChangeListener', {});
if (native_.isFailure(result)) {
- return null;
+ throw native_.getErrorObject(result);
}
- var _result = native_.getResultObject(result);
- if (result.error || _result === 0)
- return null;
+ _timeUtilTimezoneChangeListener = args.changeCallback;
+ native_.addListener('TimezoneChangeListener',
+ _timezoneListenerCallback);
- var utc_time = getMsUTC(new Date(_result), this.timezone_);
- return new tizen.TZDate(new Date(utc_time)).toTimezone(this.timezone_);
};
+
+exports.unsetTimezoneChangeListener = function() {
+ console.log('Entered TimeUtil.unsetTimezoneChangeListener');
+ native_.removeListener('TimezoneChangeListener');
+ var result = native_.callSync('TimeUtil_unsetTimezoneChangeListener', {});
+ _timeUtilTimezoneChangeListener = undefined;
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+};
\ No newline at end of file
// found in the LICENSE file.
#include "time/time_instance.h"
-#include "common/platform_exception.h"
#include "common/logger.h"
-
-#if defined(TIZEN)
-#include <vconf.h>
-#endif
-
-#include <sstream>
-#include <memory>
-#include <cerrno>
-#include <unistd.h>
-
#include "common/picojson.h"
#include "common/platform_result.h"
-#include "unicode/timezone.h"
-#include "unicode/calendar.h"
-#include "unicode/vtzone.h"
-#include "unicode/tztrans.h"
-#include "unicode/smpdtfmt.h"
-#include "unicode/dtptngen.h"
-
namespace extension {
namespace time {
using namespace common;
-enum ListenerType {
- kTimeChange,
- kTimezoneChange
-};
-
-namespace {
-
-const int _hourInMilliseconds = 3600000;
-const char kTimezoneListenerId[] = "TimezoneChangeListener";
-const char kDateTimeListenerId[] = "DateTimeChangeListener";
-
-} // namespace
-
-TimeInstance::TimeInstance() {
+TimeInstance::TimeInstance() : manager_(this) {
using std::placeholders::_1;
using std::placeholders::_2;
LoggerD("Entered");
#define REGISTER_SYNC(c, x) \
- RegisterSyncHandler(c, std::bind(&TimeInstance::x, this, _1, _2));
+ RegisterSyncHandler(c, std::bind(&TimeInstance::x, this, _1, _2));
#define REGISTER_ASYNC(c, x) \
- RegisterSyncHandler(c, std::bind(&TimeInstance::x, this, _1, _2));
-
- REGISTER_SYNC("Time_getAvailableTimeZones", TimeGetAvailableTimeZones);
- REGISTER_SYNC("Time_getDSTTransition", TimeGetDSTTransition);
- REGISTER_SYNC("Time_getLocalTimeZone", TimeGetLocalTimeZone);
- REGISTER_SYNC("Time_getTimeFormat", TimeGetTimeFormat);
- REGISTER_SYNC("Time_getDateFormat", TimeGetDateFormat);
- REGISTER_SYNC("Time_getTimeZoneOffset", TimeGetTimeZoneOffset);
- REGISTER_SYNC("Time_getTimeZoneAbbreviation", TimeGetTimeZoneAbbreviation);
- REGISTER_SYNC("Time_isDST", TimeIsDST);
- REGISTER_SYNC("Time_toString", TimeToString);
- REGISTER_SYNC("Time_toDateString", TimeToDateString);
- REGISTER_SYNC("Time_toTimeString", TimeToTimeString);
- REGISTER_SYNC("Time_setDateTimeChangeListener",
- TimeSetDateTimeChangeListener);
- REGISTER_SYNC("Time_unsetDateTimeChangeListener",
- TimeUnsetDateTimeChangeListener);
- REGISTER_SYNC("Time_setTimezoneChangeListener",
- TimeSetTimezoneChangeListener);
- REGISTER_SYNC("Time_unsetTimezoneChangeListener",
- TimeUnsetTimezoneChangeListener);
- REGISTER_SYNC("Time_getMsUTC", TimeGetMsUTC);
+ RegisterSyncHandler(c, std::bind(&TimeInstance::x, this, _1, _2));
+
+ REGISTER_SYNC("TimeUtil_getAvailableTimezones", TimeUtil_getAvailableTimezones);
+ REGISTER_SYNC("TimeUtil_getDateFormat", TimeUtil_getDateFormat);
+ REGISTER_SYNC("TimeUtil_getTimeFormat", TimeUtil_getTimeFormat);
+ REGISTER_SYNC("TimeUtil_setDateTimeChangeListener", TimeUtil_setDateTimeChangeListener);
+ REGISTER_SYNC("TimeUtil_unsetDateTimeChangeListener", TimeUtil_unsetDateTimeChangeListener);
+ REGISTER_SYNC("TimeUtil_setTimezoneChangeListener", TimeUtil_setTimezoneChangeListener);
+ REGISTER_SYNC("TimeUtil_unsetTimezoneChangeListener", TimeUtil_unsetTimezoneChangeListener);
+ REGISTER_SYNC("TZDate_getTimezone", TZDate_getTimezone);
+ REGISTER_SYNC("TZDate_getTimezoneOffset", TZDate_GetTimezoneOffset);
+ REGISTER_SYNC("TZDate_toLocaleDateString", TZDate_toLocaleDateString);
+ REGISTER_SYNC("TZDate_toLocaleTimeString", TZDate_toLocaleTimeString);
+ REGISTER_SYNC("TZDate_toLocaleString", TZDate_toLocaleString);
+ REGISTER_SYNC("TZDate_toDateString", TZDate_toDateString);
+ REGISTER_SYNC("TZDate_toTimeString", TZDate_toTimeString);
+ REGISTER_SYNC("TZDate_toString", TZDate_toString);
+ REGISTER_SYNC("TZDate_getTimezoneAbbreviation", TZDate_getTimezoneAbbreviation);
+ REGISTER_SYNC("TZDate_isDST", TZDate_isDST);
+ REGISTER_SYNC("TZDate_getPreviousDSTTransition", TZDate_getPreviousDSTTransition);
+ REGISTER_SYNC("TZDate_getNextDSTTransition", TZDate_getNextDSTTransition);
#undef REGISTER_SYNC
#undef REGISTER_ASYNC
}
-static void OnTimeChangedCallback(keynode_t* /*node*/, void* user_data);
-static std::string GetDefaultTimezone();
-
TimeInstance::~TimeInstance() {
- LoggerD("Entered");
-}
-
-void TimeInstance::TimeGetLocalTimeZone(const JsonValue& /*args*/,
- JsonObject& out) {
- LoggerD("Entered");
-
- UnicodeString local_timezone;
- TimeZone* timezone = TimeZone::createDefault();
- if (nullptr != timezone) {
- timezone->getID(local_timezone);
- delete timezone;
-
- std::string localtz;
- local_timezone.toUTF8String(localtz);
-
- ReportSuccess(JsonValue(localtz), out);
- } else {
- ReportError(out);
- }
-}
-
-void TimeInstance::TimeGetAvailableTimeZones(const JsonValue& /*args*/,
- JsonObject& out) {
LoggerD("Entered");
-
- UErrorCode ec = U_ZERO_ERROR;
- std::unique_ptr<StringEnumeration> timezones(TimeZone::createEnumeration());
- int32_t count = timezones->count(ec);
- if (U_FAILURE(ec)) {
- LoggerE("Failed to get timezones.");
- ReportError(out);
- return;
- }
-
- JsonArray a;
- const char* timezone = NULL;
- int i = 0;
- do {
- int32_t resultLen = 0;
- timezone = timezones->next(&resultLen, ec);
- if (U_SUCCESS(ec)) {
- a.push_back(JsonValue(timezone));
- i++;
- }
- } while (timezone && i < count);
-
- ReportSuccess(JsonValue(a), out);
}
-void TimeInstance::TimeGetTimeZoneOffset(const JsonValue& args,
- JsonObject& out) {
+void TimeInstance::TimeUtil_getAvailableTimezones(const picojson::value& /*args*/,
+ picojson::object& out) {
LoggerD("Entered");
-
- std::unique_ptr<UnicodeString> id(
- new UnicodeString(args.get("timezone").to_str().c_str()));
- UDate dateInMs = strtod(args.get("value").to_str().c_str(), NULL);
-
- if (errno == ERANGE) {
- LoggerE("Value out of range");
- ReportError(out);
- return;
- }
-
- UErrorCode ec = U_ZERO_ERROR;
- std::unique_ptr<TimeZone> timezone(TimeZone::createTimeZone(*id));
-
- int32_t rawOffset = 0;
- int32_t dstOffset = 0;
- timezone->getOffset(dateInMs, false, rawOffset, dstOffset, ec);
- if (U_FAILURE(ec)) {
- LoggerE("Failed to get timezone offset");
- ReportError(out);
+ picojson::value result = picojson::value(picojson::object());
+ picojson::object& result_obj = result.get<picojson::object>();
+
+ auto array = result_obj.insert(std::make_pair("availableTimezones",
+ picojson::value(picojson::array())));
+ PlatformResult res = TimeUtilTools::GetAvailableTimezones(
+ &array.first->second.get<picojson::array>());
+ if (res.IsError()) {
+ ReportError(res, &out);
return;
}
- std::stringstream offsetStr;
- offsetStr << (rawOffset + dstOffset);
- ReportSuccess(JsonValue(offsetStr.str()), out);
+ ReportSuccess(result, out);
}
-void TimeInstance::TimeGetTimeZoneAbbreviation(const JsonValue& args,
- JsonObject& out) {
+void TimeInstance::TimeUtil_getDateFormat(const picojson::value& args, picojson::object& out) {
LoggerD("Entered");
-
- std::unique_ptr<UnicodeString> id(
- new UnicodeString(args.get("timezone").to_str().c_str()));
- UDate dateInMs = strtod(args.get("value").to_str().c_str(), NULL);
-
- if (errno == ERANGE) {
- LoggerE("Value out of range");
- ReportError(out);
+ if (!args.contains("shortformat")) {
+ LoggerE("Invalid parameter passed.");
+ ReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."), &out);
return;
}
- UErrorCode ec = U_ZERO_ERROR;
- std::unique_ptr<TimeZone> timezone(TimeZone::createTimeZone(*id));
- std::unique_ptr<Calendar> cal(Calendar::createInstance(*timezone, ec));
- if (U_FAILURE(ec)) {
- LoggerE("Failed to create Calendar instance");
- ReportError(out);
+ bool shortformat = args.get("shortformat").get<bool>();
+ std::string format;
+ PlatformResult res = TimeUtilTools::GetDateFormat(shortformat, &format);
+ if (res.IsError()) {
+ ReportError(res, &out);
return;
}
- cal->setTime(dateInMs, ec);
- if (U_FAILURE(ec)) {
- LoggerE("Failed to set date");
- ReportError(out);
- return;
- }
-
- std::unique_ptr<DateFormat> fmt(
- new SimpleDateFormat(UnicodeString("z"), Locale::getEnglish(), ec));
- if (U_FAILURE(ec)) {
- LoggerE("Failed to create format object");
- ReportError(out);
- return;
- }
+ picojson::value result = picojson::value(picojson::object());
+ picojson::object& result_obj = result.get<picojson::object>();
+ result_obj.insert(std::make_pair("format", picojson::value(format)));
- UnicodeString uAbbreviation;
- fmt->setCalendar(*cal);
- fmt->format(cal->getTime(ec), uAbbreviation);
- if (U_FAILURE(ec)) {
- LoggerE("Failed to format object");
- ReportError(out);
- return;
- }
-
- std::string abbreviation = "";
- uAbbreviation.toUTF8String(abbreviation);
-
- ReportSuccess(JsonValue(abbreviation), out);
+ ReportSuccess(result, out);
}
-void TimeInstance::TimeIsDST(const JsonValue& args, JsonObject& out) {
+void TimeInstance::TimeUtil_getTimeFormat(const picojson::value& /* args */,
+ picojson::object& out) {
LoggerD("Entered");
-
- std::unique_ptr<UnicodeString> id(
- new UnicodeString(args.get("timezone").to_str().c_str()));
- UDate dateInMs = strtod(args.get("value").to_str().c_str(), NULL);
-
- if (errno == ERANGE) {
- LoggerE("Value out of range");
- ReportError(out);
+ std::string format;
+ PlatformResult res = TimeUtilTools::GetTimeFormat(&format);
+ if (res.IsError()) {
+ ReportError(res, &out);
return;
}
- UErrorCode ec = U_ZERO_ERROR;
- std::unique_ptr<TimeZone> timezone(TimeZone::createTimeZone(*id));
+ picojson::value result = picojson::value(picojson::object());
+ picojson::object& result_obj = result.get<picojson::object>();
+ result_obj.insert(std::make_pair("format", picojson::value(format)));
- int32_t rawOffset = 0;
- int32_t dstOffset = 0;
- timezone->getOffset(dateInMs, false, rawOffset, dstOffset, ec);
- if (U_FAILURE(ec)) {
- LoggerE("Failed to get timezone offset");
- ReportError(out);
- return;
- }
- ReportSuccess(JsonValue{static_cast<bool>(dstOffset)}, out);
+ ReportSuccess(result, out);
}
-void TimeInstance::TimeGetDSTTransition(const JsonValue& args,
- JsonObject& out) {
+void TimeInstance::TimeUtil_setDateTimeChangeListener(const picojson::value& /*args*/,
+ picojson::object& out) {
LoggerD("Entered");
-
- std::unique_ptr<UnicodeString> id(
- new UnicodeString(args.get("timezone").to_str().c_str()));
- std::string trans = args.get("trans").to_str();
- UDate dateInMs = strtod(args.get("value").to_str().c_str(), NULL);
-
- if (errno == ERANGE) {
- LoggerE("Value out of range");
- ReportError(out);
- return;
- }
-
- std::unique_ptr<VTimeZone> vtimezone(VTimeZone::createVTimeZoneByID(*id));
-
- if (!vtimezone->useDaylightTime()) {
- LoggerE("Failed to set DST");
- ReportError(out);
- return;
- }
-
- TimeZoneTransition tzTransition;
- if (trans.compare("NEXT_TRANSITION") &&
- vtimezone->getNextTransition(dateInMs, FALSE, tzTransition)) {
- ReportSuccess(JsonValue{tzTransition.getTime()}, out);
- } else if (vtimezone->getPreviousTransition(dateInMs, FALSE, tzTransition)) {
- ReportSuccess(JsonValue{tzTransition.getTime()}, out);
- } else {
- LoggerE("Error while getting transition");
- ReportError(out);
+ PlatformResult res = manager_.RegisterVconfCallback(kTimeChange);
+ if (res.IsError()) {
+ ReportError(res, &out);
}
+ ReportSuccess(out);
}
-void TimeInstance::TimeToString(const JsonValue& args, JsonObject& out) {
- JsonValue val;
+void TimeInstance::TimeUtil_unsetDateTimeChangeListener(const picojson::value& /*args*/,
+ picojson::object& out) {
LoggerD("Entered");
-
- if (!this->toStringByFormat(args, val, TimeInstance::DATETIME_FORMAT)) {
- LoggerE("Failed to convert to string");
- ReportError(out);
- return;
+ PlatformResult res = manager_.UnregisterVconfCallback(kTimeChange);
+ if (res.IsError()) {
+ ReportError(res, &out);
}
-
- ReportSuccess(val, out);
+ ReportSuccess(out);
}
-void TimeInstance::TimeToDateString(const JsonValue& args, JsonObject& out) {
- JsonValue val;
+void TimeInstance::TimeUtil_setTimezoneChangeListener(const picojson::value& /*args*/,
+ picojson::object& out) {
LoggerD("Entered");
-
- if (!this->toStringByFormat(args, val, TimeInstance::DATE_FORMAT)) {
- LoggerE("Failed to convert to string");
- ReportError(out);
- return;
+ PlatformResult res = manager_.RegisterVconfCallback(kTimezoneChange);
+ if (res.IsError()) {
+ ReportError(res, &out);
}
-
- ReportSuccess(val, out);
+ ReportSuccess(out);
}
-void TimeInstance::TimeToTimeString(const JsonValue& args, JsonObject& out) {
- JsonValue val;
+void TimeInstance::TimeUtil_unsetTimezoneChangeListener(const picojson::value& /*args*/,
+ picojson::object& out) {
LoggerD("Entered");
-
- if (!this->toStringByFormat(args, val, TimeInstance::TIME_FORMAT)) {
- LoggerE("Failed to convert to string");
- ReportError(out);
- return;
+ PlatformResult res = manager_.UnregisterVconfCallback(kTimezoneChange);
+ if (res.IsError()) {
+ ReportError(res, &out);
}
-
- ReportSuccess(val, out);
+ ReportSuccess(out);
}
-bool TimeInstance::toStringByFormat(const JsonValue& args, JsonValue& out,
- DateTimeFormatType format) {
+void TimeInstance::TZDate_getTimezone(const picojson::value& /*args*/, picojson::object& out) {
LoggerD("Entered");
- std::unique_ptr<UnicodeString> id(
- new UnicodeString(args.get("timezone").to_str().c_str()));
- bool bLocale = args.get("locale").evaluate_as_boolean();
+ std::string local_timezone = TimeManager::GetDefaultTimezone();
- UDate dateInMs = strtod(args.get("value").to_str().c_str(), NULL);
- if (errno == ERANGE) {
- LoggerE("Value out of range");
- return false;
- }
-
- UErrorCode ec = U_ZERO_ERROR;
- std::unique_ptr<TimeZone> timezone(TimeZone::createTimeZone(*id));
- std::unique_ptr<Calendar> cal(Calendar::createInstance(*timezone, ec));
- if (U_FAILURE(ec)) {
- LoggerE("Failed to create Calendar instance");
- return false;
- }
-
- cal->setTime(dateInMs, ec);
- if (U_FAILURE(ec)) {
- LoggerE("Failed to set time");
- return false;
- }
-
- std::unique_ptr<DateFormat> fmt(new SimpleDateFormat(
- getDateTimeFormat(format, bLocale),
- (bLocale ? Locale::getDefault() : Locale::getEnglish()), ec));
- if (U_FAILURE(ec)) {
- LoggerE("Failed to create format object");
- return false;
- }
+ picojson::value result = picojson::value(picojson::object());
+ picojson::object& result_obj = result.get<picojson::object>();
+ result_obj.insert(std::make_pair("timezoneId", picojson::value(local_timezone)));
- UnicodeString uResult;
- fmt->setCalendar(*cal);
- fmt->format(cal->getTime(ec), uResult);
- if (U_FAILURE(ec)) {
- LoggerE("Failed to format object");
- return false;
- }
-
- std::string result = "";
- uResult.toUTF8String(result);
-
- out = JsonValue(result);
- return true;
-}
-
-void TimeInstance::TimeGetTimeFormat(const JsonValue& /*args*/,
- JsonObject& out) {
- LoggerD("Entered");
-
- UnicodeString timeFormat = getDateTimeFormat(TimeInstance::TIME_FORMAT, true);
-
- timeFormat = timeFormat.findAndReplace("H", "h");
- timeFormat = timeFormat.findAndReplace("a", "ap");
-
- timeFormat = timeFormat.findAndReplace("hh", "h");
- timeFormat = timeFormat.findAndReplace("mm", "m");
- timeFormat = timeFormat.findAndReplace("ss", "s");
-
- std::string result = "";
- timeFormat.toUTF8String(result);
-
- ReportSuccess(JsonValue(result), out);
+ ReportSuccess(result, out);
}
-void TimeInstance::TimeGetDateFormat(const JsonValue& args, JsonObject& out) {
+void TimeInstance::TZDate_GetTimezoneOffset(const picojson::value& args,
+ picojson::object& out) {
LoggerD("Entered");
-
- bool shortformat = args.get("shortformat").evaluate_as_boolean();
- UnicodeString time_format =
- getDateTimeFormat((shortformat ? DateTimeFormatType::DATE_SHORT_FORMAT
- : DateTimeFormatType::DATE_FORMAT),
- true);
-
- time_format = time_format.findAndReplace("E", "D");
-
- if (time_format.indexOf("MMM") > 0) {
- if (time_format.indexOf("MMMM") > 0) {
- time_format = time_format.findAndReplace("MMMM", "M");
- } else {
- time_format = time_format.findAndReplace("MMM", "M");
- }
- } else {
- time_format = time_format.findAndReplace("M", "m");
+ if (!args.contains("timezone") || !args.contains("timestamp")) {
+ LoggerE("Invalid parameter passed.");
+ ReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."), &out);
+ return;
}
-
- int i = 0;
- while (i < time_format.length() - 1) {
- if (time_format[i] == time_format[i + 1]) {
- time_format.remove(i, 1);
- } else {
- ++i;
- }
+ const std::string& timezone_id = args.get("timezone").get<std::string>();
+ LoggerD("Getting timezone details for id: %s ", timezone_id.c_str());
+
+ const std::string& timestamp_str = args.get("timestamp").get<std::string>();
+
+ std::string offset;
+ std::string modifier;
+ PlatformResult res = manager_.GetTimezoneOffset(timezone_id, timestamp_str,
+ &offset, &modifier);
+ if (res.IsSuccess()) {
+ picojson::value result = picojson::value(picojson::object());
+ picojson::object& result_obj = result.get<picojson::object>();
+ result_obj.insert(std::make_pair("offset", picojson::value(offset)));
+ //this value is to correct 'missing' hour also in JS
+ result_obj.insert(std::make_pair("modifier", picojson::value(modifier)));
+ ReportSuccess(result, out);
+ } else {
+ ReportError(res, &out);
}
-
- std::string result = "";
- time_format.toUTF8String(result);
- ReportSuccess(JsonValue(result), out);
}
-Locale* TimeInstance::getDefaultLocale() {
- char *tempstr = vconf_get_str(VCONFKEY_REGIONFORMAT);
- if (NULL == tempstr){
- return NULL;
- }
-
- Locale *defaultLocale = NULL;
-
- char *str_region = NULL;
- char* p = strchr(tempstr, '.');
- int len = strlen(tempstr) - (p != nullptr ? strlen(p) : 0);
- if (len > 0) {
- str_region = strndup(tempstr, len); //.UTF8 => 5
- defaultLocale = new Locale(str_region);
- }
-
- free(tempstr);
- free(str_region);
-
- if (defaultLocale) {
- if (defaultLocale->isBogus()) {
- delete defaultLocale;
- defaultLocale = NULL;
- }
- }
-
- return defaultLocale;
-}
-
-UnicodeString TimeInstance::getDateTimeFormat(DateTimeFormatType type,
- bool bLocale) {
+void TimeInstance::ToStringTemplate(const picojson::value& args,
+ bool use_locale_fmt,
+ TimeUtilTools::DateTimeFormatType type,
+ picojson::object* out) {
LoggerD("Entered");
- LoggerD("bLocale %d", bLocale);
-
- UErrorCode ec = U_ZERO_ERROR;
- Locale *defaultLocale = getDefaultLocale();
- std::unique_ptr<DateTimePatternGenerator> dateTimepattern(
- DateTimePatternGenerator::createInstance(
- ((bLocale && defaultLocale) ? *defaultLocale : Locale::getEnglish()), ec));
+ if (!args.contains("timezone") || !args.contains("timestamp")) {
+ LoggerE("Invalid parameter passed.");
+ ReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."), out);
+ return;
+ }
+ const std::string& timezone_id = args.get("timezone").get<std::string>();
+ std::shared_ptr<UnicodeString> unicode_id (new UnicodeString(timezone_id.c_str()));
+ LoggerD("Getting timezone details for id: %s ", timezone_id.c_str());
- delete defaultLocale;
+ const std::string& timestamp_str = args.get("timestamp").get<std::string>();
+ UDate date = std::stod(timestamp_str);
- if (U_FAILURE(ec)) {
- LoggerE("Failed to create Calendar instance");
- return "";
+ std::string result_string;
+ PlatformResult res = TimeUtilTools::ToStringHelper(date, unicode_id, use_locale_fmt,
+ type, &result_string);
+ if (res.IsError()) {
+ ReportError(res, out);
+ return;
}
- UnicodeString pattern;
- if (type == DATE_FORMAT) {
- pattern = dateTimepattern->getBestPattern(UDAT_YEAR_MONTH_WEEKDAY_DAY, ec);
- } else if (type == DATE_SHORT_FORMAT) {
- pattern = dateTimepattern->getBestPattern(UDAT_YEAR_NUM_MONTH_DAY, ec);
- } else {
- std::string skeleton;
- if (type != TIME_FORMAT) skeleton = UDAT_YEAR_MONTH_WEEKDAY_DAY;
-
-#if defined(TIZEN)
- int ret = 0;
- int value = 0;
- ret = vconf_get_int(VCONFKEY_REGIONFORMAT_TIME1224, &value);
- // if failed, set default time format
- if (-1 == ret) {
- value = VCONFKEY_TIME_FORMAT_12;
- }
- if (VCONFKEY_TIME_FORMAT_12 == value) {
- skeleton += "hhmmss";
- } else {
- skeleton += "HHmmss";
- }
-#else
- skeleton += "hhmmss";
-#endif
-
- pattern = dateTimepattern->getBestPattern(
- UnicodeString(skeleton.c_str()), ec);
- if (U_FAILURE(ec)) {
- LoggerE("Failed to get time pattern");
- return "";
- }
-
- if (!bLocale) pattern += " 'GMT'Z v'";
- }
+ picojson::value result = picojson::value(picojson::object());
+ picojson::object& result_obj = result.get<picojson::object>();
+ result_obj.insert(
+ std::make_pair("string", picojson::value(result_string)));
- return pattern;
+ ReportSuccess(result, *out);
}
-/////////////////////////// TimeUtilListeners ////////////////////////////////
-
-class TimeUtilListeners {
- public:
- TimeUtilListeners();
- ~TimeUtilListeners();
-
- PlatformResult RegisterVconfCallback(ListenerType type, TimeInstance& instance);
- PlatformResult UnregisterVconfCallback(ListenerType type);
-
- std::string GetCurrentTimezone();
- void SetCurrentTimezone(std::string& newTimezone);
-
- private:
- std::string current_timezone_;
- bool is_time_listener_registered_;
- bool is_timezone_listener_registered_;
-};
-
-TimeUtilListeners::TimeUtilListeners()
- : current_timezone_(GetDefaultTimezone()),
- is_time_listener_registered_(false),
- is_timezone_listener_registered_(false) {
+void TimeInstance::TZDate_toLocaleDateString(const picojson::value& args, picojson::object& out) {
LoggerD("Entered");
+ ToStringTemplate(args, true, TimeUtilTools::DateTimeFormatType::kDateFormat, &out);
}
-TimeUtilListeners::~TimeUtilListeners() {
+void TimeInstance::TZDate_toLocaleTimeString(const picojson::value& args, picojson::object& out) {
LoggerD("Entered");
- if (is_time_listener_registered_ || is_timezone_listener_registered_) {
- if (0 != vconf_ignore_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
- OnTimeChangedCallback)) {
- LoggerE("Failed to unregister vconf callback");
- }
- }
+ ToStringTemplate(args, true, TimeUtilTools::DateTimeFormatType::kTimeFormat, &out);
}
-PlatformResult TimeUtilListeners::RegisterVconfCallback(ListenerType type, TimeInstance& instance) {
+void TimeInstance::TZDate_toLocaleString(const picojson::value& args, picojson::object& out) {
LoggerD("Entered");
-
- if (!is_time_listener_registered_ && !is_timezone_listener_registered_) {
- LoggerD("registering listener on platform");
- if (0 != vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
- OnTimeChangedCallback, static_cast<void*>(&instance))) {
- LoggerE("Failed to register vconf callback");
- return PlatformResult(ErrorCode::UNKNOWN_ERR,
- "Failed to register vconf callback");
- }
- } else {
- LoggerD("not registering listener on platform - already registered");
- }
- switch (type) {
- case kTimeChange:
- is_time_listener_registered_ = true;
- LoggerD("time change listener registered");
- break;
- case kTimezoneChange:
- is_timezone_listener_registered_ = true;
- LoggerD("time zone change listener registered");
- break;
- default:
- LoggerE("Unknown type of listener");
- return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown type of listener");
- }
- return PlatformResult(ErrorCode::NO_ERROR);
+ ToStringTemplate(args, true, TimeUtilTools::DateTimeFormatType::kDateTimeFormat, &out);
}
-PlatformResult TimeUtilListeners::UnregisterVconfCallback(ListenerType type) {
+void TimeInstance::TZDate_toDateString(const picojson::value& args, picojson::object& out) {
LoggerD("Entered");
-
- switch (type) {
- case kTimeChange:
- is_time_listener_registered_ = false;
- LoggerD("time change listener unregistered");
- break;
- case kTimezoneChange:
- is_timezone_listener_registered_ = false;
- LoggerD("time zone change listener unregistered");
- break;
- default:
- return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown type of listener");
- }
- if (!is_time_listener_registered_ && !is_timezone_listener_registered_) {
- LoggerD("unregistering listener on platform");
- if (0 != vconf_ignore_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
- OnTimeChangedCallback)) {
- LoggerE("Failed to unregister vconf callback");
- }
- }
- return PlatformResult(ErrorCode::NO_ERROR);
+ ToStringTemplate(args, false, TimeUtilTools::DateTimeFormatType::kDateFormat, &out);
}
-std::string TimeUtilListeners::GetCurrentTimezone() {
- return current_timezone_;
-}
-
-void TimeUtilListeners::SetCurrentTimezone(std::string& newTimezone) {
- current_timezone_ = newTimezone;
-}
-
-static std::string GetDefaultTimezone() {
+void TimeInstance::TZDate_toTimeString(const picojson::value& args, picojson::object& out) {
LoggerD("Entered");
-
- char buf[1024];
- std::string result;
- ssize_t len = readlink("/opt/etc/localtime", buf, sizeof(buf) - 1);
- if (len != -1) {
- buf[len] = '\0';
- } else {
- /* handle error condition */
- LoggerE("Error while reading link - incorrect length");
- return result;
- }
- result = std::string(buf + strlen("/usr/share/zoneinfo/"));
-
- LoggerD("tzpath = %s", result.c_str());
- return result;
+ ToStringTemplate(args, false, TimeUtilTools::DateTimeFormatType::kTimeFormat, &out);
}
-/////////////////////////// TimeUtilListeners object ////////////////////////
-static TimeUtilListeners g_time_util_listeners_obj;
-
-static void PostMessage(const char* message, TimeInstance& instance) {
+void TimeInstance::TZDate_toString(const picojson::value& args, picojson::object& out) {
LoggerD("Entered");
-
- JsonValue result{JsonObject{}};
- JsonObject& result_obj = result.get<JsonObject>();
- result_obj.insert(std::make_pair("listenerId", picojson::value(message)));
- Instance::PostMessage(&instance, result.serialize().c_str());
+ ToStringTemplate(args, false, TimeUtilTools::DateTimeFormatType::kDateTimeFormat, &out);
}
-static void OnTimeChangedCallback(keynode_t* /*node*/, void* user_data) {
+void TimeInstance::TZDate_getTimezoneAbbreviation(const picojson::value& args,
+ picojson::object& out) {
LoggerD("Entered");
-
- TimeInstance *that = static_cast<TimeInstance*>(user_data);
- if (!that) {
- LoggerE("instance is NULL");
+ if (!args.contains("timezone") || !args.contains("timestamp")) {
+ LoggerE("Invalid parameter passed.");
+ ReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."), &out);
return;
}
+ const std::string& timezone_id = args.get("timezone").get<std::string>();
+ std::shared_ptr<UnicodeString> unicode_id (new UnicodeString(timezone_id.c_str()));
- std::string defaultTimezone = GetDefaultTimezone();
+ const std::string& timestamp_str = args.get("timestamp").get<std::string>();
+ UDate date = std::stod(timestamp_str);
- if (g_time_util_listeners_obj.GetCurrentTimezone() != defaultTimezone) {
- g_time_util_listeners_obj.SetCurrentTimezone(defaultTimezone);
- PostMessage(kTimezoneListenerId, *that);
+ std::string result_string;
+ PlatformResult res = TimeUtilTools::GetTimezoneAbbreviation(date, unicode_id, &result_string);
+ if (res.IsError()) {
+ ReportError(res, &out);
+ return;
}
- PostMessage(kDateTimeListenerId, *that);
-}
-void TimeInstance::TimeSetDateTimeChangeListener(const JsonValue& /*args*/,
- JsonObject& out) {
- LoggerD("Entered");
+ picojson::value result = picojson::value(picojson::object());
+ picojson::object& result_obj = result.get<picojson::object>();
+ result_obj.insert(std::make_pair("abbreviation", picojson::value(result_string)));
- PlatformResult result =
- g_time_util_listeners_obj.RegisterVconfCallback(kTimeChange, *this);
- if (result.IsError()) {
- LoggerE("Error while registering vconf callback");
- ReportError(result, &out);
- }
- else
- ReportSuccess(out);
+ ReportSuccess(result, out);
}
-void TimeInstance::TimeUnsetDateTimeChangeListener(const JsonValue& /*args*/,
- JsonObject& out) {
+void TimeInstance::TZDate_isDST(const picojson::value& args, picojson::object& out) {
LoggerD("Entered");
-
- PlatformResult result =
- g_time_util_listeners_obj.UnregisterVconfCallback(kTimeChange);
- if (result.IsError()) {
- LoggerE("Failed to unregister vconf callback");
- ReportError(result, &out);
+ if (!args.contains("timezone") || !args.contains("timestamp")) {
+ LoggerE("Invalid parameter passed.");
+ ReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."), &out);
+ return;
}
- else
- ReportSuccess(out);
-}
+ const std::string& timezone_id = args.get("timezone").get<std::string>();
+ std::shared_ptr<UnicodeString> unicode_id (new UnicodeString(timezone_id.c_str()));
-void TimeInstance::TimeSetTimezoneChangeListener(const JsonValue& /*args*/,
- JsonObject& out) {
- LoggerD("Entered");
+ const std::string& timestamp_str = args.get("timestamp").get<std::string>();
+ UDate date = std::stod(timestamp_str);
- PlatformResult result =
- g_time_util_listeners_obj.RegisterVconfCallback(kTimezoneChange, *this);
- if (result.IsError()) {
- LoggerE("Failed to register vconf callback");
- ReportError(result, &out);
+ bool is_dst = false;
+ PlatformResult res = TimeUtilTools::IsDST(date, unicode_id, &is_dst);
+ if (res.IsError()) {
+ ReportError(res, &out);
+ return;
}
- else
- ReportSuccess(out);
+ picojson::value result = picojson::value(picojson::object());
+ picojson::object& result_obj = result.get<picojson::object>();
+ result_obj.insert(
+ std::make_pair("isDST", picojson::value(is_dst)));
+ ReportSuccess(result, out);
}
-void TimeInstance::TimeUnsetTimezoneChangeListener(const JsonValue& /*args*/,
- JsonObject& out) {
+void TimeInstance::TZDate_getPreviousDSTTransition(const picojson::value& args,
+ picojson::object& out) {
LoggerD("Entered");
-
- PlatformResult result =
- g_time_util_listeners_obj.UnregisterVconfCallback(kTimezoneChange);
- if (result.IsError()) {
- LoggerE("Failed to unregister vconf callback");
- ReportError(result, &out);
+ if (!args.contains("timezone") || !args.contains("timestamp")) {
+ LoggerE("Invalid parameter passed.");
+ ReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."), &out);
+ return;
}
- else
- ReportSuccess(out);
-}
+ const std::string& timezone_id = args.get("timezone").get<std::string>();
+ std::shared_ptr<UnicodeString> unicode_id (new UnicodeString(timezone_id.c_str()));
-void TimeInstance::TimeGetMsUTC(const JsonValue& args, JsonObject& out) {
- LoggerD("Entered");
+ const std::string& timestamp_str = args.get("timestamp").get<std::string>();
+ UDate date = std::stod(timestamp_str);
- std::unique_ptr<UnicodeString> id(new UnicodeString(args.get("timezone").to_str().c_str()));
- if (id == NULL) {
- LoggerE("Allocation error");
- ReportError(out);
- return;
- }
- UDate dateInMs = strtod(args.get("value").to_str().c_str(), NULL);
- if (errno == ERANGE) {
- LoggerE("Value out of range");
- ReportError(out);
- return;
- }
+ picojson::value result = picojson::value(picojson::object());
+ picojson::object& result_obj = result.get<picojson::object>();
+ UDate prev_dst = TimeUtilTools::GetDSTTransition(date, unicode_id,
+ TimeUtilTools::DSTTransition::kPreviousDST);
+ result_obj.insert(std::make_pair("prevDSTDate", picojson::value(prev_dst)));
- UErrorCode ec = U_ZERO_ERROR;
- std::unique_ptr<TimeZone> timezone(TimeZone::createTimeZone(*id));
+ ReportSuccess(result, out);
+}
- int32_t rawOffset = 0;
- int32_t dstOffset = 0;
- timezone->getOffset(dateInMs, true, rawOffset, dstOffset, ec);
- if (U_FAILURE(ec)) {
- LoggerE("Failed to get timezone offset");
- ReportError(out);
+void TimeInstance::TZDate_getNextDSTTransition(const picojson::value& args, picojson::object& out) {
+ LoggerD("Entered");
+ if (!args.contains("timezone") || !args.contains("timestamp")) {
+ LoggerE("Invalid parameter passed.");
+ ReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."), &out);
return;
}
+ const std::string& timezone_id = args.get("timezone").get<std::string>();
+ std::shared_ptr<UnicodeString> unicode_id (new UnicodeString(timezone_id.c_str()));
+
+ const std::string& timestamp_str = args.get("timestamp").get<std::string>();
+ UDate date = std::stod(timestamp_str);
- dateInMs -= (rawOffset + dstOffset);
+ picojson::value result = picojson::value(picojson::object());
+ picojson::object& result_obj = result.get<picojson::object>();
+ UDate next_dst = TimeUtilTools::GetDSTTransition(date, unicode_id,
+ TimeUtilTools::DSTTransition::kNextDST);
+ result_obj.insert(std::make_pair("nextDSTDate", picojson::value(next_dst)));
- ReportSuccess(JsonValue{static_cast<double>(dateInMs)}, out);
+ ReportSuccess(result, out);
}
} // namespace time
#include "common/extension.h"
#include "common/picojson.h"
#include "unicode/unistr.h"
+#include "time/time_manager.h"
+#include "time/time_utils.h"
#include <string>
namespace extension {
namespace time {
-typedef picojson::value JsonValue;
-typedef picojson::object JsonObject;
-typedef picojson::array JsonArray;
-typedef std::string JsonString;
-
class TimeInstance : public common::ParsedInstance {
public:
TimeInstance();
virtual ~TimeInstance();
private:
- enum DateTimeFormatType {
- TIME_FORMAT,
- DATE_FORMAT,
- DATE_SHORT_FORMAT,
- DATETIME_FORMAT
- };
-
- void TimeGetAvailableTimeZones(const JsonValue& args, JsonObject& out);
- void TimeGetDSTTransition(const JsonValue& args, JsonObject& out);
- void TimeGetLocalTimeZone(const JsonValue& args, JsonObject& out);
- void TimeGetTimeFormat(const JsonValue& args, JsonObject& out);
- void TimeGetDateFormat(const JsonValue& args, JsonObject& out);
- void TimeGetTimeZoneOffset(const JsonValue& args, JsonObject& out);
- void TimeGetTimeZoneAbbreviation(const JsonValue& args, JsonObject& out);
- void TimeIsDST(const JsonValue& args, JsonObject& out);
- void TimeToString(const JsonValue& args, JsonObject& out);
- void TimeToDateString(const JsonValue& args, JsonObject& out);
- void TimeToTimeString(const JsonValue& args, JsonObject& out);
- void TimeSetDateTimeChangeListener(const JsonValue& args, JsonObject& out);
- void TimeUnsetDateTimeChangeListener(const JsonValue& args, JsonObject& out);
- void TimeSetTimezoneChangeListener(const JsonValue& args, JsonObject& out);
- void TimeUnsetTimezoneChangeListener(const JsonValue& args, JsonObject& out);
- void TimeGetMsUTC(const JsonValue& args, JsonObject& out);
-
- Locale* getDefaultLocale();
- UnicodeString getDateTimeFormat(DateTimeFormatType type, bool bLocale);
- bool toStringByFormat(const JsonValue& args, JsonValue& out,
- DateTimeFormatType format);
+ void TimeUtil_getAvailableTimezones(const picojson::value& args, picojson::object& out);
+ void TimeUtil_getDateFormat(const picojson::value& args, picojson::object& out);
+ void TimeUtil_getTimeFormat(const picojson::value& args, picojson::object& out);
+ void TimeUtil_setDateTimeChangeListener(const picojson::value& args, picojson::object& out);
+ void TimeUtil_unsetDateTimeChangeListener(const picojson::value& args, picojson::object& out);
+ void TimeUtil_setTimezoneChangeListener(const picojson::value& args, picojson::object& out);
+ void TimeUtil_unsetTimezoneChangeListener(const picojson::value& args, picojson::object& out);
+ void TZDate_getTimezone(const picojson::value& args, picojson::object& out);
+ void TZDate_GetTimezoneOffset(const picojson::value& args, picojson::object& out);
+ void ToStringTemplate(const picojson::value& args, bool use_locale_fmt,
+ TimeUtilTools::DateTimeFormatType type, picojson::object* out);
+ void TZDate_toLocaleDateString(const picojson::value& args, picojson::object& out);
+ void TZDate_toLocaleTimeString(const picojson::value& args, picojson::object& out);
+ void TZDate_toLocaleString(const picojson::value& args, picojson::object& out);
+ void TZDate_toDateString(const picojson::value& args, picojson::object& out);
+ void TZDate_toTimeString(const picojson::value& args, picojson::object& out);
+ void TZDate_toString(const picojson::value& args, picojson::object& out);
+ void TZDate_getTimezoneAbbreviation(const picojson::value& args, picojson::object& out);
+ void TZDate_isDST(const picojson::value& args, picojson::object& out);
+ void TZDate_getPreviousDSTTransition(const picojson::value& args, picojson::object& out);
+ void TZDate_getNextDSTTransition(const picojson::value& args, picojson::object& out);
+
+ TimeManager manager_;
};
} // namespace time
} // namespace extension
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "time/time_manager.h"
+
+#include <unicode/timezone.h>
+#include <unicode/calendar.h>
+#include <unistd.h>
+
+#include "common/logger.h"
+#include "time/time_instance.h"
+
+using common::PlatformResult;
+using common::ErrorCode;
+using common::Instance;
+
+namespace extension {
+namespace time {
+
+TimeManager::TimeManager(TimeInstance* instance)
+ : instance_(instance),
+ current_timezone_(GetDefaultTimezone()),
+ is_time_listener_registered_(false),
+ is_timezone_listener_registered_(false) {
+ LoggerD("Entered");
+}
+
+TimeManager::~TimeManager() {
+ LoggerD("Entered");
+ if (is_time_listener_registered_) {
+ UnregisterVconfCallback(kTimeChange);
+ }
+ if (is_timezone_listener_registered_) {
+ UnregisterVconfCallback(kTimezoneChange);
+ }
+}
+
+PlatformResult TimeManager::GetTimezoneOffset(const std::string& timezone_id,
+ const std::string& timestamp_str,
+ std::string* offset,
+ std::string* modifier) {
+ LoggerD("Entered");
+ std::unique_ptr<UnicodeString> unicode_id (new UnicodeString(timezone_id.c_str()));
+ std::unique_ptr<TimeZone> tz (TimeZone::createTimeZone(*unicode_id));
+
+ if (TimeZone::getUnknown() == *tz) {
+ return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed.");
+ }
+
+ const int32_t oneHour = 3600000;
+ UDate date = std::stod(timestamp_str);
+ int32_t stdOffset = 0;
+ int32_t dstOffset = 0;
+ UErrorCode ec = U_ZERO_ERROR;
+ //offset is get for target LOCAL date timestamp, but it should be UTC timestamp,
+ //so it has to be checked below against DST edge condition
+ tz->getOffset(date, false, stdOffset, dstOffset, ec);
+ LOGD("stdOffset: %d, dstOffset: %d", stdOffset, dstOffset);
+
+ //this section checks if date is not in DST transition point
+ //check if date shifted to UTC timestamp is still with the same offset
+ int32_t dstOffsetBefore = 0;
+ tz->getOffset(date - stdOffset - dstOffset, false, stdOffset, dstOffsetBefore, ec);
+ LOGD("stdOffset: %d, dstOffsetBefore: %d", stdOffset, dstOffsetBefore);
+
+ //it has to be checked if it is 'missing' hour case
+ int32_t dstOffsetAfterBefore = 0;
+ tz->getOffset(date - stdOffset - dstOffset + oneHour,
+ false, stdOffset, dstOffsetAfterBefore, ec);
+ LOGD("stdOffset: %d, dstOffsetAfterBefore: %d", stdOffset, dstOffsetAfterBefore);
+
+ //offset would be minimum of local and utc timestamp offsets
+ //(to work correctly even if DST transtion is 'now')
+ dstOffset = std::min(dstOffset, dstOffsetBefore);
+
+ *offset = std::to_string(stdOffset + dstOffset);
+ *modifier = std::to_string(dstOffsetAfterBefore - dstOffsetBefore);
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult TimeManager::RegisterVconfCallback(ListenerType type) {
+ LoggerD("Entered");
+ if (!is_time_listener_registered_ && !is_timezone_listener_registered_){
+ LOGD("registering listener on platform");
+ if (0 != vconf_notify_key_changed(
+ VCONFKEY_SYSTEM_TIME_CHANGED, OnTimeChangedCallback, this)) {
+ LOGE("Failed to register vconf callback");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to register vconf callback");
+ }
+ } else {
+ LOGD("not registering listener on platform - already registered");
+ }
+ switch (type) {
+ case kTimeChange :
+ is_time_listener_registered_ = true;
+ LOGD("time change listener registered");
+ break;
+ case kTimezoneChange :
+ is_timezone_listener_registered_ = true;
+ LOGD("time zone change listener registered");
+ break;
+ default :
+ LOGE("Unknown type of listener");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown type of listener");
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult TimeManager::UnregisterVconfCallback(ListenerType type) {
+ LoggerD("Entered");
+ switch (type) {
+ case kTimeChange :
+ is_time_listener_registered_ = false;
+ LOGD("time change listener unregistered");
+ break;
+ case kTimezoneChange :
+ is_timezone_listener_registered_ = false;
+ LOGD("time zone change listener unregistered");
+ break;
+ default :
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown type of listener");
+ }
+ if (!is_time_listener_registered_ && !is_timezone_listener_registered_) {
+ LOGD("unregistering listener on platform");
+ if (0 != vconf_ignore_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, OnTimeChangedCallback)) {
+ LOGE("Failed to unregister vconf callback");
+ // silent fail
+ //return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to unregister vconf callback");
+ }
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+void TimeManager::OnTimeChangedCallback(keynode_t* /*node*/, void* event_ptr) {
+ LoggerD("Entered");
+ TimeManager* manager = static_cast<TimeManager*>(event_ptr);
+ TimeInstance* instance = manager->GetTimeInstance();
+ std::string defaultTimezone = GetDefaultTimezone();
+
+ if (manager->GetCurrentTimezone() != defaultTimezone) {
+ manager->SetCurrentTimezone(defaultTimezone);
+ //call timezone callback
+
+ const std::shared_ptr<picojson::value>& response =
+ std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
+ response->get<picojson::object>()["listenerId"] = picojson::value("TimezoneChangeListener");
+ // ReportSuccess(result,response->get<picojson::object>());
+ Instance::PostMessage(instance, response->serialize().c_str());
+ }
+ //call date time callback
+ const std::shared_ptr<picojson::value>& response =
+ std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
+ response->get<picojson::object>()["listenerId"] = picojson::value("DateTimeChangeListener");
+ // ReportSuccess(result,response->get<picojson::object>());
+ Instance::PostMessage(instance, response->serialize().c_str());
+}
+
+std::string TimeManager::GetDefaultTimezone() {
+ LoggerD("Entered");
+ char buf[1024];
+ std::string result;
+ ssize_t len = readlink("/opt/etc/localtime", buf, sizeof(buf)-1);
+ if (len != -1) {
+ buf[len] = '\0';
+ } else {
+ /* handle error condition */
+ return result;
+ }
+ result = std::string(buf+strlen("/usr/share/zoneinfo/"));
+
+ LoggerD("tzpath = %s", result.c_str());
+ return result;
+}
+
+std::string TimeManager::GetCurrentTimezone(){
+ LoggerD("Entered");
+ return current_timezone_;
+}
+
+void TimeManager::SetCurrentTimezone(const std::string& new_timezone){
+ LoggerD("Entered");
+ current_timezone_ = new_timezone;
+}
+
+TimeInstance* TimeManager::GetTimeInstance() {
+ LoggerD("Entered");
+ return instance_;
+}
+
+} // time
+} // extension
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TIME_TIME_MANAGER_H_
+#define TIME_TIME_MANAGER_H_
+
+#include <memory>
+#include <vconf.h>
+#include "common/picojson.h"
+#include "common/platform_result.h"
+
+namespace extension {
+namespace time {
+
+enum ListenerType {
+ kTimeChange,
+ kTimezoneChange
+};
+
+class TimeInstance;
+
+class TimeManager
+{
+ public:
+ TimeManager(TimeInstance* instance);
+ ~TimeManager();
+
+ common::PlatformResult GetTimezoneOffset(const std::string& timezone_id,
+ const std::string& timestamp_str,
+ std::string* offset,
+ std::string* modifier);
+ common::PlatformResult RegisterVconfCallback(ListenerType type);
+ common::PlatformResult UnregisterVconfCallback(ListenerType type);
+ static void OnTimeChangedCallback(keynode_t* node, void* event_ptr);
+ std::string GetCurrentTimezone();
+ void SetCurrentTimezone(const std::string& new_timezone);
+ TimeInstance* GetTimeInstance();
+ static std::string GetDefaultTimezone();
+ private:
+ TimeInstance* instance_;
+ std::string current_timezone_;
+ bool is_time_listener_registered_;
+ bool is_timezone_listener_registered_;
+};
+
+}
+}
+
+#endif // TIME_TIME_MANAGER_H_
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "time_utils.h"
+
+#include <unicode/dtptngen.h>
+#include <unicode/smpdtfmt.h>
+#include <unicode/timezone.h>
+#include <unicode/vtzone.h>
+
+#include <vconf.h>
+
+#include "common/logger.h"
+
+using common::PlatformResult;
+using common::ErrorCode;
+
+namespace extension {
+namespace time {
+
+UDate TimeUtilTools::GetDSTTransition(UDate timestamp,
+ const std::shared_ptr<UnicodeString>& timezone_id,
+ DSTTransition tr_type) {
+ LoggerD("Entered");
+ UBool result = false;
+ UDate dst_transition_date = timestamp;
+ std::unique_ptr<VTimeZone> vtz(VTimeZone::createVTimeZoneByID(*timezone_id));
+
+ TimeZoneTransition tz_trans;
+ if (vtz->useDaylightTime()) {
+ switch (tr_type) {
+ case DSTTransition::kNextDST:
+ result = vtz->getNextTransition(dst_transition_date, FALSE, tz_trans);
+ break;
+
+ case DSTTransition::kPreviousDST:
+ result = vtz->getPreviousTransition(dst_transition_date, FALSE, tz_trans);
+ break;
+ }
+
+ if (result) {
+ dst_transition_date = tz_trans.getTime();
+ }
+ }
+ return dst_transition_date;
+}
+
+PlatformResult TimeUtilTools::IsDST(UDate timestamp,
+ const std::shared_ptr<UnicodeString>& timezone_id,
+ bool* result_bool) {
+ LoggerD("Entered");
+ UErrorCode ec = U_ZERO_ERROR;
+ std::unique_ptr<TimeZone> tz (TimeZone::createTimeZone(*timezone_id));
+ std::unique_ptr<icu::Calendar> calendar (Calendar::createInstance(*tz, ec));
+
+ if (U_FAILURE(ec)){
+ LoggerE("Failed to create calendar instance: %d", ec);
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to create calendar instance");
+ }
+ calendar->setTime(timestamp, ec);
+ if (U_FAILURE(ec)){
+ LoggerE("Failed to set calendar date: %d", ec);
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to set calendar date");
+ }
+ bool result = static_cast<bool>(calendar->inDaylightTime(ec));
+ if (U_FAILURE(ec)){
+ LoggerE("Failed to get day light boolean: %d", ec);
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get day light boolean");
+ }
+ *result_bool = result;
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult TimeUtilTools::GetTimezoneAbbreviation(UDate date,
+ const std::shared_ptr<UnicodeString>& timezone_id,
+ std::string* result_string) {
+ LoggerD("Entered");
+ UErrorCode ec = U_ZERO_ERROR;
+ UnicodeString str;
+
+ std::unique_ptr<DateFormat> fmt(new SimpleDateFormat(UnicodeString("z"),
+ Locale::getEnglish(), ec));
+ if (U_SUCCESS(ec)) {
+ std::unique_ptr<TimeZone> tz(TimeZone::createTimeZone(*timezone_id));
+ fmt->setTimeZone(*tz);
+ fmt->format(date, str);
+
+ if ((str.length() > 3) && (str.compare(0, 3, "GMT") == 0)) {
+ str.remove();
+ std::unique_ptr<DateFormat> gmt(new SimpleDateFormat(UnicodeString("OOOO"),
+ Locale::getEnglish(), ec));
+ gmt->setTimeZone(*tz);
+ gmt->format(date, str);
+ }
+
+ return TimeUtilTools::ToUTF8String(str, result_string);
+ }
+ LOGE("can't make SimpleDateFormat or can't get time");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR,
+ "can't make SimpleDateFormat or can't get time");
+}
+
+PlatformResult TimeUtilTools::ToStringHelper(UDate date,
+ std::shared_ptr<UnicodeString>& timezone_id,
+ bool use_locale_fmt,
+ TimeUtilTools::DateTimeFormatType type,
+ std::string* result_string) {
+ LoggerD("Entered");
+ UErrorCode ec = U_ZERO_ERROR;
+ UnicodeString str;
+
+ std::unique_ptr<Locale> default_locale(TimeUtilTools::GetDefaultLocale());
+ std::unique_ptr<DateFormat> fmt(
+ new SimpleDateFormat(
+ TimeUtilTools::GetDateTimeFormat(type, use_locale_fmt),
+ ((use_locale_fmt && default_locale != nullptr) ? *default_locale : Locale::getEnglish()),
+ ec));
+
+ if (U_SUCCESS(ec)) {
+ std::unique_ptr<TimeZone> tz(TimeZone::createTimeZone(*timezone_id));
+
+ fmt->setTimeZone(*tz);
+ fmt->format(date, str);
+
+ return TimeUtilTools::ToUTF8String(str, result_string);
+ }
+
+ LOGE("can't make SimpleDateFormat or can't get time");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "can't make SimpleDateFormat or can't get time");
+}
+
+PlatformResult TimeUtilTools::ToUTF8String(const UnicodeString& uni_str,
+ std::string* result_string) {
+ LoggerD("Entered");
+ int buffer_len = sizeof(UChar) * static_cast<int>(uni_str.length()) + 1;
+
+ std::unique_ptr<char, void(*)(void*)> result_buffer(static_cast<char*>(malloc(buffer_len)),
+ &std::free);
+
+ if (!result_buffer) {
+ LOGE("memory allocation error");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "memory allocation error");
+ }
+
+ memset(result_buffer.get(), 0, buffer_len);
+ CheckedArrayByteSink sink(result_buffer.get(), buffer_len);
+ uni_str.toUTF8(sink);
+
+ if (sink.Overflowed()) {
+ LOGE("Converting error");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Converting error");
+ }
+
+ *result_string = result_buffer.get();
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+UnicodeString* TimeUtilTools::ToUnicodeString(const std::string& str) {
+ LoggerD("Entered");
+ return new UnicodeString(str.c_str());
+}
+
+PlatformResult TimeUtilTools::GetLocalTimeZone(std::string* result_string) {
+ LoggerD("Entered");
+ UnicodeString id;
+ std::unique_ptr<TimeZone> zone(TimeZone::createDefault());
+ zone->getID(id);
+
+ PlatformResult res = ToUTF8String(id, result_string);
+ if(res.IsError()) {
+ return res;
+ }
+ LoggerD("local timezone: %s", result_string->c_str());
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+Locale* TimeUtilTools::GetDefaultLocale() {
+ LoggerD("Entered");
+ char* tempstr = vconf_get_str(VCONFKEY_REGIONFORMAT);
+
+ if (nullptr == tempstr){
+ return nullptr;
+ }
+
+ Locale* default_locale = nullptr;
+
+ char* p = strchr(tempstr, '.');
+ int len = strlen(tempstr) - (p != nullptr ? strlen(p) : 0);
+
+ if (len > 0) {
+ char* str_region = strndup(tempstr, len); //.UTF8 => 5
+ default_locale = new Locale(str_region);
+ free(str_region);
+ }
+
+ free(tempstr);
+
+ if (default_locale && default_locale->isBogus()) {
+ delete default_locale;
+ default_locale = nullptr;
+ }
+
+ return default_locale;
+}
+
+UnicodeString TimeUtilTools::GetDateTimeFormat(DateTimeFormatType type, bool use_locale_fmt) {
+ LoggerD("Entered");
+ UErrorCode ec = U_ZERO_ERROR;
+ Locale* default_locale = GetDefaultLocale();
+
+ std::unique_ptr<DateTimePatternGenerator> date_time_pattern(
+ DateTimePatternGenerator::createInstance(
+ ((use_locale_fmt && default_locale) ? *default_locale : Locale::getEnglish()),
+ ec));
+
+ delete default_locale;
+ if (U_SUCCESS(ec)) {
+ UnicodeString pattern;
+
+ switch (type) {
+ case DateTimeFormatType::kDateFormat:
+ pattern = date_time_pattern->getBestPattern(UDAT_YEAR_MONTH_WEEKDAY_DAY, ec);
+ break;
+
+ case DateTimeFormatType::kDateShortFormat:
+ pattern = date_time_pattern->getBestPattern(UDAT_YEAR_NUM_MONTH_DAY, ec);
+ break;
+
+ default:
+ {
+ int ret = 0;
+ int value = 0;
+ ret = vconf_get_int(VCONFKEY_REGIONFORMAT_TIME1224, &value);
+ // if failed, set default time format
+ if (-1 == ret) {
+ value = VCONFKEY_TIME_FORMAT_12;
+ }
+
+ std::string skeletone;
+ if (DateTimeFormatType::kTimeFormat != type) {
+ skeletone = UDAT_YEAR_MONTH_WEEKDAY_DAY;
+ }
+
+ if (VCONFKEY_TIME_FORMAT_12 == value) {
+ skeletone += "hhmmss";
+ } else {
+ skeletone += "HHmmss";
+ }
+
+ std::unique_ptr<UnicodeString> skeletone_str(ToUnicodeString(skeletone));
+ pattern = date_time_pattern->getBestPattern(*skeletone_str, ec);
+
+ if (!use_locale_fmt) {
+ pattern += " 'GMT'Z v'";
+ }
+ }
+ break;
+ }
+
+ return pattern;
+ }
+
+ return "";
+}
+
+PlatformResult TimeUtilTools::GetDateFormat(bool shortformat, std::string* result_string) {
+ LoggerD("Entered");
+ UnicodeString time_format =
+ TimeUtilTools::GetDateTimeFormat(
+ (shortformat ?
+ DateTimeFormatType::kDateShortFormat:
+ DateTimeFormatType::kDateFormat),
+ true);
+ time_format = time_format.findAndReplace("E", "D");
+
+ if (time_format.indexOf("MMM") > 0) {
+ if (time_format.indexOf("MMMM") > 0){
+ time_format = time_format.findAndReplace("MMMM", "M");
+ } else {
+ time_format = time_format.findAndReplace("MMM", "M");
+ }
+ } else {
+ time_format = time_format.findAndReplace("M", "m");
+ }
+
+ int32_t i = 0;
+
+ while (i < time_format.length() - 1) {
+ if (time_format[i] == time_format[i + 1]) {
+ time_format.remove(i, 1);
+ } else {
+ ++i;
+ }
+ }
+
+ PlatformResult res = ToUTF8String(time_format, result_string);
+ if(res.IsError()) {
+ return res;
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult TimeUtilTools::GetTimeFormat(std::string* result_string) {
+ LoggerD("Entered");
+ UnicodeString time_format = TimeUtilTools::GetDateTimeFormat(
+ DateTimeFormatType::kTimeFormat, true);
+ time_format = time_format.findAndReplace("H", "h");
+ time_format = time_format.findAndReplace("K", "h");
+ time_format = time_format.findAndReplace("k", "h");
+ time_format = time_format.findAndReplace("a", "ap");
+
+ int32_t i = 0;
+
+ while (i < time_format.length() - 1) {
+ if (time_format[i] == time_format[i + 1]) {
+ time_format.remove(i, 1);
+ } else {
+ ++i;
+ }
+ }
+ PlatformResult res = ToUTF8String(time_format, result_string);
+ if(res.IsError()) {
+ return res;
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult TimeUtilTools::GetAvailableTimezones(picojson::array* available_timezones) {
+ LoggerD("Entered");
+ UErrorCode ec = U_ZERO_ERROR;
+ std::unique_ptr<StringEnumeration> tz_enum(TimeZone::createEnumeration());
+ const char* str = nullptr;
+ int32_t count = tz_enum->count(ec);
+
+ if (U_SUCCESS(ec)) {
+ int i = 0;
+ do {
+ int32_t resultLen = 0;
+ str = tz_enum->next(&resultLen, ec);
+ if (U_SUCCESS(ec)) {
+ available_timezones->push_back(picojson::value(str));
+ ++i;
+ } else {
+ LOGE("An error occurred");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "An error occurred");
+ }
+ } while ((str != nullptr) && (i < count));
+ }
+ else {
+ LOGE("Can't get timezones list");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Can't get timezones list");
+ }
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+} // time
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TIME_TIME_UTILS_H_
+#define TIME_TIME_UTILS_H_
+
+#include <memory>
+#include <unicode/unistr.h>
+#include "common/picojson.h"
+#include "common/platform_result.h"
+
+namespace extension {
+namespace time {
+
+class TimeUtilTools
+{
+ public:
+ enum class DateTimeFormatType {
+ kTimeFormat,
+ kDateFormat,
+ kDateShortFormat,
+ kDateTimeFormat
+ };
+ enum class DSTTransition {
+ kPreviousDST,
+ kNextDST
+ };
+ static UDate GetDSTTransition(UDate dstTransitionDate,
+ const std::shared_ptr<UnicodeString>& timezone_id,
+ DSTTransition tr_type);
+ static common::PlatformResult IsDST(UDate dstTransitionDate,
+ const std::shared_ptr<UnicodeString>& timezone_id, bool* result_bool);
+ static common::PlatformResult GetTimezoneAbbreviation(UDate date,
+ const std::shared_ptr<UnicodeString>& timezone_id,
+ std::string* result_string);
+ static common::PlatformResult ToStringHelper(
+ UDate date, std::shared_ptr<UnicodeString>& timezone_id, bool use_locale_fmt,
+ TimeUtilTools::DateTimeFormatType type,
+ std::string* result_string);
+ static common::PlatformResult ToUTF8String(const UnicodeString& uniStr,
+ std::string* result_string);
+ static UnicodeString* ToUnicodeString(const std::string& str);
+ static common::PlatformResult GetLocalTimeZone(std::string* result_string);
+ static UnicodeString GetDateTimeFormat(DateTimeFormatType type, bool bLocale);
+ static Locale* GetDefaultLocale();
+ static common::PlatformResult GetDateFormat(bool shortformat, std::string* result_string);
+ static common::PlatformResult GetTimeFormat(std::string* result_string);
+ static common::PlatformResult GetAvailableTimezones(picojson::array* available_timezones);
+};
+
+}
+}
+
+#endif // TIME_TIME_UTILS_H_
DateConverter.prototype.toTZDate = function(v, isAllDay) {
if (typeof v === 'number') {
v = {
- UTCTimestamp: v
- };
+ UTCTimestamp: v
+ };
isAllDay = false;
}
return new tizen.TZDate(v.year, v.month - 1, v.day,
null, null, null, null, v.timezone || null);
} else {
- return new tizen.TZDate(new Date(v.UTCTimestamp * 1000), 'UTC').toLocalTimezone();
+ return new tizen.TZDate(new Date(v.UTCTimestamp * 1000));
}
};
return v;
}
- var timestamp = Date.UTC(v.date_.getUTCFullYear(),
- v.date_.getUTCMonth(),
- v.date_.getUTCDate(),
- v.date_.getUTCHours(),
- v.date_.getUTCMinutes(),
- v.date_.getUTCSeconds(),
- v.date_.getUTCMilliseconds()) / 1000;
-
return {
year: v.getFullYear(),
month: v.getMonth(),
day: v.getDate(),
timezone: v.getTimezone(),
- UTCTimestamp: timestamp
+ UTCTimestamp: v._utcTimestamp / 1000
};
};