<option defaultValue="gnu.cpp.compiler.debugging.level.max" id="sbi.gnu.cpp.compiler.option.debugging.level.core.508515725" name="Debug level" superClass="sbi.gnu.cpp.compiler.option.debugging.level.core" valueType="enumerated"/>
<option defaultValue="false" id="sbi.gnu.cpp.compiler.option.misc.pic.core.1071875033" name="-fPIC option" superClass="sbi.gnu.cpp.compiler.option.misc.pic.core" valueType="boolean"/>
<option id="sbi.gnu.cpp.compiler.option.781067055" name="Tizen-Target" superClass="sbi.gnu.cpp.compiler.option" valueType="userObjs">
- <listOptionValue builtIn="false" value="mobile-3.0-device.core_llvm36.armel.core.app"/>
+ <listOptionValue builtIn="false" value="mobile-3.0-emulator.core_llvm36.i386.core.app"/>
+ </option>
+ <option id="sbi.gnu.cpp.compiler.option.frameworks_inc.core.2103208823" name="Tizen-Frameworks-Include-Path" superClass="sbi.gnu.cpp.compiler.option.frameworks_inc.core" valueType="includePath">
+ <listOptionValue builtIn="false" value=""${SBI_SYSROOT}/usr/include/libxml2""/>
</option>
<option id="sbi.gnu.cpp.compiler.option.frameworks_inc.core.2103208823" name="Tizen-Frameworks-Include-Path" superClass="sbi.gnu.cpp.compiler.option.frameworks_inc.core" valueType="includePath">
<listOptionValue builtIn="false" value=""${SBI_SYSROOT}/usr/include/libxml2""/>
<listOptionValue builtIn="false" value="${RS_COMPILER_MISC}"/>
<listOptionValue builtIn="false" value=" -fPIE"/>
<listOptionValue builtIn="false" value="--sysroot="${SBI_SYSROOT}""/>
- <listOptionValue builtIn="false" value="-mthumb"/>
</option>
<option id="gnu.cpp.compiler.option.include.paths.1337650806" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc}""/>
<option defaultValue="gnu.c.debugging.level.max" id="sbi.gnu.c.compiler.option.debugging.level.core.1218321510" name="Debug level" superClass="sbi.gnu.c.compiler.option.debugging.level.core" valueType="enumerated"/>
<option defaultValue="false" id="sbi.gnu.c.compiler.option.misc.pic.core.824960994" name="-fPIC option" superClass="sbi.gnu.c.compiler.option.misc.pic.core" valueType="boolean"/>
<option id="sbi.gnu.c.compiler.option.1133367837" name="Tizen-Target" superClass="sbi.gnu.c.compiler.option" valueType="userObjs">
- <listOptionValue builtIn="false" value="mobile-3.0-device.core_llvm36.armel.core.app"/>
+ <listOptionValue builtIn="false" value="mobile-3.0-emulator.core_llvm36.i386.core.app"/>
</option>
<option id="sbi.gnu.c.compiler.option.frameworks_inc.core.891354465" name="Tizen-Frameworks-Include-Path" superClass="sbi.gnu.c.compiler.option.frameworks_inc.core" valueType="includePath">
<listOptionValue builtIn="false" value=""${SBI_SYSROOT}/usr/include/libxml2""/>
<option id="gnu.cpp.link.option.userobjs.1206172838" name="Other objects" superClass="gnu.cpp.link.option.userobjs" valueType="userObjs">
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Common/CounterAnimator.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Controller/MainController.o""/>
+ <listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Controller/RingController.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/Alarm.o""/>
+ <listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/AlarmEvent.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/AlarmProvider.o""/>
+ <listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/AlarmProviderEvent.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/AlarmProviderFile.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/StopWatch.o""/>
+ <listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/Timer.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/WeekFlags.o""/>
+ <listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/WorldClock.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Presenter/AlarmPresenter.o""/>
+ <listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Presenter/DeleteAlarmPresenter.o""/>
+ <listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Presenter/EditAlarmPresenter.o""/>
+ <listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Presenter/RingPresenter.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Presenter/StopWatchPresenter.o""/>
+ <listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Presenter/TimerPresenter.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Utils/BinaryFileReader.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Utils/BinaryFileWriter.o""/>
+ <listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Utils/EventBus.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Utils/Serialization.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Utils/Time.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Utils/Utils.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/View/AlarmView.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/View/CounterView.o""/>
+ <listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/View/DeleteAlarmView.o""/>
+ <listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/View/EditAlarmView.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/View/MainView.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/View/PageView.o""/>
+ <listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/View/RingView.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/View/StopWatchView.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/View/TimerView.o""/>
+ <listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/View/WeekFlagsView.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/View/WorldClockView.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Controller/RingController.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/Timer.o""/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
- <tool command="arm-linux-gnueabi-as" id="org.tizen.nativeapp.tool.sbi.gnu.assembler.base.1231941130" name="Assembler" superClass="org.tizen.nativeapp.tool.sbi.gnu.assembler.base">
+ <tool command="i386-linux-gnueabi-as" id="org.tizen.nativeapp.tool.sbi.gnu.assembler.base.1231941130" name="Assembler" superClass="org.tizen.nativeapp.tool.sbi.gnu.assembler.base">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.834372949" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<tool id="org.tizen.nativecore.tool.fnmapgen.802860601" name="C FN-Map Generator" superClass="org.tizen.nativecore.tool.fnmapgen"/>
<option defaultValue="gnu.cpp.compiler.debugging.level.none" id="sbi.gnu.cpp.compiler.option.debugging.level.core.712308302" name="Debug level" superClass="sbi.gnu.cpp.compiler.option.debugging.level.core" valueType="enumerated"/>
<option defaultValue="false" id="sbi.gnu.cpp.compiler.option.misc.pic.core.41747109" name="-fPIC option" superClass="sbi.gnu.cpp.compiler.option.misc.pic.core" valueType="boolean"/>
<option id="sbi.gnu.cpp.compiler.option.1827232363" name="Tizen-Target" superClass="sbi.gnu.cpp.compiler.option" valueType="userObjs">
- <listOptionValue builtIn="false" value="mobile-3.0-device.core_llvm36.armel.core.app"/>
+ <listOptionValue builtIn="false" value="mobile-3.0-emulator.core_llvm36.i386.core.app"/>
</option>
<option id="sbi.gnu.cpp.compiler.option.frameworks_inc.core.971982965" name="Tizen-Frameworks-Include-Path" superClass="sbi.gnu.cpp.compiler.option.frameworks_inc.core" valueType="includePath">
<listOptionValue builtIn="false" value=""${SBI_SYSROOT}/usr/include/libxml2""/>
<listOptionValue builtIn="false" value="${RS_COMPILER_MISC}"/>
<listOptionValue builtIn="false" value=" -fPIE"/>
<listOptionValue builtIn="false" value="--sysroot="${SBI_SYSROOT}""/>
- <listOptionValue builtIn="false" value="-mthumb"/>
</option>
<option id="gnu.cpp.compiler.option.include.paths.2079184222" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc}""/>
<option defaultValue="gnu.c.debugging.level.default" id="sbi.gnu.c.compiler.option.debugging.level.core.1121232151" name="Debug level" superClass="sbi.gnu.c.compiler.option.debugging.level.core" valueType="enumerated"/>
<option defaultValue="false" id="sbi.gnu.c.compiler.option.misc.pic.core.1483125974" name="-fPIC option" superClass="sbi.gnu.c.compiler.option.misc.pic.core" valueType="boolean"/>
<option id="sbi.gnu.c.compiler.option.1432194874" name="Tizen-Target" superClass="sbi.gnu.c.compiler.option" valueType="userObjs">
- <listOptionValue builtIn="false" value="mobile-3.0-device.core_llvm36.armel.core.app"/>
+ <listOptionValue builtIn="false" value="mobile-3.0-emulator.core_llvm36.i386.core.app"/>
</option>
<option id="sbi.gnu.c.compiler.option.frameworks_inc.core.965580502" name="Tizen-Frameworks-Include-Path" superClass="sbi.gnu.c.compiler.option.frameworks_inc.core" valueType="includePath">
<listOptionValue builtIn="false" value=""${SBI_SYSROOT}/usr/include/libxml2""/>
<listOptionValue builtIn="false" value="${RS_COMPILER_MISC}"/>
<listOptionValue builtIn="false" value=" -fPIE"/>
<listOptionValue builtIn="false" value="--sysroot="${SBI_SYSROOT}""/>
- <listOptionValue builtIn="false" value="-mthumb"/>
</option>
<option id="gnu.c.compiler.option.include.paths.234793489" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc}""/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
- <tool command="arm-linux-gnueabi-as" id="org.tizen.nativeapp.tool.sbi.gnu.assembler.base.1137717587" name="Assembler" superClass="org.tizen.nativeapp.tool.sbi.gnu.assembler.base">
+ <tool command="i386-linux-gnueabi-as" id="org.tizen.nativeapp.tool.sbi.gnu.assembler.base.1137717587" name="Assembler" superClass="org.tizen.nativeapp.tool.sbi.gnu.assembler.base">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1683314605" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<tool id="org.tizen.nativecore.tool.fnmapgen.940558103" name="C FN-Map Generator" superClass="org.tizen.nativecore.tool.fnmapgen"/>
TEST(TestSuite, test01)
{
}
-
--- /dev/null
+#include "Utils/Time.h"
+
+#include <gtest/gtest.h>
+
+using namespace testing;
+using namespace utils;
+
+class TimeTestSuite : public testing::Test
+{
+ protected:
+ // virtual void SetUp() will be called before each test is run.
+ // You should define it if you need to initialize the variables.
+ // Otherwise, you don't have to provide it.
+ virtual void SetUp()
+ {
+
+ }
+ // virtual void TearDown() will be called after each test is run.
+ // You should define it if there is cleanup work to do.
+ // Otherwise, you don't have to provide it.
+ virtual void TearDown()
+ {
+
+ }
+};
+
+// When you have a test fixture, you define a test using TEST_F.
+// Otherwise, you define a test using TEST.
+TEST(TimeTestSuite, test_default_tz)
+{
+ Time tm1(2016, 9, 17, 23, 11, 0, 0);
+ EXPECT_EQ(tm1.Format(Time::FORMAT_TIME_12H), "11:11");
+
+ Time tm2(2016, 9, 17, 23, 11, 0, 0);
+ EXPECT_EQ(tm2.Format(Time::FORMAT_TIME_24H), "23:11");
+
+ Time tm3(2016, 9, 17, 23, 11, 0, 0);
+ EXPECT_EQ(tm3.Format(Time::FORMAT_TIME_AMPM), "PM");
+
+ Time tm4(2016, 9, 17, 23, 1, 0, 0);
+ EXPECT_EQ(tm4.Format(Time::FORMAT_TIME_12H), "11:01");
+}
+
+TEST(TimeTestSuite, test_predefined_tz)
+{
+ Time tm1(2016, 9, 17, 23, 11, 0, 0, "Europe/Warsaw");
+ EXPECT_EQ(tm1.Format(Time::FORMAT_TIME_12H), "11:11");
+
+ Time tm2(2016, 9, 17, 23, 11, 0, 0, "America/New_York");
+ EXPECT_EQ(tm2.Format(Time::FORMAT_TIME_24H), "23:11");
+
+ Time tm3(2016, 9, 17, 23, 11, 0, 0, "Europe/Warsaw");
+ EXPECT_EQ(tm3.Format(Time::FORMAT_TIME_AMPM), "PM");
+
+ Time tm4(2016, 9, 17, 23, 1, 0, 0, "America/New_York");
+ EXPECT_EQ(tm4.Format(Time::FORMAT_TIME_12H), "11:01");
+}
+
+TEST(TimeTestSuite, test_tz_transform)
+{
+ Time tm1(2016, 9, 17, 8, 1, 0, 0, "Europe/Warsaw");
+ EXPECT_EQ(tm1.InTimezone("Asia/Seoul").Format(Time::FORMAT_TIME_24H), "15:01");
+ EXPECT_EQ(tm1.InTimezone("America/New_York").Format(Time::FORMAT_TIME_24H), "02:01");
+
+ Time tm2(2016, 9, 17, 4, 1, 0, 0, "Asia/Seoul");
+ EXPECT_EQ(tm2.InTimezone("Europe/Warsaw").Format(Time::FORMAT_TIME_24H), "21:01");
+ EXPECT_EQ(tm2.InTimezone("America/New_York").Format(Time::FORMAT_TIME_24H), "15:01");
+
+ Time tm3(2016, 9, 17, 4, 1, 0, 0, "Asia/Seoul");
+ EXPECT_EQ(tm3.InTimezone("Europe/Warsaw").Format(Time::FORMAT_TIME_24H), "21:01");
+ EXPECT_EQ(tm3.InTimezone("America/New_York").Format(Time::FORMAT_TIME_24H), "15:01");
+}
+
+TEST(TimeTestSuite, test_timezonebyoffset)
+{
+ EXPECT_EQ(Time::GetTimezoneNameByOffset(0), "GMT+0:00");
+ EXPECT_EQ(Time::GetTimezoneNameByOffset(1), "GMT+0:01");
+ EXPECT_EQ(Time::GetTimezoneNameByOffset(-1), "GMT-0:01");
+ EXPECT_EQ(Time::GetTimezoneNameByOffset(-10), "GMT-0:10");
+ EXPECT_EQ(Time::GetTimezoneNameByOffset(-10), "GMT-0:10");
+ EXPECT_EQ(Time::GetTimezoneNameByOffset(-(60 * 1 + 59)), "GMT-1:59");
+ EXPECT_EQ(Time::GetTimezoneNameByOffset(60 * 1 + 59), "GMT+1:59");
+ EXPECT_EQ(Time::GetTimezoneNameByOffset(-(60 * 12 + 59)), "GMT-12:59");
+ EXPECT_EQ(Time::GetTimezoneNameByOffset(60 * 12 + 59), "GMT+12:59");
+}
+
+TEST(TimeTestSuite, test_timezonebyoffset_with_dates)
+{
+ Time tm1(2016, 9, 17, 23, 11, 0, 0, Time::GetTimezoneNameByOffset(0).c_str());
+ EXPECT_EQ(tm1.InTimezone(Time::GetTimezoneNameByOffset(0).c_str()).Format(Time::FORMAT_TIME_12H), "11:11");
+ EXPECT_EQ(tm1.InTimezone(Time::GetTimezoneNameByOffset(1).c_str()).Format(Time::FORMAT_TIME_12H), "11:12");
+ EXPECT_EQ(tm1.InTimezone(Time::GetTimezoneNameByOffset(-1).c_str()).Format(Time::FORMAT_TIME_12H), "11:10");
+ EXPECT_EQ(tm1.InTimezone(Time::GetTimezoneNameByOffset(60 * 1 + 30).c_str()).Format(Time::FORMAT_TIME_12H), "12:41");
+ EXPECT_EQ(tm1.InTimezone(Time::GetTimezoneNameByOffset(-(60 * 1 + 30)).c_str()).Format(Time::FORMAT_TIME_12H), "9:41");
+}
+
+TEST(TimeTestSuite, test_tm_conmvert)
+{
+ Time tm1(2016, 9, 17, 23, 11, 9, 0, "Europe/Warsaw");
+ auto tm = tm1.GetTMStruct();
+ EXPECT_EQ(tm.tm_year, 116);
+ EXPECT_EQ(tm.tm_mon, 8);
+ EXPECT_EQ(tm.tm_mday, 17);
+ EXPECT_EQ(tm.tm_wday, 6);
+ EXPECT_EQ(tm.tm_yday, 261);
+ EXPECT_EQ(tm.tm_hour, 23);
+ EXPECT_EQ(tm.tm_min, 11);
+ EXPECT_EQ(tm.tm_sec, 9);
+ EXPECT_TRUE(!strcmp(tm.tm_zone, "Europe/Warsaw"));
+}
+
+TEST(TimeTestSuite, test_long_format)
+{
+ Time tm1(2016, 9, 17, 23, 11, 9, 0, "Europe/Warsaw");
+ EXPECT_EQ(tm1.Format("QQQQ ? MMM d EEEE H:m:s"), "3rd quarter ? Sep 17 Saturday 23:11:9");
+}
+
+TEST(TimeTestSuite, test_long_local_format)
+{
+ Time tm1(2016, 9, 17, 23, 11, 9, 0, "Europe/Warsaw");
+ EXPECT_EQ(tm1.LocalFormat("QQQQ MMM d EEEE H:m:s"), "Saturday, Sep 17 (quarter: 3rd quarter), 23:11:09");
+}
+
+TEST(TimeTestSuite, test_format_local)
+{
+ Time tm1(2016, 9, 17, 23, 11, 0, 0, "Europe/Warsaw");
+ EXPECT_EQ(tm1.LocalFormat("h:mm"), "11:11 PM");
+}
+
+
<targetFile>Clock.cpp</targetFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Common/CounterAnimator.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Controller/MainController.o</targetObjectFile>
+<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Controller/RingController.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/Alarm.o</targetObjectFile>
+<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/AlarmEvent.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/AlarmProvider.o</targetObjectFile>
+<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/AlarmProviderEvent.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/AlarmProviderFile.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/StopWatch.o</targetObjectFile>
+<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/Timer.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/WeekFlags.o</targetObjectFile>
+<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/WorldClock.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Presenter/AlarmPresenter.o</targetObjectFile>
+<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Presenter/DeleteAlarmPresenter.o</targetObjectFile>
+<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Presenter/EditAlarmPresenter.o</targetObjectFile>
+<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Presenter/RingPresenter.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Presenter/StopWatchPresenter.o</targetObjectFile>
+<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Presenter/TimerPresenter.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Utils/BinaryFileReader.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Utils/BinaryFileWriter.o</targetObjectFile>
+<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Utils/EventBus.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Utils/Serialization.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Utils/Time.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Utils/Utils.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/View/AlarmView.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/View/CounterView.o</targetObjectFile>
+<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/View/DeleteAlarmView.o</targetObjectFile>
+<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/View/EditAlarmView.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/View/MainView.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/View/PageView.o</targetObjectFile>
+<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/View/RingView.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/View/StopWatchView.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/View/TimerView.o</targetObjectFile>
+<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/View/WeekFlagsView.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/View/WorldClockView.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Controller/RingController.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/Timer.o</targetObjectFile>
<option defaultValue="gnu.cpp.compiler.debugging.level.max" id="sbi.gnu.cpp.compiler.option.debugging.level.core.560740604" name="Debug level" superClass="sbi.gnu.cpp.compiler.option.debugging.level.core" valueType="enumerated"/>
<option defaultValue="false" id="sbi.gnu.cpp.compiler.option.misc.pic.core.1289916342" name="-fPIC option" superClass="sbi.gnu.cpp.compiler.option.misc.pic.core" valueType="boolean"/>
<option id="sbi.gnu.cpp.compiler.option.1180801303" name="Tizen-Target" superClass="sbi.gnu.cpp.compiler.option" valueType="userObjs">
- <listOptionValue builtIn="false" value="mobile-3.0-device.core_llvm36.armel.core.app"/>
+ <listOptionValue builtIn="false" value="mobile-3.0-emulator.core_llvm36.i386.core.app"/>
</option>
<option id="sbi.gnu.cpp.compiler.option.frameworks_inc.core.728385348" name="Tizen-Frameworks-Include-Path" superClass="sbi.gnu.cpp.compiler.option.frameworks_inc.core" valueType="includePath">
<listOptionValue builtIn="false" value=""${SBI_SYSROOT}/usr/include/libxml2""/>
<listOptionValue builtIn="false" value="${RS_COMPILER_MISC}"/>
<listOptionValue builtIn="false" value=" -fPIE"/>
<listOptionValue builtIn="false" value="--sysroot="${SBI_SYSROOT}""/>
- <listOptionValue builtIn="false" value="-mthumb"/>
</option>
<option id="gnu.cpp.compiler.option.include.paths.1668895094" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc}""/>
<option defaultValue="gnu.c.debugging.level.max" id="sbi.gnu.c.compiler.option.debugging.level.core.1101789042" name="Debug level" superClass="sbi.gnu.c.compiler.option.debugging.level.core" valueType="enumerated"/>
<option defaultValue="false" id="sbi.gnu.c.compiler.option.misc.pic.core.207975531" name="-fPIC option" superClass="sbi.gnu.c.compiler.option.misc.pic.core" valueType="boolean"/>
<option id="sbi.gnu.c.compiler.option.600001807" name="Tizen-Target" superClass="sbi.gnu.c.compiler.option" valueType="userObjs">
- <listOptionValue builtIn="false" value="mobile-3.0-device.core_llvm36.armel.core.app"/>
+ <listOptionValue builtIn="false" value="mobile-3.0-emulator.core_llvm36.i386.core.app"/>
</option>
<option id="sbi.gnu.c.compiler.option.frameworks_inc.core.2111102001" name="Tizen-Frameworks-Include-Path" superClass="sbi.gnu.c.compiler.option.frameworks_inc.core" valueType="includePath">
<listOptionValue builtIn="false" value=""${SBI_SYSROOT}/usr/include/libxml2""/>
<listOptionValue builtIn="false" value="${RS_COMPILER_MISC}"/>
<listOptionValue builtIn="false" value=" -fPIE"/>
<listOptionValue builtIn="false" value="--sysroot="${SBI_SYSROOT}""/>
- <listOptionValue builtIn="false" value="-mthumb"/>
</option>
<option id="gnu.c.compiler.option.include.paths.2001094680" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc}""/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
- <tool command="arm-linux-gnueabi-as" id="org.tizen.nativeapp.tool.sbi.gnu.assembler.base.784950171" name="Assembler" superClass="org.tizen.nativeapp.tool.sbi.gnu.assembler.base">
+ <tool command="i386-linux-gnueabi-as" id="org.tizen.nativeapp.tool.sbi.gnu.assembler.base.784950171" name="Assembler" superClass="org.tizen.nativeapp.tool.sbi.gnu.assembler.base">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1097107177" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<tool id="org.tizen.nativecore.tool.fnmapgen.1050341554" name="C FN-Map Generator" superClass="org.tizen.nativecore.tool.fnmapgen"/>
#include "View/View.h"
#include "Model/StopWatch.h"
#include "Common/CounterAnimator.h"
-#include "Utils/Time.h"
namespace presenter {
view::StopWatchView *ui_;
model::StopWatch *model_;
+ struct Time {
+ unsigned int Hour, Min, Sec, Msec;
+ };
common::CounterAnimator animator_;
void StartButtonClicked(void);
void TimeUpdateRequest(void);
std::string GetTimeString(std::chrono::milliseconds time);
- utils::Time GetTimeStructure(std::chrono::milliseconds time);
+ Time GetTimeStructure(std::chrono::milliseconds time);
};
}
#include "Common/Defines.h"
#include "Utils/Serialization.h"
+#include <map>
+#include <ctime>
+#include <utils_i18n.h>
+
namespace utils {
- enum Format {
- FORMAT_12H,
- FORMAT_24H
- };
class Time : public utils::ISerializable {
public:
- unsigned int Hour, Min, Sec, Msec;
- Time() : Hour(0), Min(0), Sec(0) , Msec(0) {}
- Time(unsigned int h, unsigned int m, unsigned int s, unsigned int ms = 0) : Hour(h), Min(m), Sec(s), Msec(ms) {}
+ /** Predefined formats for convenience */
+ static const char *FORMAT_TIME_12H;// = "h:mm";
+ static const char *FORMAT_TIME_24H; // = "HH:mm";
+ static const char *FORMAT_TIME_AMPM; // = "a";
+
+ enum class Month {
+ January = I18N_UCALENDAR_JANUARY,
+ Febuary = I18N_UCALENDAR_FEBRUARY,
+ March = I18N_UCALENDAR_MARCH,
+ April = I18N_UCALENDAR_APRIL,
+ May = I18N_UCALENDAR_MAY,
+ June = I18N_UCALENDAR_JUNE,
+ July = I18N_UCALENDAR_JULY,
+ August = I18N_UCALENDAR_AUGUST,
+ September = I18N_UCALENDAR_SEPTEMBER,
+ October = I18N_UCALENDAR_OCTOBER,
+ November = I18N_UCALENDAR_NOVEMBER,
+ December = I18N_UCALENDAR_DECEMBER,
+ };
+
+ Time() : timezone_(GetCurrentTimezone()), milliseconds_(0) {}
+
+ /**
+ * @brief copy constructor
+ */
+ Time(const Time &tm);
+
+ /**
+ * @brief Creates new Time in given timezone
+ *
+ * @note if timezone parameter is null, the local timezone will be
+ * used instead.
+ */
+ Time(unsigned int year, Month month, unsigned int day,
+ unsigned int hour, unsigned int minute, unsigned int seconds,
+ unsigned int miliseconds, const char *timezone = nullptr);
+
+ /**
+ * @brief Deserialization constructor
+ */
Time(utils::IReader &);
+
+ /**
+ * @brief Serialization constructor
+ */
void Serialize(utils::IWriter &w) const;
- inline bool operator==(const Time &a) { return (a.Hour == Hour ) &&
- (a.Min == Min) && (a.Sec == Sec) && (a.Msec == Msec); }
- std::string Format(enum Format format) const;
- std::string Meridiem() const;
- std::string GetMeridiemByOffset(int timezone_offset) const;
- std::string GetFormattedTime(const char *icu_format) const;
- std::string GetFormattedTimeByTimezoneOffset(const char *icu_format, int timezone_offset) const;
- int GetLocalTimezoneOffset(void) const;
- const std::string GetTimezoneRelativeToLocalString(int timezone_offset);
- std::string GetTimezoneDate(int timezone_offset);
-
- std::string GetDate() const;
+ /**
+ * @brief Compare operator
+ */
+ bool operator==(const Time &a);
+
+ /**
+ * @brief Return year AD.
+ */
+ unsigned int GetYear() const;
+
+ /**
+ * @brief Return month
+ */
+ Month GetMonth() const;
+
+ /**
+ * @brief Return a number of day in given month [1-31]
+ */
+ unsigned int GetDay() const;
+
+ /**
+ * @brief Return hour [0-23]
+ */
+ unsigned int GetHour() const;
+
+ /**
+ * @brief Return minute [0-59]
+ */
+ unsigned int GetMinute() const;
+
+ /**
+ * @brief Return second [0-59]
+ */
+ unsigned int GetSecond() const;
+
+ /**
+ * @brief Return milliseconds [0-999]
+ */
+ unsigned int GetMilliSec() const;
+
+ /**
+ * @brief Returns textual representation of time.
+ *
+ * @param format i18n valid format. Please refer to Tizen utils_i18n.h
+ * documentation formats for reference.
+ *
+ * example: "HH:mm", "h:mm a"
+ */
+ std::string Format(const char *format) const;
+
+ /**
+ * @brief Returns textual representation of time adjusted to local
+ * preferences.
+ *
+ * @param format i18n valid format. Please refer to Tizen utils_i18n.h
+ * documentation formats for reference.
+ *
+ * @note It is guaranteed that textual representation will contain
+ * all fields specified in format parameter. Some additional fields
+ * may be appended according to local preferences.
+ */
+ std::string LocalFormat(const char *format) const;
+
+ /**
+ * Return current local time
+ */
static Time Now(void);
+
+ /**
+ * @brief Returns Time adjusted to localtime.
+ */
+ Time Local() const;
+
+ /**
+ * @brief Returns Time adjusted to given timezone.
+ *
+ * @param timezone valid i18n timezone string.
+ */
+ Time InTimezone(const char *timezone) const;
+
+ /**
+ * @brief Converts time to tm struct
+ *
+ * @note returned tm_zone remains valid until Time object is
+ * destroyed.
+ */
+ std::tm GetTmStruct() const;
+
+ /**
+ * @brief Return timezone in "GMT+1:00" format according to
+ * given offset
+ *
+ * @param[in] offset timezone offset in minutes.
+ */
+ static std::string GetTimezoneNameByOffset(int offset);
+
+ /**
+ * @brief Return timezone offset.
+ *
+ * @param[in] timezone valid timezone id.
+ *
+ * @ret difference in minutes between "timezone" and GMT:+00
+ * @note return INT_MAX when timezone string is invalid.
+ */
+ static int GetTimezoneOffset(const char *timezone);
+
+ /**
+ * @brief Get current timezone
+ */
+ static const std::string &GetCurrentTimezone();
+
+ private:
+ Time(double milliseconds, const std::string &tz);
+
+ std::string timezone_;
+ double milliseconds_;
+
+ static const char *GetLocale();
+ static std::map<std::string, std::string> best_patterns_cache;
+ static std::string FormatInternal(double time, const std::string &timezone,
+ const char *locale, const char *pattern, size_t buf_len = 32);
+ static const std::string *GetBestPattern(const char *locale,
+ const char *skeleton);
+ static std::string GenerateBestPattern(const char *locale,
+ const char *skeleton, unsigned int m = 2);
};
} /* utils */
#include "View/View.h"
#include "View/PageView.h"
#include "View/CounterView.h"
-#include "Utils/Time.h"
namespace view {
Evas_Object *selector_ = NULL;
view::CounterView *counter_ = NULL;
- utils::Time set_time_;
+ struct Time {
+ Time() : Hour(0), Min(0), Sec(0) {}
+ unsigned int Hour, Min, Sec;
+ };
+ Time set_time_;
std::vector<std::function<void(void)>> signals
= std::vector<std::function<void(void)>>((int)TimerSignal::MAX, nullptr);
void Alarm::Activate()
{
int err;
- struct tm tmtime = {0, };
+ struct tm tmtime = time.GetTmStruct();
if (activated)
return;
- err = alarm_get_current_time(&tmtime);
- if (err != ALARM_ERROR_NONE) {
- ERR("alarm_get_current_time failed: %s", get_error_message(err));
- return;
- }
-
app_control_h control = AppControlCreate();
if (!control) {
DBG("AppControlCreate failed");
return;
}
- tmtime.tm_hour = time.Hour;
- tmtime.tm_min= time.Min;
- tmtime.tm_sec= time.Sec;
-
err = alarm_schedule_with_recurrence_week_flag(
control,
&tmtime,
utils::Time time = alarm_->GetTime();
- view_->SetTitle(alarm_->GetName().c_str());
- view_->SetTimeLabel(time.Meridiem().c_str(), time.GetFormattedTime("HH:mm").c_str(), time.GetDate().c_str());
+ view->SetTitle(alarm->GetName().c_str());
+ view->SetTimeLabel(time.Format(utils::Time::FORMAT_TIME_AMPM).c_str(),
+ time.Format(utils::Time::FORMAT_TIME_12H).c_str(),
+ time.Format("E, d MMMM").c_str());
if (utils::Utils::FileExists(alarm_->GetMelody().c_str()))
view_->PlayMusic(alarm_->GetMelody().c_str(), alarm_->GetVolume());
else {
{
milliseconds time = model_->GetTime();
- utils::Time ts = GetTimeStructure(time);
+ Time ts = GetTimeStructure(time);
ui_->DisplayTime(ts.Hour, ts.Min, ts.Sec, ts.Msec);
const model::Lap *last = model_->GetLastLap();
ui_->DisplayLapTime(ts.Hour, ts.Min, ts.Sec, ts.Msec);
}
-utils::Time StopWatchPresenter::GetTimeStructure(milliseconds time)
+StopWatchPresenter::Time StopWatchPresenter::GetTimeStructure(milliseconds time)
{
- utils::Time ts;
+ Time ts;
ts.Hour = duration_cast<hours>(time).count() % 100;
ts.Min = duration_cast<minutes>(time).count() % 60;
#include "Utils/Time.h"
#include "Utils/Log.h"
-#include <utils_i18n.h>
#include <cstring>
#include <ctime>
#include <Elementary.h>
+#include <system_settings.h>
+
using namespace utils;
+
+const char *Time::FORMAT_TIME_12H = "h:mm";
+const char *Time::FORMAT_TIME_24H = "HH:mm";
+const char *Time::FORMAT_TIME_AMPM = "a";
+const int BEST_PATTERNS_CACHE_MAX_CAPACITY = 10;
+
+std::map<std::string, std::string> Time::best_patterns_cache;
+
+
Time::Time(utils::IReader &r)
{
- utils::Deserialize(r, Hour);
- utils::Deserialize(r, Min);
- utils::Deserialize(r, Sec);
- utils::Deserialize(r, Msec);
+ utils::Deserialize(r, timezone_);
+ utils::Deserialize(r, milliseconds_);
}
void Time::Serialize(utils::IWriter &w) const
{
- utils::Serialize(w, Hour);
- utils::Serialize(w, Min);
- utils::Serialize(w, Sec);
- utils::Serialize(w, Msec);
+ utils::Serialize(w, timezone_);
+ utils::Serialize(w, milliseconds_);
+}
+
+// Simple wrapper around i18n_uchar strings to simplify i18n_uchar strings
+// management
+class I18nString {
+ public:
+ I18nString(const char *str = nullptr);
+ I18nString(const std::string &str);
+ ~I18nString();
+ void reserve(size_t max_characters);
+ const i18n_uchar *i18n_str() const { return data_;}
+ std::string std_string() const;
+ i18n_uchar& operator[](int index);
+ size_t size() const { return size_;}
+ private:
+ i18n_uchar *data_;
+ size_t size_;
+};
+
+I18nString::I18nString(const char *str)
+{
+ str = str ? str : "";
+ size_ = strlen(str);
+ data_ = new i18n_uchar[size_ + 1];
+ i18n_ustring_copy_ua_n(data_, str, size_ + 1);
+ if (get_last_result() != I18N_ERROR_NONE) {
+ FAT("i18n_ustring_copy_ua_n failed");
+ }
+}
+
+i18n_uchar& I18nString::operator[](int index)
+{
+ return data_[index];
+}
+
+I18nString::I18nString(const std::string &str)
+{
+ size_ = str.size();
+ data_ = new i18n_uchar[size_ + 1];
+ i18n_ustring_copy_ua_n(data_, str.c_str(), size_ + 1);
+ if (get_last_result() != I18N_ERROR_NONE) {
+ FAT("i18n_ustring_copy_ua_n failed");
+ }
+}
+
+void I18nString::reserve(size_t max_characters)
+{
+ size_ = max_characters;
+ delete[] data_;
+ data_ = new i18n_uchar[size_ + 1]();
+}
+
+I18nString::~I18nString()
+{
+ delete[] data_;
+}
+
+std::string I18nString::std_string() const
+{
+ std::string str;
+ size_t new_size = i18n_ustring_get_length(data_);
+ if (get_last_result() != I18N_ERROR_NONE) {
+ FAT("i18n_ustring_copy_ua_n failed");
+ }
+ str.reserve(new_size + 1);
+ str.resize(new_size);
+ i18n_ustring_copy_au(&str[0], data_);
+ if (get_last_result() != I18N_ERROR_NONE) {
+ FAT("i18n_ustring_copy_ua_n failed");
+ }
+ return str;
+}
+
+/**
+ * @locale -> can be NULL
+ * @skeleton -> cannot be NULL
+ */
+std::string Time::GenerateBestPattern(const char *locale, const char *skeleton, unsigned int multip)
+{
+ i18n_udatepg_h generator;
+ I18nString u_best_pattern;
+ I18nString u_skeleton(skeleton);
+ int32_t best_pattern_len;
+
+ // estimate required output lenght - should be enough in 99% cases
+ u_best_pattern.reserve(u_skeleton.size() * multip);
+
+ int err = i18n_udatepg_create(NULL, &generator);
+ if (err != I18N_ERROR_NONE) {
+ ERR("i18n_udatepg_create failed: %s", get_error_message(err));
+ return "";
+ }
+
+ err = i18n_udatepg_get_best_pattern(generator, u_skeleton.i18n_str(),
+ u_skeleton.size(), &u_best_pattern[0], u_best_pattern.size(), &best_pattern_len);
+ if (err == I18N_ERROR_BUFFER_OVERFLOW) {
+ INF("Best pattern too long: %s. Retrying with longer buffer...", skeleton);
+ i18n_udatepg_destroy(generator);
+ return GenerateBestPattern(locale, skeleton, multip + 1);
+ } else if (err != I18N_ERROR_NONE) {
+ ERR("i18n_udatepg_get_best_pattern failed[%d]: %s", err, get_error_message(err));
+ i18n_udatepg_destroy(generator);
+ return "";
+ }
+
+ i18n_udatepg_destroy(generator);
+ return u_best_pattern.std_string();
}
-std::string Time::Format(enum Format format) const
+/**
+ * Gets best pattern for given locale, containing all fields specified in skeleton
+ */
+const std::string *Time::GetBestPattern(const char *locale, const char *skeleton)
{
- switch (format) {
- case FORMAT_12H:
- return GetFormattedTime("h:mm");
- case FORMAT_24H:
- return GetFormattedTime("HH:mm");
+ // use small cache to speed up matching patterns
+ auto it = best_patterns_cache.find(skeleton);
+
+ if (it != best_patterns_cache.end()) {
+ return &(it->second);
+ }
+
+ // if not found generate new localized pattern using i18n
+ std::string best_pattern = GenerateBestPattern(locale, skeleton);
+ if (best_pattern == "") {
+ ERR("Unable to generate localized format pattern for '%s'", skeleton);
+ return nullptr;
}
- abort();
- return "";
+
+ // clear cache if exceeded max capacity
+ if (best_patterns_cache.size() > BEST_PATTERNS_CACHE_MAX_CAPACITY)
+ best_patterns_cache.clear();
+
+ auto it2 = best_patterns_cache.insert(std::pair<std::string, std::string>(skeleton, best_pattern));
+
+ return &(it2.first->second);
}
-std::string Time::Meridiem() const
+std::string Time::LocalFormat(const char *format) const
{
- return Hour >= 12 ? "PM" : "AM";
+ if (!format) return "";
+
+ const std::string *pattern = GetBestPattern(GetLocale(), format);
+ if (!pattern) {
+ ERR("Unable to get localized format.");
+ return "";
+ }
+ return FormatInternal(milliseconds_, timezone_, GetLocale(), pattern->c_str());
}
-std::string Time::GetMeridiemByOffset(int timezone_offset) const
+std::string Time::Format(const char *format) const
{
- return "PM";
+ if (!format) return "";
+ return FormatInternal(milliseconds_, timezone_, GetLocale(), format);
}
-std::string Time::GetFormattedTime(const char *icu_format) const
+std::string Time::FormatInternal(double time, const std::string &timezone,
+ const char *locale, const char *pattern, size_t buf_len)
{
- char buf[32] = {0,};
- if (!strcmp(icu_format, "HH:mm")) {
- snprintf(buf, sizeof(buf), "%d:%d", Hour, Min);
+ i18n_udate_format_h formatter;
+ I18nString u_timezone(timezone);
+ I18nString u_pattern(pattern);
+ I18nString u_formatted;
+ i18n_udate u_date = (i18n_udate)time;
+ int32_t formatted_size_needed;
+
+ int err = i18n_udate_create(I18N_UDATE_PATTERN, I18N_UDATE_PATTERN, locale,
+ u_timezone.i18n_str(), -1, u_pattern.i18n_str(), -1, &formatter);
+ if (err != I18N_ERROR_NONE) {
+ ERR("i18n_udate_create failed: %s", get_error_message(err));
+ return "";
}
- if (!strcmp(icu_format, "h:mm")) {
- snprintf(buf, sizeof(buf), "%d:%d", Hour > 12 ? Hour - 12 : Hour, Min);
+
+ u_formatted.reserve(buf_len);
+
+ err = i18n_udate_format_date(formatter, u_date, &u_formatted[0], u_formatted.size(),
+ nullptr, &formatted_size_needed);
+ if (err == I18N_ERROR_BUFFER_OVERFLOW) {
+ INF("Buffer not sufficient. Retrying with bigger buffer...");
+ i18n_udate_destroy(formatter);
+ return FormatInternal(time, timezone, locale, pattern, buf_len * 2);
+ } else if (err != I18N_ERROR_NONE) {
+ ERR("i18n_udate_format_date failed: %s", get_error_message(err));
+ i18n_udate_destroy(formatter);
+ return "";
}
- return buf;
+
+ i18n_udate_destroy(formatter);
+ return u_formatted.std_string();
}
-std::string Time::GetFormattedTimeByTimezoneOffset(const char *icu_format, int timezone_offset) const
+Time::Time(unsigned int year, Month month, unsigned int day,
+ unsigned int hour, unsigned int minute, unsigned int seconds,
+ unsigned int miliseconds, const char *timezone)
{
- return "15:01";
+ i18n_ucalendar_h calendar;
+ i18n_udate udate;
+
+ if (!timezone)
+ timezone_ = GetCurrentTimezone();
+ else
+ timezone_ = timezone;
+
+ I18nString u_timezone(timezone_);
+
+ int err = i18n_ucalendar_create(u_timezone.i18n_str(), -1, nullptr,
+ I18N_UCALENDAR_GREGORIAN, &calendar);
+ if (err != I18N_ERROR_NONE) {
+ FAT("i18n_ucalendar_create failed[%d]: %s", err, get_error_message(err));
+ }
+
+ err = i18n_ucalendar_set_date_time(calendar,
+ year, (int)month, day, hour, minute, seconds);
+ if (err != I18N_ERROR_NONE) {
+ i18n_ucalendar_destroy(calendar);
+ FAT("i18n_ucalendar_set_date_time failed[%d]: %s", err, get_error_message(err));
+ }
+
+ err = i18n_ucalendar_get_milliseconds(calendar, &udate);
+ if (err != I18N_ERROR_NONE) {
+ i18n_ucalendar_destroy(calendar);
+ FAT("i18n_ucalendaer_get_miliseconds failed[%d]: %s", err, get_error_message(err));
+ }
+
+ milliseconds_ = udate;
+ i18n_ucalendar_destroy(calendar);
}
-int Time::GetLocalTimezoneOffset(void) const
+bool Time::operator==(const Time &a)
{
- return 60;
+ return a.milliseconds_ == milliseconds_;
}
-const std::string Time::GetTimezoneRelativeToLocalString(int timezone_offset)
+Time Time::Now(void)
{
- char *pattern;
- static char relative[128] = { 0, };
- std::string s;
+ i18n_udate handle;
+
+ int err = i18n_ucalendar_get_now(&handle);
+ if (err != I18N_ERROR_NONE) {
+ FAT("i18n_ucalendar_get_now failed[%d]: %s", err, get_error_message(err));
+ }
- int local_timezone_offset = GetLocalTimezoneOffset();
- int offset_integer = (abs(timezone_offset - local_timezone_offset)) / 60;
- int offset_remainder = (abs(timezone_offset - local_timezone_offset)) % 60;
+ return Time(double(handle), GetCurrentTimezone());
+}
- DBG("passed offset:%d, local:%d, remainder:%d", timezone_offset,
- local_timezone_offset, offset_remainder);
+const char *Time::GetLocale()
+{
+ static const char *locale;
- if (timezone_offset < local_timezone_offset) {
- if (offset_remainder > 0) {
- pattern = _("IDS_CLOCK_BODY_PS1D_H_P2SD_M_BEHIND_ABB");
- snprintf(relative, sizeof(relative), pattern, offset_integer,
- offset_remainder);
+ if (!locale) {
+ char *l;
+ int ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &l);
+ if (ret != SYSTEM_SETTINGS_ERROR_NONE) {
+ ERR("system_settings_get_value_string failed: %s", get_error_message(ret));
+ locale = getenv("LOCALE") ? strdup(getenv("LOCALE")) : "";
} else {
- pattern = _("IDS_CLOCK_BODY_PD_H_BEHIND_ABB");
- snprintf(relative, sizeof(relative), pattern, offset_integer);
+ locale = l;
}
+ if (!locale)
+ FAT("Unable to get current locale.");
+ }
+ return locale;
+}
- } else if (timezone_offset > local_timezone_offset) {
- if (offset_remainder > 0) {
- pattern = _("IDS_CLOCK_BODY_PS1D_H_P2SD_M_AHEAD_ABB");
- snprintf(relative, sizeof(relative), pattern, offset_integer,
- offset_remainder);
- } else {
- pattern = _("IDS_CLOCK_BODY_PD_H_AHEAD_ABB");
- snprintf(relative, sizeof(relative), pattern, offset_integer);
+Time Time::Local() const
+{
+ return Time(milliseconds_, GetCurrentTimezone());
+}
+
+Time Time::InTimezone(const char *timezone) const
+{
+ return Time(milliseconds_, timezone);
+}
+
+const std::string& Time::GetCurrentTimezone()
+{
+ static std::string timezone;
+
+ if (timezone.empty()) {
+ i18n_timezone_h handle;
+ char *timezone_str;
+ int err = i18n_timezone_create_default(&handle);
+ if (err != I18N_ERROR_NONE) {
+ FAT("i18n_timezone_create_default failed: %s", get_error_message(err));
}
+ err = i18n_timezone_get_id(handle, &timezone_str);
+ if (err != I18N_ERROR_NONE) {
+ i18n_timezone_destroy(handle);
+ FAT("i18n_timezone_get_id failed: %s", get_error_message(err));
+ }
+ i18n_timezone_destroy(handle);
+ timezone = std::string(timezone_str);
+ free(timezone_str);
+ }
+ return timezone;
+}
+
+Time::Time(double milliseconds, const std::string &tz)
+{
+ timezone_ = tz;
+ milliseconds_ = milliseconds;
+}
- } else {
- snprintf(relative, sizeof(relative), "Same as local time");
+std::string Time::GetTimezoneNameByOffset(int offset)
+{
+ char buf[16];
+ char sign = offset >= 0 ? '+' : '-';
+
+ int hours = abs(offset) / 60;
+ int minutes = abs(offset) % 60;
+
+ snprintf(buf, sizeof(buf), "GMT%c%d:%02d", sign, hours, minutes);
+ return std::string(buf);
+}
+
+static int GetCalendarField(double milliseconds, const char *zone, const char *locale,
+ i18n_ucalendar_date_fields_e field)
+{
+ i18n_ucalendar_h calendar;
+ I18nString u_zone(zone);
+ int32_t value;
+
+ int err = i18n_ucalendar_create(u_zone.i18n_str(), -1, locale,
+ I18N_UCALENDAR_GREGORIAN, &calendar);
+ if (err != I18N_ERROR_NONE) {
+ ERR("i18n_ucalendar_create failed: %s", get_error_message(err));
+ return -1;
+ }
+
+ err = i18n_ucalendar_set_milliseconds(calendar, (i18n_udate)milliseconds);
+ if (err != I18N_ERROR_NONE) {
+ ERR("i18n_ucalendar_set_milliseconds failed: %s", get_error_message(err));
+ i18n_ucalendar_destroy(calendar);
+ return -1;
+ }
+
+ err = i18n_ucalendar_get(calendar, field, &value);
+ if (err != I18N_ERROR_NONE) {
+ ERR("i18n_ucalendar_get failed: (%d) %s", field, get_error_message(err));
+ i18n_ucalendar_destroy(calendar);
+ return -1;
}
- return &relative[0];
+
+ i18n_ucalendar_destroy(calendar);
+ return value;
+}
+
+unsigned int Time::GetYear() const
+{
+ return GetCalendarField(milliseconds_, timezone_.c_str(), GetLocale(), I18N_UCALENDAR_YEAR);
+}
+
+Time::Month Time::GetMonth() const
+{
+ return (Time::Month)GetCalendarField(milliseconds_, timezone_.c_str(), GetLocale(), I18N_UCALENDAR_MONTH);
+}
+
+unsigned int Time::GetDay() const
+{
+ return GetCalendarField(milliseconds_, timezone_.c_str(), GetLocale(), I18N_UCALENDAR_DAY_OF_MONTH);
+}
+
+unsigned int Time::GetHour() const
+{
+ return GetCalendarField(milliseconds_, timezone_.c_str(), GetLocale(), I18N_UCALENDAR_HOUR_OF_DAY);
+}
+
+unsigned int Time::GetMinute() const
+{
+ return GetCalendarField(milliseconds_, timezone_.c_str(), GetLocale(), I18N_UCALENDAR_MINUTE);
+}
+
+unsigned int Time::GetSecond() const
+{
+ return GetCalendarField(milliseconds_, timezone_.c_str(), GetLocale(), I18N_UCALENDAR_SECOND);
+}
+
+unsigned int Time::GetMilliSec() const
+{
+ return int(milliseconds_) % 1000;
}
-std::string Time::GetTimezoneDate(int timezone_offset)
+static int i18n_calendar_month_2_tm_month(int icu_month)
{
- return "Mon 32 Aug";
+ switch (icu_month) {
+ case I18N_UCALENDAR_JANUARY:
+ return 0;
+ case I18N_UCALENDAR_FEBRUARY:
+ return 1;
+ case I18N_UCALENDAR_MARCH:
+ return 2;
+ case I18N_UCALENDAR_APRIL:
+ return 3;
+ case I18N_UCALENDAR_MAY:
+ return 4;
+ case I18N_UCALENDAR_JUNE:
+ return 5;
+ case I18N_UCALENDAR_JULY:
+ return 6;
+ case I18N_UCALENDAR_AUGUST:
+ return 7;
+ case I18N_UCALENDAR_SEPTEMBER:
+ return 8;
+ case I18N_UCALENDAR_OCTOBER:
+ return 9;
+ case I18N_UCALENDAR_NOVEMBER:
+ return 10;
+ case I18N_UCALENDAR_DECEMBER:
+ return 11;
+ }
+ FAT("Invalid month constant.");
+ return -1;
}
-std::string Time::GetDate() const
+std::tm Time::GetTmStruct() const
{
- time_t now;
- time(&now);
+ std::tm tmstruct = {0,};
+ i18n_ucalendar_h calendar;
+ I18nString u_zone(timezone_);
+ int32_t value;
+
+ int err = i18n_ucalendar_create(u_zone.i18n_str(), -1, GetLocale(),
+ I18N_UCALENDAR_GREGORIAN, &calendar);
+ if (err != I18N_ERROR_NONE) {
+ ERR("i18n_ucalendar_create failed: %s", get_error_message(err));
+ return tmstruct;
+ }
+
+ err = i18n_ucalendar_set_milliseconds(calendar, (i18n_udate)milliseconds_);
+ if (err != I18N_ERROR_NONE) {
+ ERR("i18n_ucalendar_set_milliseconds failed: %s", get_error_message(err));
+ i18n_ucalendar_destroy(calendar);
+ return tmstruct;
+ }
+
+ i18n_ucalendar_get(calendar, I18N_UCALENDAR_YEAR, &value);
+ tmstruct.tm_year = value - 1900;
+
+ i18n_ucalendar_get(calendar, I18N_UCALENDAR_MONTH, &value);
+ tmstruct.tm_mon = i18n_calendar_month_2_tm_month(value);
- struct timeval *day;
+ i18n_ucalendar_get(calendar, I18N_UCALENDAR_DAY_OF_MONTH, &value);
+ tmstruct.tm_mday = value;
- struct tm *timeInfo = localtime(&now);
+ i18n_ucalendar_get(calendar, I18N_UCALENDAR_HOUR_OF_DAY, &value);
+ tmstruct.tm_hour = value;
- char buffer[128] = {0, };
+ i18n_ucalendar_get(calendar, I18N_UCALENDAR_MINUTE, &value);
+ tmstruct.tm_min = value;
- std::strftime(buffer, sizeof(buffer)/sizeof(buffer[0]), "%a, %e %B", timeInfo);
+ i18n_ucalendar_get(calendar, I18N_UCALENDAR_SECOND, &value);
+ tmstruct.tm_sec = value;
- return std::string(buffer);
+ i18n_ucalendar_get(calendar, I18N_UCALENDAR_DAY_OF_WEEK, &value);
+ tmstruct.tm_wday = value - 1;
+
+ i18n_ucalendar_get(calendar, I18N_UCALENDAR_DAY_OF_YEAR, &value);
+ tmstruct.tm_yday = value - 1;
+
+ tmstruct.tm_zone = timezone_.c_str();
+ tmstruct.tm_gmtoff = GetTimezoneOffset(timezone_.c_str()) * 60;
+
+ i18n_ucalendar_destroy(calendar);
+ return tmstruct;
}
-Time Time::Now(void)
+Time::Time(const Time &tm) :
+ timezone_(tm.timezone_),
+ milliseconds_(tm.milliseconds_)
{
- time_t ct;
- struct tm *ct_tm;
+}
- time(&ct);
- ct_tm = localtime(&ct);
- return Time(ct_tm->tm_hour, ct_tm->tm_min, 0);
+int Time::GetTimezoneOffset(const char *timezone_id)
+{
+ i18n_timezone_h handle;
+ int32_t offset;
+ int err = i18n_timezone_create(&handle, timezone_id);
+ if (err != I18N_ERROR_NONE) {
+ ERR("i18n_timezone_create failed[%d]: %s", err, get_error_message(err));
+ return INT_MAX;
+ }
+ err = i18n_timezone_get_raw_offset(handle, &offset);
+ if (err != I18N_ERROR_NONE) {
+ ERR("i18n_timezone_get_raw_offset failed[%d]: %s", err, get_error_message(err));
+ i18n_timezone_destroy(handle);
+ return INT_MAX;
+ }
+ i18n_timezone_destroy(handle);
+ return offset / (60 * 1000);
}
{
std::stringstream formatted_time;
- formatted_time << time.Format(FORMAT_12H);
+ formatted_time << time.Format(Time::FORMAT_TIME_12H);
formatted_time << " <meridiem>";
- formatted_time << time.Meridiem();
+ formatted_time << time.Format(Time::FORMAT_TIME_AMPM);
formatted_time << "</meridiem>";
return strdup(formatted_time.str().c_str());
{
std::stringstream formatted_time;
- formatted_time << time.Format(FORMAT_12H);
+ formatted_time << time.Format(Time::FORMAT_TIME_12H);
formatted_time << " <meridiem>";
- formatted_time << time.Meridiem();
+ formatted_time << time.Format(Time::FORMAT_TIME_AMPM);
formatted_time << "</meridiem>";
return strdup(formatted_time.str().c_str());
return label;
}
-inline static Elm_Datetime_Time ConvertTimeToElmDatetimeTime(const Time &atime)
+inline static Time::Month ConvertTmMont2TimeMonth(int mon)
{
- Elm_Datetime_Time elm_time = {0,};
- // set valid year, according to elm_datetime doc default years range is between
- // 1970-2037
- elm_time.tm_year = 100; // + 1900
- elm_time.tm_hour = atime.Hour;
- elm_time.tm_min = atime.Min;
- elm_time.tm_sec = atime.Sec;
- return elm_time;
+ switch (mon) {
+ case 0:
+ return Time::Month::January;
+ case 1:
+ return Time::Month::Febuary;
+ case 2:
+ return Time::Month::March;
+ case 3:
+ return Time::Month::April;
+ case 4:
+ return Time::Month::May;
+ case 5:
+ return Time::Month::June;
+ case 6:
+ return Time::Month::July;
+ case 7:
+ return Time::Month::August;
+ case 8:
+ return Time::Month::September;
+ case 9:
+ return Time::Month::October;
+ case 10:
+ return Time::Month::November;
+ case 11:
+ return Time::Month::December;
+ }
+ FAT("Invalid struct tm month value");
}
inline static Time ConvertElmDatetimeTimeToTime(const Elm_Datetime_Time &time)
{
- return Time(time.tm_hour, time.tm_min, time.tm_sec);
+ return Time(time.tm_year + 1900, ConvertTmMont2TimeMonth(time.tm_mon), time.tm_mday,
+ time.tm_hour, time.tm_min, 0, 0);
}
static const char *GetLabelForAlarmType(AlarmType type)
elm_theme_extension_add(NULL,
Utils::GetAppResourcePath(Utils::APP_DIR_RESOURCE, "edje/edit_alarm.edj"));
+ data_.time = Time::Now();
+
CreateGenlistItems();
}
elm_object_style_set(dt, "time_layout"); // from tizen-theme
evas_object_smart_callback_add(dt, "changed"
, EditAlarmView::DateTimeChangedCallback, view);
- auto elm_time = ConvertTimeToElmDatetimeTime(view->data_.time);
+ auto elm_time = view->data_.time.GetTmStruct();
elm_datetime_value_set(dt, &elm_time);
evas_object_show(dt);
return dt;
elm_layout_content_set(world_clock_, TIMEZONE_CUSTOM_LOCATIONS_LIST_PART, custom_locations_list_);
}
+// local_timezone_offset and timezone_offset should be relative to GMT
+std::string GetTimezoneDiffDescription(int local_timezone_offset, int timezone_offset)
+{
+ char *pattern;
+ char relative[128] = { 0, };
+
+ int offset_integer = (abs(timezone_offset - local_timezone_offset)) / 60;
+ int offset_remainder = (abs(timezone_offset - local_timezone_offset)) % 60;
+
+ if (timezone_offset < local_timezone_offset) {
+ if (offset_remainder > 0) {
+ pattern = _("IDS_CLOCK_BODY_PS1D_H_P2SD_M_BEHIND_ABB");
+ snprintf(relative, sizeof(relative), pattern, offset_integer,
+ offset_remainder);
+ } else {
+ pattern = _("IDS_CLOCK_BODY_PD_H_BEHIND_ABB");
+ snprintf(relative, sizeof(relative), pattern, offset_integer);
+ }
+ } else if (timezone_offset > local_timezone_offset) {
+ if (offset_remainder > 0) {
+ pattern = _("IDS_CLOCK_BODY_PS1D_H_P2SD_M_AHEAD_ABB");
+ snprintf(relative, sizeof(relative), pattern, offset_integer,
+ offset_remainder);
+ } else {
+ pattern = _("IDS_CLOCK_BODY_PD_H_AHEAD_ABB");
+ snprintf(relative, sizeof(relative), pattern, offset_integer);
+ }
+ } else {
+ snprintf(relative, sizeof(relative), "Same as local time");
+ }
+ return std::string(&relative[0]);
+}
+
void WorldClockView::AppendItemToCustomList(const model::Location *location)
{
LocationItemData *data = new LocationItemData;
- Time t;
+ Time t = Time::Now().InTimezone(
+ Time::GetTimezoneNameByOffset(location->gmt_offset_).c_str());;
+ int local_timezone_offset = Time::GetTimezoneOffset(Time::GetCurrentTimezone().c_str());
std::stringstream ss;
data->location = location;
ss << location->name << ", " << location->country;
data->city_country = strdup(ss.str().c_str());
- data->ampm = strdup(t.GetMeridiemByOffset(location->gmt_offset_).c_str());
- data->gmt_offset_relative = strdup(t.GetTimezoneRelativeToLocalString(location->gmt_offset_).c_str());
+ data->ampm = strdup(t.Format("a").c_str());
+ data->gmt_offset_relative = strdup(
+ GetTimezoneDiffDescription(local_timezone_offset, location->gmt_offset_).c_str());
data->gmt_offset = location->gmt_offset_;
- data->date = strdup(t.GetTimezoneDate(location->gmt_offset_).c_str());
+ data->date = strdup(t.Format("E d MMM").c_str());
data->it = elm_genlist_item_append(custom_locations_list_,
&world_clock_itc_,
elm_table_pack(lid->time, ampm, 2, 0, 1, 1);
elm_table_pack(lid->time, dynamic_padding, 3, 0, 1, 1);
- //TODO Time need to be set as current for specific timezone
- Time t;
+ Time t = Time::Now().InTimezone(Time::GetTimezoneNameByOffset(lid->gmt_offset).c_str());
- std::string timezone_time = t.GetFormattedTimeByTimezoneOffset("HH:MM", lid->gmt_offset);
+ std::string timezone_time = t.Format("HH:mm");
char time_formatted[MAX_STYLE_LEN] = { 0, };
snprintf(time_formatted, sizeof(time_formatted),
CUSTOM_LIST_TIME_STYLE("%s"), timezone_time.c_str());
elm_object_text_set(time, time_formatted);
- std::string meridiem = t.GetMeridiemByOffset(lid->gmt_offset);
+ std::string meridiem = t.Format("a");
char ampm_formatted[MAX_STYLE_LEN] = { 0, };
snprintf(ampm_formatted, sizeof(ampm_formatted),
CUSTOM_LIST_AMPM_STYLE("%s"), meridiem.c_str());
void WorldClockView::UpdateTimezoneTime(int timezone_offset)
{
- Time t;
+ Time t = Time::Now().InTimezone(Time::GetTimezoneNameByOffset(
+ timezone_offset).c_str());
- //TODO This must be formated according to global device settings
- std::string timezone_time = t.GetFormattedTimeByTimezoneOffset("HH:MM", timezone_offset);
+ std::string timezone_time = t.Format("HH:mm");
char time_formatted[MAX_STYLE_LEN] = { 0, };
snprintf(time_formatted, sizeof(time_formatted),
void WorldClockView::UpdateTimezoneXMeridiem(int timezone_offset)
{
- Time t;
+ Time t = Time::Now().InTimezone(Time::GetTimezoneNameByOffset(timezone_offset).c_str());
- //TODO This must be formated according to global device settings
- std::string meridiem = t.GetMeridiemByOffset(timezone_offset);
+ std::string meridiem = t.Format(Time::FORMAT_TIME_AMPM);
char ampm_formatted[MAX_STYLE_LEN] = { 0, };
snprintf(ampm_formatted, sizeof(ampm_formatted),
void WorldClockView::UpdateTimezoneRelativeToLocal(int timezone_offset)
{
- Time t;
+ int local_timezone_offset = Time::GetTimezoneOffset(Time::GetCurrentTimezone().c_str());
char relative_formatted[MAX_STYLE_LEN] = { 0, };
snprintf(relative_formatted, sizeof(relative_formatted),
TIMEZONE_DETAILS_FIRST_LINE_RELATIVE_TO_LOCAL_STYLE("%s"),
- t.GetTimezoneRelativeToLocalString(timezone_offset).c_str());
+ GetTimezoneDiffDescription(local_timezone_offset, timezone_offset).c_str());
elm_object_text_set(elm_table_child_get(timezone_details_, 4, 0), relative_formatted);
}