[Time] - fixing bugs with timezones
authorAndrzej Popowski <a.popowski@samsung.com>
Fri, 24 Jul 2015 06:26:02 +0000 (08:26 +0200)
committerAndrzej Popowski <a.popowski@samsung.com>
Mon, 27 Jul 2015 11:53:45 +0000 (20:53 +0900)
[Verification] - TCT results 100% for Alarm, Calendar, Exif and Time

Change-Id: Ifd9f74315c8374d5331ff44185cdbe8ea80fb054
Signed-off-by: Andrzej Popowski <a.popowski@samsung.com>
src/calendar/calendar_instance.cc
src/time/time_api.js
src/time/time_instance.cc
src/time/time_instance.h
src/utils/utils_api.js

index 70d9a0763b6ec0140605bbdc1f1a4f653aed3367..733c35487260da04357fb0df0b2952cb6a8638ee 100755 (executable)
@@ -96,9 +96,9 @@ void CalendarInstance::CalendarAdd(const JsonValue& args, JsonObject& out) {
   PlatformResult status = calendar_.Add(common::JsonCast<JsonObject>(args),
                                         val.get<JsonObject>());
 
-  if (status.IsSuccess())
+  if (status.IsSuccess()) {
     ReportSuccess(val, out);
-  else{
+  else{
     LoggerE("Failed");
     ReportError(status, &out);
   }
index 0d4afaef03e93d2772197ba05cff072587f4b33c..11a1fe41acd71765814d5208914125be3e046e8e 100644 (file)
@@ -281,50 +281,91 @@ tizen.TimeDuration.prototype.toString = function() {
   return this.length + ' ' + this.unit;
 };
 
+function getTimezoneOffset(_timezone, _timeInMs) {
+  var result = native_.callSync('Time_getTimeZoneOffset', {
+    timezone: _timezone,
+    value: _timeInMs
+  });
+  if (native_.isFailure(result)) {
+    throw native_.getErrorObject(result);
+  }
+
+  return native_.getResultObject(result);
+}
+
+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);
+    }
+
+    ms_utc = native_.getResultObject(result);
+  }
+
+  return ms_utc;
+}
+
 tizen.TZDate = function(year, month, day, hours, minutes, seconds, milliseconds, timezone) {
   validator_.isConstructorCall(this, tizen.TZDate);
 
-  this.timezone_ = timezone || tizen.time.getLocalTimezone();
+  if (timezone) {
+    if (tizen.time.getAvailableTimezones().indexOf(timezone) < 0) {
+      throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR);
+    }
+
+    this.timezone_ = timezone;
+  } else {
+    this.timezone_ = tizen.time.getLocalTimezone();
+  }
 
   var hours = hours || 0;
   var minutes = minutes || 0;
   var seconds = seconds || 0;
   var milliseconds = milliseconds || 0;
 
-  if (!arguments.length)
+  if (!arguments.length) {
     this.date_ = new Date();
-  else if (arguments.length === 1 || arguments.length === 2) {
-    if (arguments[0] instanceof Date)
+  else if (arguments.length === 1 || arguments.length === 2) {
+    if (arguments[0] instanceof Date) {
       this.date_ = arguments[0];
-    else
+    } else {
       this.date_ = new Date();
-    if (arguments[1])
+    }
+    if (arguments[1]) {
+      if (tizen.time.getAvailableTimezones().indexOf(arguments[1]) < 0) {
+        throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR);
+      }
       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);
+    }
   }
-  else
-    this.date_ = new Date(year, month, day, hours, minutes, seconds, milliseconds);
-
-  if (tizen.time.getAvailableTimezones().indexOf(this.timezone_) < 0)
-    throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR);
 };
 
-function getTimezoneOffset(_timezone, _timeInMs) {
-  var result = native_.callSync('Time_getTimeZoneOffset', {
-    timezone: _timezone,
-    value: _timeInMs
-  });
-  if (native_.isFailure(result)) {
-    throw native_.getErrorObject(result);
-  }
-
-  return native_.getResultObject(result);
-}
-
-function _getTimeWithOffset(date) {
-  var OffsetInMilliseconds = date.getTimezoneOffset() * _minuteInMilliseconds * -1;
-  return date.getTime() + OffsetInMilliseconds;
-}
-
 tizen.TZDate.prototype.getDate = function() {
   return this.date_.getDate();
 };
@@ -356,7 +397,9 @@ tizen.TZDate.prototype.setFullYear = function() {
 };
 
 tizen.TZDate.prototype.getHours = function() {
-  return this.date_.getHours();
+  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
+                                           getMsUTC(this.date_))));
+  return d.date_.getUTCHours();
 };
 
 tizen.TZDate.prototype.setHours = function() {
@@ -422,7 +465,7 @@ tizen.TZDate.prototype.setSeconds = function() {
 
 tizen.TZDate.prototype.getUTCDate = function() {
   var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
-                                          _getTimeWithOffset(this.date_)) * -1));
+                                          getMsUTC(this.date_)) * -1));
   return d.getDate();
 };
 
@@ -437,13 +480,13 @@ tizen.TZDate.prototype.setUTCDate = function() {
 
 tizen.TZDate.prototype.getUTCDay = function() {
   var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
-                                         _getTimeWithOffset(this.date_)) * -1));
+                                         getMsUTC(this.date_)) * -1));
   return d.getDay();
 };
 
 tizen.TZDate.prototype.getUTCFullYear = function() {
   var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
-                                          _getTimeWithOffset(this.date_)) * -1));
+                                          getMsUTC(this.date_)) * -1));
   return d.getFullYear();
 };
 
@@ -457,9 +500,7 @@ tizen.TZDate.prototype.setUTCFullYear = function() {
 };
 
 tizen.TZDate.prototype.getUTCHours = function() {
-  var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
-                                           _getTimeWithOffset(this.date_)) * -1));
-  return d.getHours();
+  return this.date_.getUTCHours();
 };
 
 tizen.TZDate.prototype.setUTCHours = function() {
@@ -468,14 +509,14 @@ tizen.TZDate.prototype.setUTCHours = function() {
     type: types_.LONG
   }]);
 
-  var offset_hours = getTimezoneOffset(this.timezone_, _getTimeWithOffset(this.date_)) /
+  var offset_hours = getTimezoneOffset(this.timezone_, getMsUTC(this.date_)) /
                      _hourInMilliseconds;
   this.date_.setHours(args.hours + offset_hours);
 };
 
 tizen.TZDate.prototype.getUTCMilliseconds = function() {
   var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
-                                              _getTimeWithOffset(this.date_)) * -1));
+                                              getMsUTC(this.date_)) * -1));
   return d.getMilliseconds();
 };
 
@@ -490,7 +531,7 @@ tizen.TZDate.prototype.setUTCMilliseconds = function() {
 
 tizen.TZDate.prototype.getUTCMinutes = function() {
   var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
-                                             _getTimeWithOffset(this.date_)) * -1));
+                                             getMsUTC(this.date_)) * -1));
   return d.getMinutes();
 };
 
@@ -505,7 +546,7 @@ tizen.TZDate.prototype.setUTCMinutes = function() {
 
 tizen.TZDate.prototype.getUTCMonth = function() {
   var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
-                                           _getTimeWithOffset(this.date_)) * -1));
+                                           getMsUTC(this.date_)) * -1));
   return d.getMonth();
 };
 
@@ -520,7 +561,7 @@ tizen.TZDate.prototype.setUTCMonth = function() {
 
 tizen.TZDate.prototype.getUTCSeconds = function() {
   var d = this.addDuration(new tizen.TimeDuration(getTimezoneOffset(this.timezone_,
-                                         _getTimeWithOffset(this.date_)) * -1));
+                                         getMsUTC(this.date_)) * -1));
   return d.getSeconds();
 };
 
@@ -736,7 +777,7 @@ tizen.TZDate.prototype.secondsFromUTC = function() {
 tizen.TZDate.prototype.isDST = function() {
   var result = native_.callSync('Time_isDST', {
     timezone: this.timezone_,
-    value: _getTimeWithOffset(this.date_)
+    value: getMsUTC(this.date_)
   });
   if (native_.isFailure(result)) {
     return false;
@@ -748,7 +789,7 @@ tizen.TZDate.prototype.isDST = function() {
 tizen.TZDate.prototype.getPreviousDSTTransition = function() {
   var result = native_.callSync('Time_getDSTTransition', {
     'timezone': this.timezone_,
-    'value': _getTimeWithOffset(this.date_),
+    'value': getMsUTC(this.date_),
     'trans': 'NEXT_TRANSITION'
   });
   if (native_.isFailure(result)) {
@@ -764,7 +805,7 @@ tizen.TZDate.prototype.getPreviousDSTTransition = function() {
 tizen.TZDate.prototype.getNextDSTTransition = function() {
   var result = native_.callSync('Time_getDSTTransition', {
     timezone: this.timezone_,
-    value: _getTimeWithOffset(this.date_),
+    value: getMsUTC(this.date_),
     trans: 'PREV_TRANSITION'
   });
   if (native_.isFailure(result)) {
index c170780de22379c1e33bc430c134efb45df9e6f4..297cef37dbc208c711bab72cc6ed8d964f3733b6 100644 (file)
@@ -74,6 +74,7 @@ TimeInstance::TimeInstance() {
                 TimeSetTimezoneChangeListener);
   REGISTER_SYNC("Time_unsetTimezoneChangeListener",
                 TimeUnsetTimezoneChangeListener);
+  REGISTER_SYNC("Time_getMsUTC", TimeGetMsUTC);
 
 #undef REGISTER_SYNC
 #undef REGISTER_ASYNC
@@ -149,27 +150,17 @@ void TimeInstance::TimeGetTimeZoneOffset(const JsonValue& args,
 
   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);
-    return;
-  }
 
-  cal->setTime(dateInMs, ec);
+  int32_t rawOffset = 0;
+  int32_t dstOffset = 0;
+  timezone->getOffset(dateInMs, false, rawOffset, dstOffset, ec);
   if (U_FAILURE(ec)) {
-    LoggerE("Failed to set time");
+    LoggerE("Failed to get timezone offset");
     ReportError(out);
     return;
   }
-
-  int32_t offset = timezone->getRawOffset();
-
-  if (cal->inDaylightTime(ec)) offset += _hourInMilliseconds;
-
   std::stringstream offsetStr;
-  offsetStr << offset;
-
+  offsetStr << (rawOffset + dstOffset);
   ReportSuccess(JsonValue(offsetStr.str()), out);
 }
 
@@ -188,8 +179,8 @@ void TimeInstance::TimeGetTimeZoneAbbreviation(const JsonValue& args,
   }
 
   UErrorCode ec = U_ZERO_ERROR;
-  std::unique_ptr<Calendar> cal(
-      Calendar::createInstance(TimeZone::createTimeZone(*id), ec));
+  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);
@@ -232,7 +223,6 @@ void TimeInstance::TimeIsDST(const JsonValue& args, JsonObject& out) {
   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);
-  dateInMs -= _hourInMilliseconds;
 
   if (errno == ERANGE) {
     LoggerE("Value out of range");
@@ -241,22 +231,17 @@ void TimeInstance::TimeIsDST(const JsonValue& args, JsonObject& out) {
   }
 
   UErrorCode ec = U_ZERO_ERROR;
-  std::unique_ptr<Calendar> cal(
-      Calendar::createInstance(TimeZone::createTimeZone(*id), ec));
-  if (U_FAILURE(ec)) {
-    LoggerE("Failed to create Calendar instance");
-    ReportError(out);
-    return;
-  }
+  std::unique_ptr<TimeZone> timezone(TimeZone::createTimeZone(*id));
 
-  cal->setTime(dateInMs, ec);
+  int32_t rawOffset = 0;
+  int32_t dstOffset = 0;
+  timezone->getOffset(dateInMs, false, rawOffset, dstOffset, ec);
   if (U_FAILURE(ec)) {
-    LoggerE("Failed to set time");
+    LoggerE("Failed to get timezone offset");
     ReportError(out);
     return;
   }
-
-  ReportSuccess(JsonValue{static_cast<bool>(cal->inDaylightTime(ec))}, out);
+  ReportSuccess(JsonValue{static_cast<bool>(dstOffset)}, out);
 }
 
 void TimeInstance::TimeGetDSTTransition(const JsonValue& args,
@@ -348,8 +333,8 @@ bool TimeInstance::toStringByFormat(const JsonValue& args, JsonValue& out,
   }
 
   UErrorCode ec = U_ZERO_ERROR;
-  std::unique_ptr<Calendar> cal(
-      Calendar::createInstance(TimeZone::createTimeZone(*id), ec));
+  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;
@@ -690,5 +675,33 @@ void TimeInstance::TimeUnsetTimezoneChangeListener(const JsonValue& /*args*/,
     ReportSuccess(out);
 }
 
+void TimeInstance::TimeGetMsUTC(const JsonValue& args, JsonObject& 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, true, rawOffset, dstOffset, ec);
+  if (U_FAILURE(ec)) {
+    LoggerE("Failed to get timezone offset");
+    ReportError(out);
+    return;
+  }
+
+  dateInMs -= (rawOffset + dstOffset);
+
+  ReportSuccess(JsonValue{static_cast<double>(dateInMs)}, out);
+}
+
 }  // namespace time
 }  // namespace extension
index ec4c55951ee0d8e0da2446b23cea640cc237da65..6cb1e1ed5ea809f80dc36964ad3d7bb2521e6fb1 100644 (file)
@@ -48,6 +48,7 @@ class TimeInstance : public common::ParsedInstance {
   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);
 
   UnicodeString getDateTimeFormat(DateTimeFormatType type, bool bLocale);
   bool toStringByFormat(const JsonValue& args, JsonValue& out,
index 6020012ce897eff9b953f5efd5ffa08b5c4b9b55..cdb563ff384ba314af2565c1870bde32fb883722 100755 (executable)
@@ -43,9 +43,13 @@ DateConverter.prototype.fromTZDate = function(v) {
     return v;
   }
 
-  var utc = v.toUTC();
-  var timestamp = new Date(utc.getFullYear(), utc.getMonth(), utc.getDate(), utc.getHours(),
-      utc.getMinutes(), utc.getSeconds()) / 1000;
+  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(),