فهرست منبع

Merge branch 'system-time-2023' of public/ls-standard-library into development

patrick-christopher.mattulat 1 سال پیش
والد
کامیت
e8170b7d5d
58فایلهای تغییر یافته به همراه3108 افزوده شده و 47 حذف شده
  1. 160 33
      CMakeLists.txt
  2. 6 0
      README.md
  3. 3 1
      include/ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp
  4. 3 1
      include/ls-std/core/evaluator/NullPointerEvaluator.hpp
  5. 39 0
      include/ls-std/core/interface/IJniApi.hpp
  6. 42 0
      include/ls-std/core/jni/JniApi.hpp
  7. 57 0
      include/ls-std/core/jni/JniClass.hpp
  8. 43 0
      include/ls-std/core/jni/JniClassParameter.hpp
  9. 41 0
      include/ls-std/core/jni/JniMethod.hpp
  10. 55 0
      include/ls-std/core/jni/JniReturnValue.hpp
  11. 19 0
      include/ls-std/ls-std-core-jni.hpp
  12. 15 0
      include/ls-std/ls-std-time-jni.hpp
  13. 16 1
      include/ls-std/ls-std-time.hpp
  14. 53 0
      include/ls-std/time/common/DateParameter.hpp
  15. 38 0
      include/ls-std/time/common/DateParameterMapper.hpp
  16. 30 0
      include/ls-std/time/common/jni/JniDateParameterMapper.hpp
  17. 29 0
      include/ls-std/time/system-time/IClock.hpp
  18. 30 0
      include/ls-std/time/system-time/PosixClock.hpp
  19. 41 0
      include/ls-std/time/system-time/SystemTime.hpp
  20. 35 0
      include/ls-std/time/system-time/SystemTimeParameter.hpp
  21. 29 0
      include/ls-std/time/system-time/WindowsClock.hpp
  22. 21 0
      include/ls-std/time/system-time/jni/com_lynarstudios_ls_std_time_systemtime_SystemTimeJni.h
  23. 24 0
      include/ls-std/time/type/DateParameterTypes.hpp
  24. 23 3
      source/ls-std/core/evaluator/NullPointerArgumentEvaluator.cpp
  25. 19 1
      source/ls-std/core/evaluator/NullPointerEvaluator.cpp
  26. 16 0
      source/ls-std/core/interface/IJniApi.cpp
  27. 73 0
      source/ls-std/core/jni/JniApi.cpp
  28. 203 0
      source/ls-std/core/jni/JniClass.cpp
  29. 49 0
      source/ls-std/core/jni/JniClassParameter.cpp
  30. 55 0
      source/ls-std/core/jni/JniMethod.cpp
  31. 96 0
      source/ls-std/core/jni/JniReturnValue.cpp
  32. 90 0
      source/ls-std/time/common/DateParameter.cpp
  33. 56 0
      source/ls-std/time/common/DateParameterMapper.cpp
  34. 35 0
      source/ls-std/time/common/jni/JniDateParameterMapper.cpp
  35. 16 0
      source/ls-std/time/system-time/IClock.cpp
  36. 28 0
      source/ls-std/time/system-time/PosixClock.cpp
  37. 65 0
      source/ls-std/time/system-time/SystemTime.cpp
  38. 29 0
      source/ls-std/time/system-time/SystemTimeParameter.cpp
  39. 26 0
      source/ls-std/time/system-time/WindowsClock.cpp
  40. 69 0
      source/ls-std/time/system-time/jni/com_lynarstudios_ls_std_time_systemtime_SystemTimeJni.cpp
  41. 49 3
      test/cases/core/evaluator/NullPointerArgumentEvaluatorTest.cpp
  42. 49 3
      test/cases/core/evaluator/NullPointerEvaluatorTest.cpp
  43. 50 0
      test/cases/core/jni/JniApiTest.cpp
  44. 77 0
      test/cases/core/jni/JniClassParameterTest.cpp
  45. 369 0
      test/cases/core/jni/JniClassTest.cpp
  46. 114 0
      test/cases/core/jni/JniMethodTest.cpp
  47. 137 0
      test/cases/core/jni/JniReturnValueTest.cpp
  48. 0 1
      test/cases/io/evaluator/FileExistenceEvaluatorTest.cpp
  49. 91 0
      test/cases/time/common/DateParameterMapperTest.cpp
  50. 137 0
      test/cases/time/common/DateParameterTest.cpp
  51. 57 0
      test/cases/time/system-time/SystemTimeParameterTest.cpp
  52. 71 0
      test/cases/time/system-time/SystemTimeTest.cpp
  53. 16 0
      test/classes/core/jni/MockJniApi.cpp
  54. 38 0
      test/classes/core/jni/MockJniApi.hpp
  55. 16 0
      test/classes/time/system-time/MockClock.cpp
  56. 30 0
      test/classes/time/system-time/MockClock.hpp
  57. 15 0
      test/ls-std-core-jni-test.hpp
  58. 15 0
      test/ls-std-time-test.hpp

+ 160 - 33
CMakeLists.txt

@@ -32,6 +32,7 @@ option(LS_STD_BUILD_WITH_TESTS "Build project with tests..." OFF)
 option(LS_STD_BUILD_WITH_SUPPORTED_COMPILER "Build project with supported compiler only..." ON)
 option(LS_STD_BUILD_STATIC "Build ls-std static library..." ON)
 option(LS_STD_BUILD_SHARED "Build ls-std shared library..." OFF)
+option(LS_STD_BUILD_WITH_JNI "Build ls-std shared library with JNI..." OFF)
 
 set(TARGET_COUNTER 0)
 
@@ -57,6 +58,19 @@ if (TARGET_COUNTER EQUAL 0)
     return()
 endif ()
 
+##########################################################
+# JNI flag check
+##########################################################
+
+if (${LS_STD_BUILD_WITH_JNI})
+    if (${LS_STD_BUILD_SHARED})
+        message("${PROJECT_NAME}: build with JNI support...")
+    else ()
+        message("${PROJECT_NAME}: [Error] JNI support requires shared build goal!")
+        return()
+    endif ()
+endif ()
+
 ##########################################################
 # Compiler Settings
 ##########################################################
@@ -70,7 +84,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
 # Compiler Support
 ##########################################################
 
-if(${LS_STD_BUILD_WITH_SUPPORTED_COMPILER})
+if (${LS_STD_BUILD_WITH_SUPPORTED_COMPILER})
     message("${PROJECT_NAME}: build with compiler support...")
 
     # define supported compilers
@@ -80,11 +94,27 @@ if(${LS_STD_BUILD_WITH_SUPPORTED_COMPILER})
             ${CMAKE_CXX_COMPILER_ID} STREQUAL Clang OR
             ${CMAKE_CXX_COMPILER_ID} STREQUAL AppleClang)
         message("${PROJECT_NAME}: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION} is supported...")
-    else()
+    else ()
         message("${PROJECT_NAME}: [Error] ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION} is not supported... terminated!")
         return()
     endif ()
-endif()
+endif ()
+
+######################################################
+# Find Packages
+######################################################
+
+if (${LS_STD_BUILD_WITH_JNI})
+    if (DEFINED ENV{JAVA_HOME})
+        message("JAVA_HOME found in '$ENV{JAVA_HOME}' location...")
+    else ()
+        message("[Error] JAVA_HOME not found!")
+        return()
+    endif ()
+
+    message("${PROJECT_NAME}: finding JNI package in '$ENV{JAVA_HOME}'...")
+    find_package(JNI REQUIRED)
+endif ()
 
 ######################################################
 # Include Directories
@@ -92,6 +122,12 @@ endif()
 
 message("${PROJECT_NAME}: Adding include directories...")
 
+if (${LS_STD_BUILD_WITH_JNI})
+    include_directories(${JAVA_INCLUDE_PATH})
+    include_directories(${JAVA_INCLUDE_PATH2})
+    include_directories(${JAVA_AWT_INCLUDE_PATH})
+endif ()
+
 if (${LS_STD_BUILD_WITH_TESTS})
     include_directories(${CMAKE_CURRENT_SOURCE_DIR}/test)
     include_directories(${CMAKE_CURRENT_LIST_DIR}/test/lib/${GOOGLE_TEST_MODULE}/googletest/include)
@@ -158,6 +194,14 @@ set(SOURCE_FILES_CORE
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/LibraryVersion.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/Version.cpp)
 
+set(SOURCE_FILES_CORE_JNI
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/interface/IJniApi.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/jni/JniApi.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/jni/JniClass.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/jni/JniClassParameter.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/jni/JniMethod.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/core/jni/JniReturnValue.cpp)
+
 set(SOURCE_FILES_ENCODING
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/encoding/Base64.cpp)
 
@@ -219,8 +263,30 @@ set(SOURCE_FILES_IO
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/StorableFile.cpp)
 
 set(SOURCE_FILES_TIME
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/common/DateParameter.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/common/DateParameterMapper.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/system-time/IClock.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/system-time/SystemTime.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/system-time/SystemTimeParameter.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/Date.cpp)
 
+set(SOURCE_FILES_LINUX_TIME)
+set(SOURCE_FILES_WINDOWS_TIME)
+
+if (UNIX OR APPLE)
+    message("${MODULE_NAME_TIME}: Add UNIX files for time module...")
+    set(SOURCE_FILES_LINUX_TIME
+            ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/system-time/PosixClock.cpp)
+else (WIN32)
+    message("${MODULE_NAME_TIME}: Add Windows files for time module...")
+    set(SOURCE_FILES_WINDOWS_TIME
+            ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/system-time/WindowsClock.cpp)
+endif ()
+
+set(SOURCE_FILES_TIME_JNI
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/common/jni/JniDateParameterMapper.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/time/system-time/jni/com_lynarstudios_ls_std_time_systemtime_SystemTimeJni.cpp)
+
 ####################################################################################################################
 ####################################################################################################################
 ####################################################################################################################
@@ -261,6 +327,14 @@ if (${LS_STD_BUILD_WITH_TESTS})
             ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/core/ClassWrapper.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/core/MathOddValidator.cpp)
 
+    set(UNIT_TEST_FILES_CORE_JNI
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/jni/JniApiTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/jni/JniClassParameterTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/jni/JniClassTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/jni/JniMethodTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/core/jni/JniReturnValueTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/core/jni/MockJniApi.cpp)
+
     set(UNIT_TEST_FILES_ENCODING
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/encoding/Base64Test.cpp)
 
@@ -337,7 +411,12 @@ if (${LS_STD_BUILD_WITH_TESTS})
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/serialization/JsonTest.cpp)
 
     set(UNIT_TEST_FILES_TIME
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/time/DateTest.cpp)
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/time/common/DateParameterMapperTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/time/common/DateParameterTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/time/system-time/SystemTimeParameterTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/time/system-time/SystemTimeTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/time/DateTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/time/system-time/MockClock.cpp)
 endif ()
 
 ####################################################################################################################
@@ -362,8 +441,13 @@ endif ()
 ##########################################################
 
 if (${LS_STD_BUILD_WITH_TESTS})
-    message("${MODULE_NAME_CORE}: Building unit tests...")
-    add_executable(${MODULE_NAME_CORE}-unit-test ${UNIT_TEST_FILES_CORE})
+    if (${LS_STD_BUILD_WITH_JNI})
+        message("${MODULE_NAME_CORE}: Building unit tests with JNI support...")
+        add_executable(${MODULE_NAME_CORE}-unit-test ${UNIT_TEST_FILES_CORE} ${UNIT_TEST_FILES_CORE_JNI})
+    else ()
+        message("${MODULE_NAME_CORE}: Building unit tests...")
+        add_executable(${MODULE_NAME_CORE}-unit-test ${UNIT_TEST_FILES_CORE})
+    endif ()
 endif ()
 
 ##########################################################
@@ -409,16 +493,30 @@ endif ()
 ##########################################################
 
 if (${LS_STD_BUILD_WITH_TESTS})
-    message("${PROJECT_NAME}: Building unit tests...")
-    add_executable(${PROJECT_NAME}-unit-test
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/TestHelper.cpp
-            ${UNIT_TEST_FILES_BOXING}
-            ${UNIT_TEST_FILES_CORE}
-            ${UNIT_TEST_FILES_ENCODING}
-            ${UNIT_TEST_FILES_EVENT}
-            ${UNIT_TEST_FILES_IO}
-            ${UNIT_TEST_FILES_SERIALIZATION}
-            ${UNIT_TEST_FILES_TIME})
+    if (${LS_STD_BUILD_WITH_JNI})
+        message("${PROJECT_NAME}: Building unit tests with JNI support...")
+        add_executable(${PROJECT_NAME}-unit-test
+                ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/TestHelper.cpp
+                ${UNIT_TEST_FILES_BOXING}
+                ${UNIT_TEST_FILES_CORE}
+                ${UNIT_TEST_FILES_CORE_JNI}
+                ${UNIT_TEST_FILES_ENCODING}
+                ${UNIT_TEST_FILES_EVENT}
+                ${UNIT_TEST_FILES_IO}
+                ${UNIT_TEST_FILES_SERIALIZATION}
+                ${UNIT_TEST_FILES_TIME})
+    else ()
+        message("${PROJECT_NAME}: Building unit tests...")
+        add_executable(${PROJECT_NAME}-unit-test
+                ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/TestHelper.cpp
+                ${UNIT_TEST_FILES_BOXING}
+                ${UNIT_TEST_FILES_CORE}
+                ${UNIT_TEST_FILES_ENCODING}
+                ${UNIT_TEST_FILES_EVENT}
+                ${UNIT_TEST_FILES_IO}
+                ${UNIT_TEST_FILES_SERIALIZATION}
+                ${UNIT_TEST_FILES_TIME})
+    endif ()
 endif ()
 
 ####################################################################################################################
@@ -462,17 +560,32 @@ endif ()
 ####################################################################################################################
 
 if (${LS_STD_BUILD_WITH_TESTS})
-    message("${PROJECT_NAME}: Building all tests...")
-    add_executable(${PROJECT_NAME}-test
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/TestHelper.cpp
-            ${UNIT_TEST_FILES_BOXING}
-            ${UNIT_TEST_FILES_CORE}
-            ${UNIT_TEST_FILES_ENCODING}
-            ${UNIT_TEST_FILES_EVENT}
-            ${UNIT_TEST_FILES_IO}
-            ${INTEGRATION_TEST_FILES_IO}
-            ${UNIT_TEST_FILES_SERIALIZATION}
-            ${UNIT_TEST_FILES_TIME})
+    if (${LS_STD_BUILD_WITH_JNI})
+        message("${PROJECT_NAME}: Building all tests...")
+        add_executable(${PROJECT_NAME}-test
+                ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/TestHelper.cpp
+                ${UNIT_TEST_FILES_BOXING}
+                ${UNIT_TEST_FILES_CORE}
+                ${UNIT_TEST_FILES_CORE_JNI}
+                ${UNIT_TEST_FILES_ENCODING}
+                ${UNIT_TEST_FILES_EVENT}
+                ${UNIT_TEST_FILES_IO}
+                ${INTEGRATION_TEST_FILES_IO}
+                ${UNIT_TEST_FILES_SERIALIZATION}
+                ${UNIT_TEST_FILES_TIME})
+    else ()
+        message("${PROJECT_NAME}: Building all tests with JNI support...")
+        add_executable(${PROJECT_NAME}-test
+                ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/TestHelper.cpp
+                ${UNIT_TEST_FILES_BOXING}
+                ${UNIT_TEST_FILES_CORE}
+                ${UNIT_TEST_FILES_ENCODING}
+                ${UNIT_TEST_FILES_EVENT}
+                ${UNIT_TEST_FILES_IO}
+                ${INTEGRATION_TEST_FILES_IO}
+                ${UNIT_TEST_FILES_SERIALIZATION}
+                ${UNIT_TEST_FILES_TIME})
+    endif ()
 endif ()
 
 ####################################################################################################################
@@ -512,8 +625,14 @@ if (${LS_STD_BUILD_STATIC})
 endif ()
 
 if (${LS_STD_BUILD_SHARED})
-    add_library("${MODULE_NAME_CORE}" SHARED ${SOURCE_FILES_CORE})
-    set_target_properties("${MODULE_NAME_CORE}" PROPERTIES DEBUG_POSTFIX "-d")
+    if (${LS_STD_BUILD_WITH_JNI})
+        message("${MODULE_NAME_CORE}: building with JNI...")
+        add_library("${MODULE_NAME_CORE}" SHARED ${SOURCE_FILES_CORE} ${SOURCE_FILES_CORE_JNI})
+        set_target_properties("${MODULE_NAME_CORE}" PROPERTIES DEBUG_POSTFIX "-d")
+    else ()
+        add_library("${MODULE_NAME_CORE}" SHARED ${SOURCE_FILES_CORE})
+        set_target_properties("${MODULE_NAME_CORE}" PROPERTIES DEBUG_POSTFIX "-d")
+    endif ()
 endif ()
 
 ##########################################################
@@ -579,14 +698,21 @@ endif ()
 message("${PROJECT_NAME}: Building ${MODULE_NAME_TIME} library version ${PROJECT_VERSION}...")
 
 if (${LS_STD_BUILD_STATIC})
-    add_library("${MODULE_NAME_TIME}" STATIC ${SOURCE_FILES_TIME})
+    add_library("${MODULE_NAME_TIME}" STATIC ${SOURCE_FILES_TIME} ${SOURCE_FILES_LINUX_TIME} ${SOURCE_FILES_WINDOWS_TIME})
     set_target_properties("${MODULE_NAME_TIME}" PROPERTIES DEBUG_POSTFIX "-d")
 endif ()
 
 if (${LS_STD_BUILD_SHARED})
-    add_library("${MODULE_NAME_TIME}" SHARED ${SOURCE_FILES_TIME})
-    target_link_libraries("${MODULE_NAME_TIME}" ${MODULE_NAME_CORE})
-    set_target_properties("${MODULE_NAME_TIME}" PROPERTIES DEBUG_POSTFIX "-d")
+    if (${LS_STD_BUILD_WITH_JNI})
+        message("${MODULE_NAME_TIME}: building with JNI...")
+        add_library("${MODULE_NAME_TIME}" SHARED ${SOURCE_FILES_TIME} ${SOURCE_FILES_LINUX_TIME} ${SOURCE_FILES_WINDOWS_TIME} ${SOURCE_FILES_TIME_JNI})
+        target_link_libraries("${MODULE_NAME_TIME}" ${MODULE_NAME_CORE})
+        set_target_properties("${MODULE_NAME_TIME}" PROPERTIES DEBUG_POSTFIX "-d")
+    else ()
+        add_library("${MODULE_NAME_TIME}" SHARED ${SOURCE_FILES_TIME} ${SOURCE_FILES_LINUX_TIME} ${SOURCE_FILES_WINDOWS_TIME})
+        target_link_libraries("${MODULE_NAME_TIME}" ${MODULE_NAME_CORE})
+        set_target_properties("${MODULE_NAME_TIME}" PROPERTIES DEBUG_POSTFIX "-d")
+    endif ()
 endif ()
 
 ####################################################################################################################
@@ -671,6 +797,7 @@ if (${LS_STD_BUILD_WITH_TESTS})
     message("${MODULE_NAME_TIME}: Linking libraries for unit test application...")
     target_link_libraries(${MODULE_NAME_TIME}-unit-test
             gtest
+            gmock
             gtest_main
             "${MODULE_NAME_TIME}"
             "${MODULE_NAME_CORE}")

+ 6 - 0
README.md

@@ -35,12 +35,17 @@ A __Date__ class comes with this submodule, which you can use to represent a dat
 #### Features ####
 
 - added NotImplementedException class, which can be thrown in case a method is provided, but not implemented
+- a JNI class is now available, wrapping C-like JNI functionalities, which can be found in __ls-std-core__ module - in
+  order to use this feature the CMake option __LS_STD_BUILD_WITH_JNI__ has to be enabled - please note, that this
+  feature is experimental and incomplete
+- a SystemTime class has been added to the library's time module for setting the local system time
 
 #### Improvements ####
 
 - made test constructors public and reduced test setup overhead
 - added missing __nodiscard__ attributes to test package
 - made __Exception__ base class abstract, which prevents it from being instantiated
+- __NullPointerEvaluator__ & __NullPointerArgumentEvaluator__ now except raw pointers
 
 #### Fixes ####
 
@@ -109,6 +114,7 @@ Alternatively, the CMake project generation can be controlled by providing libra
 | __LS_STD_BUILD_WITH_SUPPORTED_COMPILER__ | ON            | This flag enforces the usage of supported compilers, only.<br/>For usage of an unsupported toolchain, set this flag to __OFF__.                      |
 | __LS_STD_BUILD_STATIC__                  | ON            | This flag indicates, that all library modules should be built as static goals.  <br/>Please note, that __LS_STD_BUILD_SHARED__ has to be turned off. |
 | __LS_STD_BUILD_SHARED__                  | OFF           | This flag indicates, that all library modules should be built as shared goals.  <br/>Please note, that __LS_STD_BUILD_STATIC__ has to be turned off. |
+| __LS_STD_BUILD_WITH_JNI__                | OFF           | This flag enables the build of JNI dependencies.  <br/>Please note, that __LS_STD_BUILD_SHARED__ has to be turned on.                                |
 
 To use one or more of these flags, you'd have to adjust previous command, like:
 

+ 3 - 1
include/ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-08
-* Changed:         2023-02-22
+* Changed:         2023-04-07
 *
 * */
 
@@ -21,6 +21,8 @@ namespace ls::std::core
   {
     public:
 
+      explicit NullPointerArgumentEvaluator(const void *_rawArgument);
+      explicit NullPointerArgumentEvaluator(const void *_rawArgument, ::std::string _message);
       explicit NullPointerArgumentEvaluator(const ::std::shared_ptr<void> &_argument);
       explicit NullPointerArgumentEvaluator(const ::std::shared_ptr<void> &_argument, ::std::string _message);
       ~NullPointerArgumentEvaluator() noexcept override;

+ 3 - 1
include/ls-std/core/evaluator/NullPointerEvaluator.hpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-08
-* Changed:         2023-02-22
+* Changed:         2023-04-04
 *
 * */
 
@@ -21,6 +21,8 @@ namespace ls::std::core
   {
     public:
 
+      explicit NullPointerEvaluator(const void *_rawArgument);
+      explicit NullPointerEvaluator(const void *_rawArgument, ::std::string _message);
       explicit NullPointerEvaluator(const ::std::shared_ptr<void> &_argument);
       explicit NullPointerEvaluator(const ::std::shared_ptr<void> &_argument, ::std::string _message);
       ~NullPointerEvaluator() noexcept override;

+ 39 - 0
include/ls-std/core/interface/IJniApi.hpp

@@ -0,0 +1,39 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-11
+*
+* */
+
+#ifndef LS_STD_I_JNI_API_HPP
+#define LS_STD_I_JNI_API_HPP
+
+#include <jni.h>
+#include <ls-std/os/dynamic-goal.hpp>
+#include <string>
+
+namespace ls::std::core::experimental::interface_type
+{
+  class LS_STD_DYNAMIC_GOAL IJniApi
+  {
+    public:
+
+      IJniApi();
+      virtual ~IJniApi();
+
+      virtual jboolean callBooleanMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jbyte callByteMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jchar callCharMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jdouble callDoubleMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jfloat callFloatMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jint callIntMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jlong callLongMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jshort callShortMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jclass findClass(const ::std::string &_classPath) = 0;
+      virtual jmethodID getMethodId(jclass _javaClass, const char *_methodIdentifier, const char *_methodSignature) = 0;
+  };
+}
+
+#endif

+ 42 - 0
include/ls-std/core/jni/JniApi.hpp

@@ -0,0 +1,42 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-11
+*
+* */
+
+#ifndef LS_STD_JNI_API_HPP
+#define LS_STD_JNI_API_HPP
+
+#include <ls-std/core/interface/IJniApi.hpp>
+#include <ls-std/os/dynamic-goal.hpp>
+
+namespace ls::std::core::experimental
+{
+  class LS_STD_DYNAMIC_GOAL JniApi : public ls::std::core::experimental::interface_type::IJniApi
+  {
+    public:
+
+      explicit JniApi(JNIEnv *_environment);
+      ~JniApi() noexcept override;
+
+      jboolean callBooleanMethod(jobject _javaObject, jmethodID _methodId) override;
+      jbyte callByteMethod(jobject _javaObject, jmethodID _methodId) override;
+      jchar callCharMethod(jobject _javaObject, jmethodID _methodId) override;
+      jdouble callDoubleMethod(jobject _javaObject, jmethodID _methodId) override;
+      jfloat callFloatMethod(jobject _javaObject, jmethodID _methodId) override;
+      jint callIntMethod(jobject _javaObject, jmethodID _methodId) override;
+      jlong callLongMethod(jobject _javaObject, jmethodID _methodId) override;
+      jshort callShortMethod(jobject _javaObject, jmethodID _methodId) override;
+      jclass findClass(const ::std::string &_classPath) override;
+      jmethodID getMethodId(jclass _javaClass, const char *_methodIdentifier, const char *_methodSignature) override;
+
+    private:
+
+      JNIEnv *environment{};
+  };
+}
+
+#endif

+ 57 - 0
include/ls-std/core/jni/JniClass.hpp

@@ -0,0 +1,57 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-11
+*
+* */
+
+#ifndef LS_STD_JNI_CLASS_HPP
+#define LS_STD_JNI_CLASS_HPP
+
+#include "JniClassParameter.hpp"
+#include "JniMethod.hpp"
+#include "JniReturnValue.hpp"
+#include <jni.h>
+#include <ls-std/core/interface/IJniApi.hpp>
+#include <ls-std/os/dynamic-goal.hpp>
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+namespace ls::std::core::experimental
+{
+  class LS_STD_DYNAMIC_GOAL JniClass
+  {
+    public:
+
+      explicit JniClass(const ::std::shared_ptr<ls::std::core::experimental::JniClassParameter> &_parameter, const ::std::string &_path);
+      virtual ~JniClass();
+
+      [[nodiscard]] ls::std::core::experimental::JniReturnValue callMethod(const ::std::string &_methodIdentifier);
+      [[nodiscard]] bool hasMethod(const ::std::string &_methodIdentifier);
+      bool load();                                                                                    // nodiscard is optional here
+      bool loadMethod(const ::std::string &_methodIdentifier, const ::std::string &_methodSignature); // nodiscard is optional here
+
+    private:
+
+      jclass javaClass{};
+      ::std::unordered_map<::std::string, ls::std::core::experimental::JniMethod> methods{};
+      ::std::shared_ptr<ls::std::core::experimental::JniClassParameter> parameter{};
+      ::std::string path{};
+
+      void _callBooleanMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _callByteMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _callCharMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _callDoubleMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _callFloatMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _callIntMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _callLongMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _callShortMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _createJniApi();
+      [[nodiscard]] bool _hasMethod(const ::std::string &_methodIdentifier);
+  };
+}
+
+#endif

+ 43 - 0
include/ls-std/core/jni/JniClassParameter.hpp

@@ -0,0 +1,43 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-10
+*
+* */
+
+#ifndef LS_STD_JNI_CLASS_PARAMETER_HPP
+#define LS_STD_JNI_CLASS_PARAMETER_HPP
+
+#include <jni.h>
+#include <ls-std/core/interface/IJniApi.hpp>
+#include <ls-std/os/dynamic-goal.hpp>
+#include <memory>
+#include <string>
+
+namespace ls::std::core::experimental
+{
+  class LS_STD_DYNAMIC_GOAL JniClassParameter
+  {
+    public:
+
+      JniClassParameter();
+      ~JniClassParameter();
+
+      [[nodiscard]] JNIEnv *getJavaEnvironment();
+      [[nodiscard]] jobject getJavaObject();
+      [[nodiscard]] ::std::shared_ptr<ls::std::core::experimental::interface_type::IJniApi> getJniApi();
+      void setJavaEnvironment(JNIEnv *_environment);
+      void setJavaObject(jobject _javaObject);
+      void setJniApi(const ::std::shared_ptr<ls::std::core::experimental::interface_type::IJniApi> &_jniApi);
+
+    private:
+
+      JNIEnv *environment{};
+      jobject javaObject{};
+      ::std::shared_ptr<ls::std::core::experimental::interface_type::IJniApi> jniApi{};
+  };
+}
+
+#endif

+ 41 - 0
include/ls-std/core/jni/JniMethod.hpp

@@ -0,0 +1,41 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-08
+* Changed:         2023-04-10
+*
+* */
+
+#ifndef LS_STD_JNI_METHOD_HPP
+#define LS_STD_JNI_METHOD_HPP
+
+#include <jni.h>
+#include <ls-std/os/dynamic-goal.hpp>
+#include <string>
+
+namespace ls::std::core::experimental
+{
+  class LS_STD_DYNAMIC_GOAL JniMethod
+  {
+    public:
+
+      explicit JniMethod(const ::std::string &_methodIdentifier, const ::std::string &_methodSignature);
+      ~JniMethod();
+
+      [[nodiscard]] jmethodID getMethodId();
+      [[nodiscard]] ::std::string getMethodIdentifier();
+      [[nodiscard]] ::std::string getMethodSignature();
+      void setMethodId(jmethodID _methodId);
+      void setMethodIdentifier(const ::std::string &_methodIdentifier);
+      void setMethodSignature(const ::std::string &_methodSignature);
+
+    private:
+
+      jmethodID methodId{};
+      ::std::string methodIdentifier{};
+      ::std::string methodSignature{};
+  };
+}
+
+#endif

+ 55 - 0
include/ls-std/core/jni/JniReturnValue.hpp

@@ -0,0 +1,55 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-08
+* Changed:         2023-04-11
+*
+* */
+
+#ifndef LS_STD_JNI_RETURN_VALUE_HPP
+#define LS_STD_JNI_RETURN_VALUE_HPP
+
+#include <jni.h>
+#include <ls-std/os/dynamic-goal.hpp>
+
+namespace ls::std::core::experimental
+{
+  class LS_STD_DYNAMIC_GOAL JniReturnValue
+  {
+    public:
+
+      JniReturnValue();
+      ~JniReturnValue();
+
+      [[nodiscard]] jboolean getBooleanValue() const;
+      [[nodiscard]] jbyte getByteValue() const;
+      [[nodiscard]] jchar getCharValue() const;
+      [[nodiscard]] jdouble getDoubleValue() const;
+      [[nodiscard]] jfloat getFloatValue() const;
+      [[nodiscard]] jint getIntegerValue() const;
+      [[nodiscard]] jlong getLongValue() const;
+      [[nodiscard]] jshort getShortValue() const;
+      void setBooleanValue(jboolean _booleanValue);
+      void setByteValue(jbyte _byteValue);
+      void setCharValue(jchar _charValue);
+      void setDoubleValue(jdouble _doubleValue);
+      void setFloatValue(jfloat _floatValue);
+      void setIntegerValue(jint _integerValue);
+      void setLongValue(jlong _longValue);
+      void setShortValue(jshort _shortValue);
+
+    private:
+
+      jboolean booleanValue{};
+      jbyte byteValue{};
+      jchar charValue{};
+      jdouble doubleValue{};
+      jfloat floatValue{};
+      jint integerValue{};
+      jlong longValue{};
+      jshort shortValue{};
+  };
+}
+
+#endif

+ 19 - 0
include/ls-std/ls-std-core-jni.hpp

@@ -0,0 +1,19 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-08
+*
+* */
+
+#ifndef LS_STD_LS_STD_CORE_JNI_HPP
+#define LS_STD_LS_STD_CORE_JNI_HPP
+
+#include <ls-std/core/jni/JniApi.hpp>
+#include <ls-std/core/jni/JniClass.hpp>
+#include <ls-std/core/jni/JniClassParameter.hpp>
+#include <ls-std/core/jni/JniMethod.hpp>
+#include <ls-std/core/jni/JniReturnValue.hpp>
+
+#endif

+ 15 - 0
include/ls-std/ls-std-time-jni.hpp

@@ -0,0 +1,15 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-09
+* Changed:         2023-04-08
+*
+* */
+
+#ifndef LS_STD_LS_STD_TIME_JNI_HPP
+#define LS_STD_LS_STD_TIME_JNI_HPP
+
+#include <ls-std/time/common/jni/JniDateParameterMapper.hpp>
+
+#endif

+ 16 - 1
include/ls-std/ls-std-time.hpp

@@ -3,13 +3,28 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2022-05-16
- * Changed:         2023-02-03
+ * Changed:         2023-04-01
  *
  * */
 
 #ifndef LS_STD_LS_STD_TIME_HPP
 #define LS_STD_LS_STD_TIME_HPP
 
+#include <ls-std/time/common/DateParameter.hpp>
+#include <ls-std/time/common/DateParameterMapper.hpp>
+
+#include <ls-std/time/system-time/IClock.hpp>
+#if defined(unix) || defined(__APPLE__)
+  #include <ls-std/time/system-time/PosixClock.hpp>
+#endif
+#include <ls-std/time/system-time/SystemTime.hpp>
+#include <ls-std/time/system-time/SystemTimeParameter.hpp>
+#ifdef _WIN32
+  #include <ls-std/time/system-time/WindowsClock.hpp>
+#endif
+
+#include <ls-std/time/type/DateParameterTypes.hpp>
+
 #include <ls-std/time/Date.hpp>
 
 #endif

+ 53 - 0
include/ls-std/time/common/DateParameter.hpp

@@ -0,0 +1,53 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-29
+* Changed:         2023-03-31
+*
+* */
+
+#ifndef LS_STD_DATE_PARAMETER_HPP
+#define LS_STD_DATE_PARAMETER_HPP
+
+#include <cstdint>
+#include <ls-std/os/dynamic-goal.hpp>
+#include <ls-std/time/type/DateParameterTypes.hpp>
+
+namespace ls::std::time
+{
+  class LS_STD_DYNAMIC_GOAL DateParameter
+  {
+    public:
+
+      DateParameter(ls::std::time::type::Year _year, ls::std::time::type::Month _month, ls::std::time::type::Day _day, ls::std::time::type::Hour _hour, ls::std::time::type::Minute _minute, ls::std::time::type::Second _second);
+      DateParameter();
+      ~DateParameter();
+
+      bool operator==(const ls::std::time::DateParameter &_dateParameter) const;
+
+      [[nodiscard]] ls::std::time::type::Day getDay() const;
+      [[nodiscard]] ls::std::time::type::Hour getHour() const;
+      [[nodiscard]] ls::std::time::type::Minute getMinute() const;
+      [[nodiscard]] ls::std::time::type::Month getMonth() const;
+      [[nodiscard]] ls::std::time::type::Second getSecond() const;
+      [[nodiscard]] ls::std::time::type::Year getYear() const;
+      void setDay(ls::std::time::type::Day _day);
+      void setHour(ls::std::time::type::Hour _hour);
+      void setMinute(ls::std::time::type::Minute _minute);
+      void setMonth(ls::std::time::type::Month _month);
+      void setSecond(ls::std::time::type::Second _second);
+      void setYear(ls::std::time::type::Year _year);
+
+    private:
+
+      ls::std::time::type::Day day{};
+      ls::std::time::type::Hour hour{};
+      ls::std::time::type::Minute minute{};
+      ls::std::time::type::Month month{};
+      ls::std::time::type::Second second{};
+      ls::std::time::type::Year year{};
+  };
+}
+
+#endif

+ 38 - 0
include/ls-std/time/common/DateParameterMapper.hpp

@@ -0,0 +1,38 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-31
+* Changed:         2023-04-01
+*
+* */
+
+#ifndef LS_STD_DATE_PARAMETER_MAPPER_HPP
+#define LS_STD_DATE_PARAMETER_MAPPER_HPP
+
+#include "DateParameter.hpp"
+#include <ls-std/os/dynamic-goal.hpp>
+#include <ls-std/time/type/DateParameterTypes.hpp>
+#ifdef _WIN32
+  #include <windows.h>
+#endif
+
+namespace ls::std::time
+{
+  class LS_STD_DYNAMIC_GOAL DateParameterMapper
+  {
+    public:
+
+      DateParameterMapper();
+      ~DateParameterMapper();
+
+#if defined(unix) || defined(__APPLE__)
+      [[nodiscard]] static ls::std::time::type::UnixTimestamp toUnixTimestamp(const ls::std::time::DateParameter &_dateParameter);
+#endif
+#ifdef _WIN32
+      [[nodiscard]] static SYSTEMTIME toWindowsSystemTime(const ls::std::time::DateParameter &_dateParameter);
+#endif
+  };
+}
+
+#endif

+ 30 - 0
include/ls-std/time/common/jni/JniDateParameterMapper.hpp

@@ -0,0 +1,30 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-09
+* Changed:         2023-04-10
+*
+* */
+
+#ifndef LS_STD_JNI_DATE_PARAMETER_MAPPER_HPP
+#define LS_STD_JNI_DATE_PARAMETER_MAPPER_HPP
+
+#include <ls-std/core/jni/JniClass.hpp>
+#include <ls-std/os/dynamic-goal.hpp>
+#include <ls-std/time/common/DateParameter.hpp>
+
+namespace ls::std::time::experimental
+{
+  class LS_STD_DYNAMIC_GOAL JniDateParameterMapper
+  {
+    public:
+
+      JniDateParameterMapper();
+      ~JniDateParameterMapper();
+
+      [[nodiscard]] static ls::std::time::DateParameter toDateParameter(const ls::std::core::experimental::JniClass &_javaClass);
+  };
+}
+
+#endif

+ 29 - 0
include/ls-std/time/system-time/IClock.hpp

@@ -0,0 +1,29 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-31
+* Changed:         2023-03-31
+*
+* */
+
+#ifndef LS_STD_I_CLOCK_HPP
+#define LS_STD_I_CLOCK_HPP
+
+#include <ls-std/os/dynamic-goal.hpp>
+#include <ls-std/time/common/DateParameter.hpp>
+
+namespace ls::std::time
+{
+  class LS_STD_DYNAMIC_GOAL IClock
+  {
+    public:
+
+      IClock();
+      virtual ~IClock();
+
+      virtual bool setTime(const ls::std::time::DateParameter &_dateParameter) = 0;
+  };
+}
+
+#endif

+ 30 - 0
include/ls-std/time/system-time/PosixClock.hpp

@@ -0,0 +1,30 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-15
+* Changed:         2023-04-01
+*
+* */
+
+#ifndef LS_STD_POSIX_CLOCK_HPP
+#define LS_STD_POSIX_CLOCK_HPP
+
+#include "IClock.hpp"
+#include <cstdint>
+#include <ls-std/time/type/DateParameterTypes.hpp>
+
+namespace ls::std::time
+{
+  class PosixClock : public ls::std::time::IClock
+  {
+    public:
+
+      PosixClock();
+      ~PosixClock() noexcept override;
+
+      [[nodiscard]] bool setTime(const ls::std::time::DateParameter &_dateParameter) override;
+  };
+}
+
+#endif

+ 41 - 0
include/ls-std/time/system-time/SystemTime.hpp

@@ -0,0 +1,41 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-07
+* Changed:         2023-03-31
+*
+* */
+
+#ifndef LS_STD_SYSTEM_TIME_HPP
+#define LS_STD_SYSTEM_TIME_HPP
+
+#include "SystemTimeParameter.hpp"
+#include <cstdint>
+#include <ls-std/core/Class.hpp>
+#include <ls-std/os/dynamic-goal.hpp>
+#include <ls-std/time/common/DateParameter.hpp>
+#include <ls-std/time/type/DateParameterTypes.hpp>
+#include <memory>
+
+namespace ls::std::time
+{
+  class LS_STD_DYNAMIC_GOAL SystemTime : public ls::std::core::Class
+  {
+    public:
+
+      explicit SystemTime(const ::std::shared_ptr<ls::std::time::SystemTimeParameter> &_parameter);
+      SystemTime();
+      ~SystemTime() noexcept override;
+
+      [[nodiscard]] bool set(const ls::std::time::DateParameter &_dateParameter);
+
+    private:
+
+      ::std::shared_ptr<ls::std::time::SystemTimeParameter> parameter{};
+
+      void _generateParameter();
+  };
+}
+
+#endif

+ 35 - 0
include/ls-std/time/system-time/SystemTimeParameter.hpp

@@ -0,0 +1,35 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-15
+* Changed:         2023-03-31
+*
+* */
+
+#ifndef LS_STD_SYSTEM_TIME_PARAMETER_HPP
+#define LS_STD_SYSTEM_TIME_PARAMETER_HPP
+
+#include "IClock.hpp"
+#include <ls-std/os/dynamic-goal.hpp>
+#include <memory>
+
+namespace ls::std::time
+{
+  class LS_STD_DYNAMIC_GOAL SystemTimeParameter
+  {
+    public:
+
+      SystemTimeParameter();
+      ~SystemTimeParameter();
+
+      [[nodiscard]] ::std::shared_ptr<ls::std::time::IClock> getClock();
+      void setClock(const ::std::shared_ptr<ls::std::time::IClock> &_clock);
+
+    private:
+
+      ::std::shared_ptr<ls::std::time::IClock> clock{};
+  };
+}
+
+#endif

+ 29 - 0
include/ls-std/time/system-time/WindowsClock.hpp

@@ -0,0 +1,29 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-01
+* Changed:         2023-04-01
+*
+* */
+
+#ifndef LS_STD_WINDOW_CLOCK_HPP
+#define LS_STD_WINDOW_CLOCK_HPP
+
+#include "IClock.hpp"
+#include <ls-std/os/dynamic-goal.hpp>
+
+namespace ls::std::time
+{
+  class LS_STD_DYNAMIC_GOAL WindowsClock : public ls::std::time::IClock
+  {
+    public:
+
+      WindowsClock();
+      ~WindowsClock() noexcept override;
+
+      [[nodiscard]] bool setTime(const ls::std::time::DateParameter &_dateParameter) override;
+  };
+}
+
+#endif

+ 21 - 0
include/ls-std/time/system-time/jni/com_lynarstudios_ls_std_time_systemtime_SystemTimeJni.h

@@ -0,0 +1,21 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_lynarstudios_ls_std_time_systemtime_SystemTimeJni */
+
+#ifndef _Included_com_lynarstudios_ls_std_time_systemtime_SystemTimeJni
+#define _Included_com_lynarstudios_ls_std_time_systemtime_SystemTimeJni
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     com_lynarstudios_ls_std_time_systemtime_SystemTimeJni
+ * Method:    set
+ * Signature: (Lcom/lynarstudios/ls/std/time/systemtime/DateParameter;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_lynarstudios_ls_std_time_systemtime_SystemTimeJni_set
+  (JNIEnv *, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif

+ 24 - 0
include/ls-std/time/type/DateParameterTypes.hpp

@@ -0,0 +1,24 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-29
+* Changed:         2023-03-31
+*
+* */
+
+#ifndef LS_STD_DATE_PARAMETER_TYPES_HPP
+#define LS_STD_DATE_PARAMETER_TYPES_HPP
+
+namespace ls::std::time::type
+{
+  using Day = uint8_t;
+  using Hour = uint8_t;
+  using Minute = uint8_t;
+  using Month = uint8_t;
+  using Second = uint8_t;
+  using UnixTimestamp = uint32_t;
+  using Year = int;
+}
+
+#endif

+ 23 - 3
source/ls-std/core/evaluator/NullPointerArgumentEvaluator.cpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-08
-* Changed:         2023-02-23
+* Changed:         2023-04-07
 *
 * */
 
@@ -12,15 +12,35 @@
 
 using ls::std::core::IllegalArgumentException;
 using ls::std::core::NullPointerArgumentEvaluator;
+using std::make_shared;
 using std::move;
 using std::shared_ptr;
 using std::string;
 
+NullPointerArgumentEvaluator::NullPointerArgumentEvaluator(const void *_rawArgument)
+{
+  shared_ptr<void> value{};
+
+  if (_rawArgument != nullptr)
+  {
+    value = make_shared<int>();
+  }
+
+  this->argument = value;
+}
+
+NullPointerArgumentEvaluator::NullPointerArgumentEvaluator(const void *_rawArgument, string _message) : NullPointerArgumentEvaluator(_rawArgument)
+{
+  this->message = ::move(_message);
+}
+
 NullPointerArgumentEvaluator::NullPointerArgumentEvaluator(const shared_ptr<void> &_argument) : argument(_argument)
 {}
 
-NullPointerArgumentEvaluator::NullPointerArgumentEvaluator(const shared_ptr<void> &_argument, string _message) : argument(_argument), message(::move(_message))
-{}
+NullPointerArgumentEvaluator::NullPointerArgumentEvaluator(const shared_ptr<void> &_argument, string _message) : NullPointerArgumentEvaluator(_argument)
+{
+  this->message = ::move(_message);
+}
 
 NullPointerArgumentEvaluator::~NullPointerArgumentEvaluator() noexcept = default;
 

+ 19 - 1
source/ls-std/core/evaluator/NullPointerEvaluator.cpp

@@ -3,7 +3,7 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-08
-* Changed:         2023-02-23
+* Changed:         2023-04-04
 *
 * */
 
@@ -12,10 +12,28 @@
 
 using ls::std::core::NullPointerEvaluator;
 using ls::std::core::NullPointerException;
+using std::make_shared;
 using std::move;
 using std::shared_ptr;
 using std::string;
 
+NullPointerEvaluator::NullPointerEvaluator(const void *_rawArgument)
+{
+  shared_ptr<void> value{};
+
+  if (_rawArgument != nullptr)
+  {
+    value = make_shared<int>();
+  }
+
+  this->argument = value;
+}
+
+NullPointerEvaluator::NullPointerEvaluator(const void *_rawArgument, string _message) : NullPointerEvaluator(_rawArgument)
+{
+  this->message = ::move(_message);
+}
+
 NullPointerEvaluator::NullPointerEvaluator(const shared_ptr<void> &_argument) : argument(_argument)
 {}
 

+ 16 - 0
source/ls-std/core/interface/IJniApi.cpp

@@ -0,0 +1,16 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-10
+*
+* */
+
+#include <ls-std/core/interface/IJniApi.hpp>
+
+using ls::std::core::experimental::interface_type::IJniApi;
+
+IJniApi::IJniApi() = default;
+
+IJniApi::~IJniApi() = default;

+ 73 - 0
source/ls-std/core/jni/JniApi.cpp

@@ -0,0 +1,73 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-11
+*
+* */
+
+#include <ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp>
+#include <ls-std/core/jni/JniApi.hpp>
+
+using ls::std::core::NullPointerArgumentEvaluator;
+using ls::std::core::experimental::JniApi;
+using std::string;
+
+JniApi::JniApi(JNIEnv *_environment)
+{
+  NullPointerArgumentEvaluator{_environment, "Java environment is not being provided!"}.evaluate();
+  this->environment = _environment;
+}
+
+JniApi::~JniApi() noexcept = default;
+
+jboolean JniApi::callBooleanMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallBooleanMethod(_javaObject, _methodId);
+}
+
+jbyte JniApi::callByteMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallByteMethod(_javaObject, _methodId);
+}
+
+jchar JniApi::callCharMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallCharMethod(_javaObject, _methodId);
+}
+
+jdouble JniApi::callDoubleMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallDoubleMethod(_javaObject, _methodId);
+}
+
+jfloat JniApi::callFloatMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallFloatMethod(_javaObject, _methodId);
+}
+
+jint JniApi::callIntMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallIntMethod(_javaObject, _methodId);
+}
+
+jlong JniApi::callLongMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallLongMethod(_javaObject, _methodId);
+}
+
+jshort JniApi::callShortMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallShortMethod(_javaObject, _methodId);
+}
+
+jclass JniApi::findClass(const string &_classPath)
+{
+  return this->environment->FindClass(_classPath.c_str());
+}
+
+jmethodID JniApi::getMethodId(jclass _javaClass, const char *_methodIdentifier, const char *_methodSignature)
+{
+  return this->environment->GetMethodID(_javaClass, _methodIdentifier, _methodSignature);
+}

+ 203 - 0
source/ls-std/core/jni/JniClass.cpp

@@ -0,0 +1,203 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-11
+*
+* */
+
+#include <ls-std/core/ConditionalFunctionExecutor.hpp>
+#include <ls-std/core/evaluator/EmptyStringArgumentEvaluator.hpp>
+#include <ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp>
+#include <ls-std/core/evaluator/NullPointerEvaluator.hpp>
+#include <ls-std/core/jni/JniApi.hpp>
+#include <ls-std/core/jni/JniClass.hpp>
+#include <memory>
+
+using ls::std::core::ConditionalFunctionExecutor;
+using ls::std::core::EmptyStringArgumentEvaluator;
+using ls::std::core::NullPointerArgumentEvaluator;
+using ls::std::core::NullPointerEvaluator;
+using ls::std::core::experimental::JniApi;
+using ls::std::core::experimental::JniClass;
+using ls::std::core::experimental::JniClassParameter;
+using ls::std::core::experimental::JniMethod;
+using ls::std::core::experimental::JniReturnValue;
+using std::make_pair;
+using std::make_shared;
+using std::pair;
+using std::shared_ptr;
+using std::string;
+
+JniClass::JniClass(const shared_ptr<JniClassParameter> &_parameter, const string &_path)
+{
+  NullPointerArgumentEvaluator{_parameter, "no provided reference to JNI class parameter!"}.evaluate();
+  EmptyStringArgumentEvaluator{_path, "path to associated Java class is empty!"}.evaluate();
+  NullPointerArgumentEvaluator{_parameter->getJavaEnvironment(), "Java environment is not being provided!"}.evaluate();
+  this->parameter = _parameter;
+  this->path = _path;
+  ConditionalFunctionExecutor{_parameter->getJniApi() == nullptr}.execute([this]() { _createJniApi(); });
+}
+
+JniClass::~JniClass() = default;
+
+JniReturnValue JniClass::callMethod(const string &_methodIdentifier)
+{
+  JniReturnValue returnValue{};
+
+  if (this->_hasMethod(_methodIdentifier))
+  {
+    this->_callBooleanMethod(_methodIdentifier, returnValue);
+    this->_callByteMethod(_methodIdentifier, returnValue);
+    this->_callCharMethod(_methodIdentifier, returnValue);
+    this->_callDoubleMethod(_methodIdentifier, returnValue);
+    this->_callFloatMethod(_methodIdentifier, returnValue);
+    this->_callIntMethod(_methodIdentifier, returnValue);
+    this->_callLongMethod(_methodIdentifier, returnValue);
+    this->_callShortMethod(_methodIdentifier, returnValue);
+  }
+
+  return returnValue;
+}
+
+bool JniClass::hasMethod(const string &_methodIdentifier)
+{
+  return this->_hasMethod(_methodIdentifier);
+}
+
+bool JniClass::load()
+{
+  this->javaClass = this->parameter->getJniApi()->findClass(this->path);
+  return this->javaClass != nullptr;
+}
+
+bool JniClass::loadMethod(const string &_methodIdentifier, const string &_methodSignature)
+{
+  NullPointerEvaluator{this->javaClass, "no Java class reference available for loading class method!"}.evaluate();
+  jmethodID methodId = this->parameter->getJniApi()->getMethodId(this->javaClass, _methodIdentifier.c_str(), _methodSignature.c_str());
+  bool succeeded = methodId != nullptr && !this->_hasMethod(_methodIdentifier);
+
+  if (succeeded)
+  {
+    JniMethod method{_methodIdentifier, _methodSignature};
+    method.setMethodId(methodId);
+    succeeded = this->methods.insert(make_pair<string, JniMethod>(string{_methodIdentifier}, JniMethod{method})).second;
+  }
+
+  return succeeded;
+}
+
+void JniClass::_callBooleanMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")Z";
+  string methodSignature = method.getMethodSignature();
+  bool hasBooleanReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasBooleanReturnType)
+  {
+    _returnValue.setBooleanValue(this->parameter->getJniApi()->callBooleanMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
+void JniClass::_callByteMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")B";
+  string methodSignature = method.getMethodSignature();
+  bool hasByteReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasByteReturnType)
+  {
+    _returnValue.setByteValue(this->parameter->getJniApi()->callByteMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
+void JniClass::_callCharMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")C";
+  string methodSignature = method.getMethodSignature();
+  bool hasCharReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasCharReturnType)
+  {
+    _returnValue.setCharValue(this->parameter->getJniApi()->callCharMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
+void JniClass::_callDoubleMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")D";
+  string methodSignature = method.getMethodSignature();
+  bool hasDoubleReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasDoubleReturnType)
+  {
+    _returnValue.setDoubleValue(this->parameter->getJniApi()->callDoubleMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
+void JniClass::_callFloatMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")F";
+  string methodSignature = method.getMethodSignature();
+  bool hasFloatReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasFloatReturnType)
+  {
+    _returnValue.setFloatValue(this->parameter->getJniApi()->callFloatMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
+void JniClass::_callIntMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")I";
+  string methodSignature = method.getMethodSignature();
+  bool hasIntegerReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasIntegerReturnType)
+  {
+    _returnValue.setIntegerValue(this->parameter->getJniApi()->callIntMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
+void JniClass::_callLongMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")J";
+  string methodSignature = method.getMethodSignature();
+  bool hasLongReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasLongReturnType)
+  {
+    _returnValue.setLongValue(this->parameter->getJniApi()->callLongMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
+void JniClass::_callShortMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")S";
+  string methodSignature = method.getMethodSignature();
+  bool hasShortReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasShortReturnType)
+  {
+    _returnValue.setShortValue(this->parameter->getJniApi()->callShortMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
+void JniClass::_createJniApi()
+{
+  this->parameter->setJniApi(make_shared<JniApi>(this->parameter->getJavaEnvironment()));
+}
+
+bool JniClass::_hasMethod(const string &_methodIdentifier)
+{
+  return this->methods.find(_methodIdentifier) != this->methods.end();
+}

+ 49 - 0
source/ls-std/core/jni/JniClassParameter.cpp

@@ -0,0 +1,49 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-10
+*
+* */
+
+#include <ls-std/core/jni/JniClassParameter.hpp>
+
+using ls::std::core::experimental::JniClassParameter;
+using ls::std::core::experimental::interface_type::IJniApi;
+using std::shared_ptr;
+using std::string;
+
+JniClassParameter::JniClassParameter() = default;
+
+JniClassParameter::~JniClassParameter() = default;
+
+JNIEnv *JniClassParameter::getJavaEnvironment()
+{
+  return this->environment;
+}
+
+jobject JniClassParameter::getJavaObject()
+{
+  return this->javaObject;
+}
+
+shared_ptr<IJniApi> JniClassParameter::getJniApi()
+{
+  return this->jniApi;
+}
+
+void JniClassParameter::setJavaEnvironment(JNIEnv *_environment)
+{
+  this->environment = _environment;
+}
+
+void JniClassParameter::setJavaObject(jobject _javaObject)
+{
+  this->javaObject = _javaObject;
+}
+
+void JniClassParameter::setJniApi(const shared_ptr<IJniApi> &_jniApi)
+{
+  this->jniApi = _jniApi;
+}

+ 55 - 0
source/ls-std/core/jni/JniMethod.cpp

@@ -0,0 +1,55 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-08
+* Changed:         2023-04-10
+*
+* */
+
+#include <ls-std/core/evaluator/EmptyStringArgumentEvaluator.hpp>
+#include <ls-std/core/jni/JniMethod.hpp>
+
+using ls::std::core::EmptyStringArgumentEvaluator;
+using ls::std::core::experimental::JniMethod;
+using std::string;
+
+JniMethod::JniMethod(const string &_methodIdentifier, const string &_methodSignature)
+{
+  EmptyStringArgumentEvaluator{_methodIdentifier, "no method identifier has been provided!"}.evaluate();
+  EmptyStringArgumentEvaluator{_methodSignature, "no method signature has been provided!"}.evaluate();
+  this->methodIdentifier = _methodIdentifier;
+  this->methodSignature = _methodSignature;
+}
+
+JniMethod::~JniMethod() = default;
+
+jmethodID JniMethod::getMethodId()
+{
+  return this->methodId;
+}
+
+string JniMethod::getMethodIdentifier()
+{
+  return this->methodIdentifier;
+}
+
+string JniMethod::getMethodSignature()
+{
+  return this->methodSignature;
+}
+
+void JniMethod::setMethodId(jmethodID _methodId)
+{
+  this->methodId = _methodId;
+}
+
+void JniMethod::setMethodIdentifier(const string &_methodIdentifier)
+{
+  this->methodIdentifier = _methodIdentifier;
+}
+
+void JniMethod::setMethodSignature(const string &_methodSignature)
+{
+  this->methodSignature = _methodSignature;
+}

+ 96 - 0
source/ls-std/core/jni/JniReturnValue.cpp

@@ -0,0 +1,96 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-08
+* Changed:         2023-04-11
+*
+* */
+
+#include <ls-std/core/jni/JniReturnValue.hpp>
+
+using ls::std::core::experimental::JniReturnValue;
+
+JniReturnValue::JniReturnValue() = default;
+
+JniReturnValue::~JniReturnValue() = default;
+
+jboolean JniReturnValue::getBooleanValue() const
+{
+  return this->booleanValue;
+}
+
+jbyte JniReturnValue::getByteValue() const
+{
+  return this->byteValue;
+}
+
+jchar JniReturnValue::getCharValue() const
+{
+  return this->charValue;
+}
+
+jdouble JniReturnValue::getDoubleValue() const
+{
+  return this->doubleValue;
+}
+
+jfloat JniReturnValue::getFloatValue() const
+{
+  return this->floatValue;
+}
+
+jint JniReturnValue::getIntegerValue() const
+{
+  return this->integerValue;
+}
+
+jlong JniReturnValue::getLongValue() const
+{
+  return this->longValue;
+}
+
+jshort JniReturnValue::getShortValue() const
+{
+  return this->shortValue;
+}
+
+void JniReturnValue::setBooleanValue(jboolean _booleanValue)
+{
+  this->booleanValue = _booleanValue;
+}
+
+void JniReturnValue::setByteValue(jbyte _byteValue)
+{
+  this->byteValue = _byteValue;
+}
+
+void JniReturnValue::setCharValue(jchar _charValue)
+{
+  this->charValue = _charValue;
+}
+
+void JniReturnValue::setDoubleValue(jdouble _doubleValue)
+{
+  this->doubleValue = _doubleValue;
+}
+
+void JniReturnValue::setFloatValue(jfloat _floatValue)
+{
+  this->floatValue = _floatValue;
+}
+
+void JniReturnValue::setIntegerValue(jint _integerValue)
+{
+  this->integerValue = _integerValue;
+}
+
+void JniReturnValue::setLongValue(jlong _longValue)
+{
+  this->longValue = _longValue;
+}
+
+void JniReturnValue::setShortValue(jshort _shortValue)
+{
+  this->shortValue = _shortValue;
+}

+ 90 - 0
source/ls-std/time/common/DateParameter.cpp

@@ -0,0 +1,90 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-29
+* Changed:         2023-03-31
+*
+* */
+
+#include <ls-std/time/common/DateParameter.hpp>
+
+using ls::std::time::DateParameter;
+using ls::std::time::type::Day;
+using ls::std::time::type::Hour;
+using ls::std::time::type::Minute;
+using ls::std::time::type::Month;
+using ls::std::time::type::Second;
+using ls::std::time::type::Year;
+
+DateParameter::DateParameter(Year _year, Month _month, Day _day, Hour _hour, Minute _minute, Second _second) : year(_year), month(_month), day(_day), hour(_hour), minute(_minute), second(_second)
+{}
+
+DateParameter::DateParameter() = default;
+
+DateParameter::~DateParameter() = default;
+
+bool DateParameter::operator==(const DateParameter &_dateParameter) const
+{
+  return this->day == _dateParameter.getDay() && this->hour == _dateParameter.getHour() && this->minute == _dateParameter.getMinute() && this->month == _dateParameter.getMonth() && this->second == _dateParameter.getSecond() && this->year == _dateParameter.getYear();
+}
+
+Day DateParameter::getDay() const
+{
+  return this->day;
+}
+
+Hour DateParameter::getHour() const
+{
+  return this->hour;
+}
+
+Minute DateParameter::getMinute() const
+{
+  return this->minute;
+}
+
+Month DateParameter::getMonth() const
+{
+  return this->month;
+}
+
+Second DateParameter::getSecond() const
+{
+  return this->second;
+}
+
+Year DateParameter::getYear() const
+{
+  return this->year;
+}
+
+void DateParameter::setDay(Day _day)
+{
+  this->day = _day;
+}
+
+void DateParameter::setHour(Hour _hour)
+{
+  this->hour = _hour;
+}
+
+void DateParameter::setMinute(Minute _minute)
+{
+  this->minute = _minute;
+}
+
+void DateParameter::setMonth(Month _month)
+{
+  this->month = _month;
+}
+
+void DateParameter::setSecond(Second _second)
+{
+  this->second = _second;
+}
+
+void DateParameter::setYear(Year _year)
+{
+  this->year = _year;
+}

+ 56 - 0
source/ls-std/time/common/DateParameterMapper.cpp

@@ -0,0 +1,56 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-31
+* Changed:         2023-04-01
+*
+* */
+
+#if defined(unix) || defined(__APPLE__)
+  #include <ctime>
+#endif
+#include <ls-std/time/common/DateParameterMapper.hpp>
+
+using ls::std::time::DateParameter;
+using ls::std::time::DateParameterMapper;
+using ls::std::time::type::UnixTimestamp;
+
+DateParameterMapper::DateParameterMapper() = default;
+
+DateParameterMapper::~DateParameterMapper() = default;
+
+#if defined(unix) || defined(__APPLE__)
+UnixTimestamp DateParameterMapper::toUnixTimestamp(const DateParameter &_dateParameter)
+{
+  time_t rawTime{};
+  ::time(&rawTime);
+  tm *timeInfo = localtime(&rawTime);
+  timeInfo->tm_year = _dateParameter.getYear() - 1900;
+  timeInfo->tm_mon = _dateParameter.getMonth() - 1;
+  timeInfo->tm_mday = _dateParameter.getDay();
+  timeInfo->tm_hour = _dateParameter.getHour();
+  timeInfo->tm_min = _dateParameter.getMinute();
+  timeInfo->tm_sec = _dateParameter.getSecond();
+  timeInfo->tm_isdst = -1;
+
+  return (UnixTimestamp) mktime(timeInfo);
+}
+#endif
+
+#ifdef _WIN32
+SYSTEMTIME DateParameterMapper::toWindowsSystemTime(const DateParameter &_dateParameter)
+{
+  SYSTEMTIME systemTime{};
+  systemTime.wYear = _dateParameter.getYear();
+  systemTime.wMonth = _dateParameter.getMonth();
+  systemTime.wDayOfWeek = 0;
+  systemTime.wDay = _dateParameter.getDay();
+  systemTime.wHour = _dateParameter.getHour();
+  systemTime.wMinute = _dateParameter.getMinute();
+  systemTime.wSecond = _dateParameter.getSecond();
+  systemTime.wMilliseconds = 0;
+
+  return systemTime;
+}
+#endif

+ 35 - 0
source/ls-std/time/common/jni/JniDateParameterMapper.cpp

@@ -0,0 +1,35 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-09
+* Changed:         2023-04-10
+*
+* */
+
+#include <ls-std/core/jni/JniClass.hpp>
+#include <ls-std/time/common/DateParameter.hpp>
+#include <ls-std/time/common/jni/JniDateParameterMapper.hpp>
+
+using ls::std::core::experimental::JniClass;
+using ls::std::time::DateParameter;
+using ls::std::time::experimental::JniDateParameterMapper;
+
+JniDateParameterMapper::JniDateParameterMapper() = default;
+
+JniDateParameterMapper::~JniDateParameterMapper() = default;
+
+DateParameter JniDateParameterMapper::toDateParameter(const JniClass &_javaClass)
+{
+  JniClass javaClass = _javaClass;
+  DateParameter dateParameter{};
+
+  dateParameter.setYear(javaClass.callMethod("getYear").getIntegerValue());
+  dateParameter.setMonth(javaClass.callMethod("getMonth").getByteValue());
+  dateParameter.setDay(javaClass.callMethod("getDay").getByteValue());
+  dateParameter.setHour(javaClass.callMethod("getHour").getByteValue());
+  dateParameter.setMinute(javaClass.callMethod("getMinute").getByteValue());
+  dateParameter.setSecond(javaClass.callMethod("getSecond").getByteValue());
+
+  return dateParameter;
+}

+ 16 - 0
source/ls-std/time/system-time/IClock.cpp

@@ -0,0 +1,16 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-31
+* Changed:         2023-03-31
+*
+* */
+
+#include <ls-std/time/system-time/IClock.hpp>
+
+using ls::std::time::IClock;
+
+IClock::IClock() = default;
+
+IClock::~IClock() = default;

+ 28 - 0
source/ls-std/time/system-time/PosixClock.cpp

@@ -0,0 +1,28 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-15
+* Changed:         2023-03-31
+*
+* */
+
+#include <ctime>
+#include <ls-std/time/common/DateParameterMapper.hpp>
+#include <ls-std/time/system-time/PosixClock.hpp>
+
+using ls::std::time::DateParameter;
+using ls::std::time::DateParameterMapper;
+using ls::std::time::PosixClock;
+using ls::std::time::type::UnixTimestamp;
+
+PosixClock::PosixClock() = default;
+
+PosixClock::~PosixClock() noexcept = default;
+
+bool PosixClock::setTime(const DateParameter &_dateParameter)
+{
+  UnixTimestamp timestamp = DateParameterMapper::toUnixTimestamp(_dateParameter);
+  timespec timespec{timestamp, 0};
+  return clock_settime(CLOCK_REALTIME, &timespec) == 0;
+}

+ 65 - 0
source/ls-std/time/system-time/SystemTime.cpp

@@ -0,0 +1,65 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-15
+* Changed:         2023-04-01
+*
+* */
+
+#include <ls-std/core/Class.hpp>
+#include <ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp>
+#if defined(unix) || defined(__APPLE__)
+  #include <ls-std/time/system-time/PosixClock.hpp>
+#endif
+#include <ls-std/time/system-time/SystemTime.hpp>
+#include <ls-std/time/system-time/SystemTimeParameter.hpp>
+#ifdef _WIN32
+  #include <ls-std/time/system-time/WindowsClock.hpp>
+#endif
+#include <memory>
+
+using ls::std::core::Class;
+using ls::std::core::NullPointerArgumentEvaluator;
+using ls::std::time::DateParameter;
+#if defined(unix) || defined(__APPLE__)
+using ls::std::time::PosixClock;
+#endif
+using ls::std::time::SystemTime;
+using ls::std::time::SystemTimeParameter;
+#ifdef _WIN32
+using ls::std::time::WindowsClock;
+#endif
+using ls::std::time::type::UnixTimestamp;
+using std::make_shared;
+using std::shared_ptr;
+
+SystemTime::SystemTime(const shared_ptr<SystemTimeParameter> &_parameter) : SystemTime()
+{
+  NullPointerArgumentEvaluator{_parameter}.evaluate();
+  this->parameter = _parameter;
+}
+
+SystemTime::SystemTime() : Class("SystemTime")
+{
+  this->_generateParameter();
+}
+
+SystemTime::~SystemTime() noexcept = default;
+
+bool SystemTime::set(const DateParameter &_dateParameter)
+{
+  return this->parameter->getClock()->setTime(_dateParameter);
+}
+
+void SystemTime::_generateParameter()
+{
+  this->parameter = make_shared<SystemTimeParameter>();
+
+#if defined(unix) || defined(__APPLE__)
+  this->parameter->setClock(make_shared<PosixClock>());
+#endif
+#ifdef _WIN32
+  this->parameter->setClock(make_shared<WindowsClock>());
+#endif
+}

+ 29 - 0
source/ls-std/time/system-time/SystemTimeParameter.cpp

@@ -0,0 +1,29 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-15
+* Changed:         2023-03-31
+*
+* */
+
+#include <ls-std/time/system-time/SystemTimeParameter.hpp>
+#include <memory>
+
+using ls::std::time::IClock;
+using ls::std::time::SystemTimeParameter;
+using std::shared_ptr;
+
+SystemTimeParameter::SystemTimeParameter() = default;
+
+SystemTimeParameter::~SystemTimeParameter() = default;
+
+shared_ptr<IClock> SystemTimeParameter::getClock()
+{
+  return this->clock;
+}
+
+void SystemTimeParameter::setClock(const shared_ptr<IClock> &_clock)
+{
+  this->clock = _clock;
+}

+ 26 - 0
source/ls-std/time/system-time/WindowsClock.cpp

@@ -0,0 +1,26 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-01
+* Changed:         2023-04-01
+*
+* */
+
+#include <ls-std/time/common/DateParameterMapper.hpp>
+#include <ls-std/time/system-time/WindowsClock.hpp>
+#include <windows.h>
+
+using ls::std::time::DateParameter;
+using ls::std::time::DateParameterMapper;
+using ls::std::time::WindowsClock;
+
+WindowsClock::WindowsClock() = default;
+
+WindowsClock::~WindowsClock() noexcept = default;
+
+bool WindowsClock::setTime(const DateParameter &_dateParameter)
+{
+  SYSTEMTIME systemTime = DateParameterMapper::toWindowsSystemTime(_dateParameter);
+  return SetLocalTime(&systemTime);
+}

+ 69 - 0
source/ls-std/time/system-time/jni/com_lynarstudios_ls_std_time_systemtime_SystemTimeJni.cpp

@@ -0,0 +1,69 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-16
+* Changed:         2023-04-10
+*
+* */
+
+#include <iostream>
+#include <ls-std/core/evaluator/NullPointerEvaluator.hpp>
+#include <ls-std/core/jni/JniClass.hpp>
+#include <ls-std/core/jni/JniClassParameter.hpp>
+#include <ls-std/time/common/jni/JniDateParameterMapper.hpp>
+#include <ls-std/time/system-time/SystemTime.hpp>
+#include <ls-std/time/system-time/jni/com_lynarstudios_ls_std_time_systemtime_SystemTimeJni.h>
+#include <memory>
+
+using ls::std::core::NullPointerEvaluator;
+using ls::std::core::experimental::JniClass;
+using ls::std::core::experimental::JniClassParameter;
+using ls::std::time::DateParameter;
+using ls::std::time::SystemTime;
+using ls::std::time::experimental::JniDateParameterMapper;
+using ls::std::time::type::Day;
+using ls::std::time::type::Hour;
+using ls::std::time::type::Minute;
+using ls::std::time::type::Month;
+using ls::std::time::type::Second;
+using ls::std::time::type::Year;
+using std::cout;
+using std::endl;
+using std::make_shared;
+using std::pair;
+using std::shared_ptr;
+using std::string;
+
+JNIEXPORT jboolean JNICALL Java_com_lynarstudios_ls_std_time_systemtime_SystemTimeJni_set(JNIEnv *_environment, jobject _object, jobject _dateParameter)
+{
+  shared_ptr<JniClassParameter> parameter = make_shared<JniClassParameter>();
+  parameter->setJavaEnvironment(_environment);
+  parameter->setJavaObject(_dateParameter);
+
+  JniClass javaClass{parameter, "com/lynarstudios/ls/std/time/systemtime/DateParameter"};
+  javaClass.load();
+
+  javaClass.loadMethod("getYear", "()I");
+  javaClass.loadMethod("getMonth", "()B");
+  javaClass.loadMethod("getDay", "()B");
+  javaClass.loadMethod("getHour", "()B");
+  javaClass.loadMethod("getMinute", "()B");
+  javaClass.loadMethod("getSecond", "()B");
+
+  // map
+
+  DateParameter dateParameter = JniDateParameterMapper::toDateParameter(javaClass);
+  bool success = SystemTime{}.set(dateParameter);
+
+  if (success)
+  {
+    cout << R"lit(system time successfully set to ")lit" << dateParameter.getYear() << "-" << (int) dateParameter.getMonth() << "-" << (int) dateParameter.getDay() << " " << (int) dateParameter.getHour() << ":" << (int) dateParameter.getMinute() << ":" << (int) dateParameter.getSecond() << R"lit(" ...)lit" << endl;
+  }
+  else
+  {
+    cout << "could not set system time ..." << endl;
+  }
+
+  return success;
+}

+ 49 - 3
test/cases/core/evaluator/NullPointerArgumentEvaluatorTest.cpp

@@ -3,16 +3,18 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-08
-* Changed:         2023-03-25
+* Changed:         2023-04-07
 *
 * */
 
 #include <gtest/gtest.h>
 #include <ls-std/ls-std-core.hpp>
+#include <memory>
 #include <string>
 
 using ls::std::core::IllegalArgumentException;
 using ls::std::core::NullPointerArgumentEvaluator;
+using std::shared_ptr;
 using std::string;
 using testing::Test;
 
@@ -26,7 +28,7 @@ namespace
       ~NullPointerArgumentEvaluatorTest() override = default;
   };
 
-  TEST_F(NullPointerArgumentEvaluatorTest, evaluate)
+  TEST_F(NullPointerArgumentEvaluatorTest, evaluate_raw_pointer)
   {
     EXPECT_THROW(
         {
@@ -46,7 +48,7 @@ namespace
         IllegalArgumentException);
   }
 
-  TEST_F(NullPointerArgumentEvaluatorTest, evaluate_dedicated_message)
+  TEST_F(NullPointerArgumentEvaluatorTest, evaluate_raw_pointer_with_dedicated_message)
   {
     EXPECT_THROW(
         {
@@ -65,4 +67,48 @@ namespace
         },
         IllegalArgumentException);
   }
+
+  TEST_F(NullPointerArgumentEvaluatorTest, evaluate)
+  {
+    shared_ptr<void> value{};
+
+    EXPECT_THROW(
+        {
+          try
+          {
+            NullPointerArgumentEvaluator{value}.evaluate();
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            string actual = _exception.what();
+            string expected = _exception.getName() + " thrown - passed argument is null!";
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(NullPointerArgumentEvaluatorTest, evaluate_dedicated_message)
+  {
+    shared_ptr<void> value{};
+
+    EXPECT_THROW(
+        {
+          try
+          {
+            NullPointerArgumentEvaluator(value, "this reference is null!").evaluate();
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            string actual = _exception.what();
+            string expected = _exception.getName() + " thrown - this reference is null!";
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
 }

+ 49 - 3
test/cases/core/evaluator/NullPointerEvaluatorTest.cpp

@@ -3,16 +3,18 @@
 * Company:         Lynar Studios
 * E-Mail:          webmaster@lynarstudios.com
 * Created:         2023-02-08
-* Changed:         2023-03-25
+* Changed:         2023-04-04
 *
 * */
 
 #include <gtest/gtest.h>
 #include <ls-std/ls-std-core.hpp>
+#include <memory>
 #include <string>
 
 using ls::std::core::NullPointerEvaluator;
 using ls::std::core::NullPointerException;
+using std::shared_ptr;
 using std::string;
 using testing::Test;
 
@@ -26,7 +28,7 @@ namespace
       ~NullPointerArgumentTest() override = default;
   };
 
-  TEST_F(NullPointerArgumentTest, evaluate)
+  TEST_F(NullPointerArgumentTest, evaluate_raw_pointer)
   {
     EXPECT_THROW(
         {
@@ -46,7 +48,7 @@ namespace
         NullPointerException);
   }
 
-  TEST_F(NullPointerArgumentTest, evaluate_dedicated_message)
+  TEST_F(NullPointerArgumentTest, evaluate_raw_pointer_dedicated_message)
   {
     EXPECT_THROW(
         {
@@ -65,4 +67,48 @@ namespace
         },
         NullPointerException);
   }
+
+  TEST_F(NullPointerArgumentTest, evaluate)
+  {
+    shared_ptr<void> value{};
+
+    EXPECT_THROW(
+        {
+          try
+          {
+            NullPointerEvaluator{value}.evaluate();
+          }
+          catch (const NullPointerException &_exception)
+          {
+            string actual = _exception.what();
+            string expected = _exception.getName() + " thrown - reference in use is null!";
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        NullPointerException);
+  }
+
+  TEST_F(NullPointerArgumentTest, evaluate_dedicated_message)
+  {
+    shared_ptr<void> value{};
+
+    EXPECT_THROW(
+        {
+          try
+          {
+            NullPointerEvaluator(value, "this reference is not set and causes this exception!").evaluate();
+          }
+          catch (const NullPointerException &_exception)
+          {
+            string actual = _exception.what();
+            string expected = _exception.getName() + " thrown - this reference is not set and causes this exception!";
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        NullPointerException);
+  }
 }

+ 50 - 0
test/cases/core/jni/JniApiTest.cpp

@@ -0,0 +1,50 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-10
+*
+* */
+
+#include <gtest/gtest.h>
+#include <ls-std/ls-std-core-jni.hpp>
+#include <ls-std/ls-std-core.hpp>
+#include <string>
+
+using ls::std::core::IllegalArgumentException;
+using ls::std::core::experimental::JniApi;
+using std::string;
+using testing::Test;
+
+namespace
+{
+  class JniApiTest : public Test
+  {
+    public:
+
+      JniApiTest() = default;
+      ~JniApiTest() override = default;
+  };
+
+  TEST_F(JniApiTest, constructor)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            JniApi jniApi{nullptr};
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+
+            string expected = _exception.getName() + " thrown - Java environment is not being provided!";
+            string actual = _exception.what();
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+}

+ 77 - 0
test/cases/core/jni/JniClassParameterTest.cpp

@@ -0,0 +1,77 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-10
+*
+* */
+
+#include <gtest/gtest.h>
+#include <ls-std-core-jni-test.hpp>
+#include <ls-std/ls-std-core-jni.hpp>
+#include <memory>
+
+using ls::std::core::experimental::JniApi;
+using ls::std::core::experimental::JniClassParameter;
+using ls::std::core::experimental::interface_type::IJniApi;
+using std::make_shared;
+using std::shared_ptr;
+using test::core::jni::MockJniApi;
+using testing::Test;
+
+namespace
+{
+  class JniClassParameterTest : public Test
+  {
+    public:
+
+      JniClassParameterTest() = default;
+      ~JniClassParameterTest() override = default;
+  };
+
+  TEST_F(JniClassParameterTest, getJavaEnvironment)
+  {
+    JniClassParameter parameter{};
+    ASSERT_TRUE(parameter.getJavaEnvironment() == nullptr);
+  }
+
+  TEST_F(JniClassParameterTest, getJavaObject)
+  {
+    JniClassParameter parameter{};
+    ASSERT_TRUE(parameter.getJavaObject() == nullptr);
+  }
+
+  TEST_F(JniClassParameterTest, getJniApi)
+  {
+    JniClassParameter parameter{};
+    ASSERT_TRUE(parameter.getJniApi() == nullptr);
+  }
+
+  TEST_F(JniClassParameterTest, setJavaEnvironment)
+  {
+    JniClassParameter parameter{};
+    shared_ptr<JNIEnv> environment = make_shared<JNIEnv>();
+    parameter.setJavaEnvironment(environment.get());
+
+    ASSERT_TRUE(parameter.getJavaEnvironment() == environment.get());
+  }
+
+  TEST_F(JniClassParameterTest, setJavaObject)
+  {
+    JniClassParameter parameter{};
+    shared_ptr<_jobject> javaObject = make_shared<_jobject>();
+    parameter.setJavaObject(javaObject.get());
+
+    ASSERT_TRUE(parameter.getJavaObject() == javaObject.get());
+  }
+
+  TEST_F(JniClassParameterTest, setJniApi)
+  {
+    JniClassParameter parameter{};
+    shared_ptr<IJniApi> jniApi = make_shared<MockJniApi>();
+    parameter.setJniApi(jniApi);
+
+    ASSERT_TRUE(parameter.getJniApi() == jniApi);
+  }
+}

+ 369 - 0
test/cases/core/jni/JniClassTest.cpp

@@ -0,0 +1,369 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-11
+*
+* */
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <ls-std-core-jni-test.hpp>
+#include <ls-std/ls-std-core-jni.hpp>
+#include <ls-std/ls-std-core.hpp>
+#include <memory>
+
+using ls::std::core::IllegalArgumentException;
+using ls::std::core::NullPointerException;
+using ls::std::core::experimental::JniClass;
+using ls::std::core::experimental::JniClassParameter;
+using std::make_shared;
+using std::shared_ptr;
+using std::string;
+using test::core::jni::MockJniApi;
+using testing::AtLeast;
+using testing::Return;
+using testing::Test;
+
+namespace
+{
+  class JniClassTest : public Test
+  {
+    public:
+
+      JniClassTest() = default;
+      ~JniClassTest() override = default;
+
+      JniClass createJniClass(const string &_classPath)
+      {
+        shared_ptr<JniClassParameter> parameter = make_shared<JniClassParameter>();
+        this->jniApi = make_shared<MockJniApi>();
+        parameter->setJniApi(this->jniApi);
+        shared_ptr<JNIEnv> environment = make_shared<JNIEnv>();
+        parameter->setJavaEnvironment(environment.get());
+
+        return JniClass{parameter, _classPath};
+      }
+
+      shared_ptr<MockJniApi> jniApi{};
+  };
+
+  TEST_F(JniClassTest, constructor_no_parameter_reference)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            JniClass javaClass(nullptr, "java.utils.String");
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            string expected = _exception.getName() + " thrown - no provided reference to JNI class parameter!";
+            string actual = _exception.what();
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(JniClassTest, constructor_empty_path)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            JniClass javaClass(make_shared<JniClassParameter>(), "");
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            string expected = _exception.getName() + " thrown - path to associated Java class is empty!";
+            string actual = _exception.what();
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(JniClassTest, constructor_no_java_environment_reference)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            JniClass javaClass(make_shared<JniClassParameter>(), "java.utils.String");
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            string expected = _exception.getName() + " thrown - Java environment is not being provided!";
+            string actual = _exception.what();
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(JniClassTest, callMethod_boolean_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "isBlue";
+    string methodSignature = "()Z";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callBooleanMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callBooleanMethod(testing::_, methodId)).WillByDefault(Return(true));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_TRUE(javaClass.callMethod(methodIdentifier).getBooleanValue());
+  }
+
+  TEST_F(JniClassTest, callMethod_byte_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getDay";
+    string methodSignature = "()B";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callByteMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callByteMethod(testing::_, methodId)).WillByDefault(Return(22));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_EQ(22, javaClass.callMethod(methodIdentifier).getByteValue());
+  }
+
+  TEST_F(JniClassTest, callMethod_char_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getLetter";
+    string methodSignature = "()C";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callCharMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callCharMethod(testing::_, methodId)).WillByDefault(Return('P'));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_EQ('P', javaClass.callMethod(methodIdentifier).getCharValue());
+  }
+
+  TEST_F(JniClassTest, callMethod_double_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getPi";
+    string methodSignature = "()D";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callDoubleMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callDoubleMethod(testing::_, methodId)).WillByDefault(Return(3.14159265l));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_DOUBLE_EQ(3.14159265l, javaClass.callMethod(methodIdentifier).getDoubleValue());
+  }
+
+  TEST_F(JniClassTest, callMethod_float_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getPi";
+    string methodSignature = "()F";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callFloatMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callFloatMethod(testing::_, methodId)).WillByDefault(Return(3.14159f));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_FLOAT_EQ(3.14159f, javaClass.callMethod(methodIdentifier).getFloatValue());
+  }
+
+  TEST_F(JniClassTest, callMethod_integer_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getYear";
+    string methodSignature = "()I";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callIntMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callIntMethod(testing::_, methodId)).WillByDefault(Return(1989));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_EQ(1989, javaClass.callMethod(methodIdentifier).getIntegerValue());
+  }
+
+  TEST_F(JniClassTest, callMethod_long_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getAmountOfMoney";
+    string methodSignature = "()J";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callLongMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callLongMethod(testing::_, methodId)).WillByDefault(Return(18837828981));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_EQ(18837828981, javaClass.callMethod(methodIdentifier).getLongValue());
+  }
+
+  TEST_F(JniClassTest, callMethod_short_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getDay";
+    string methodSignature = "()S";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callShortMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callShortMethod(testing::_, methodId)).WillByDefault(Return(55));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_EQ(55, javaClass.callMethod(methodIdentifier).getShortValue());
+  }
+
+  TEST_F(JniClassTest, hasMethod)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    ASSERT_FALSE(javaClass.hasMethod("getDay"));
+  }
+
+  TEST_F(JniClassTest, load)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    ASSERT_TRUE(javaClass.load());
+  }
+
+  TEST_F(JniClassTest, loadMethod)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getDay";
+    string methodSignature = "()B";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+  }
+
+  TEST_F(JniClassTest, loadMethod_repeat)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getDay";
+    string methodSignature = "()B";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_FALSE(javaClass.loadMethod(methodIdentifier, methodSignature));
+  }
+
+  TEST_F(JniClassTest, loadMethod_without_previous_class_load)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    string methodIdentifier = "getDay";
+    string methodSignature = "()B";
+
+    EXPECT_THROW(
+        {
+          try
+          {
+            javaClass.loadMethod(methodIdentifier, methodSignature);
+          }
+          catch (const NullPointerException &_exception)
+          {
+            string expected = _exception.getName() + " thrown - no Java class reference available for loading class method!";
+            string actual = _exception.what();
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        NullPointerException);
+  }
+}

+ 114 - 0
test/cases/core/jni/JniMethodTest.cpp

@@ -0,0 +1,114 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-08
+* Changed:         2023-04-10
+*
+* */
+
+#include <gtest/gtest.h>
+#include <ls-std/ls-std-core-jni.hpp>
+#include <ls-std/ls-std-core.hpp>
+#include <memory>
+#include <string>
+
+using ls::std::core::IllegalArgumentException;
+using ls::std::core::experimental::JniMethod;
+using std::make_shared;
+using std::string;
+using testing::Test;
+
+namespace
+{
+  class JniMethodTest : public Test
+  {
+    public:
+
+      JniMethodTest() = default;
+      ~JniMethodTest() override = default;
+  };
+
+  TEST_F(JniMethodTest, constructor_empty_method_identifier)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            JniMethod method("", "()B");
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            string expected = _exception.getName() + " thrown - no method identifier has been provided!";
+            string actual = _exception.what();
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(JniMethodTest, constructor_empty_method_signature)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            JniMethod method("getDay", "");
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            string expected = _exception.getName() + " thrown - no method signature has been provided!";
+            string actual = _exception.what();
+
+            ASSERT_STREQ(expected.c_str(), actual.c_str());
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(JniMethodTest, getMethodId)
+  {
+    JniMethod method{"getDay", "()B"};
+    ASSERT_TRUE(method.getMethodId() == nullptr);
+  }
+
+  TEST_F(JniMethodTest, getMethodIdentifier)
+  {
+    JniMethod method{"getDay", "()B"};
+    ASSERT_STREQ("getDay", method.getMethodIdentifier().c_str());
+  }
+
+  TEST_F(JniMethodTest, getMethodSignature)
+  {
+    JniMethod method{"getDay", "()B"};
+    ASSERT_STREQ("()B", method.getMethodSignature().c_str());
+  }
+
+  TEST_F(JniMethodTest, setMethodId)
+  {
+    JniMethod method{"getDay", "()B"};
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    method.setMethodId(methodId);
+
+    ASSERT_TRUE(method.getMethodId() == methodId);
+  }
+
+  TEST_F(JniMethodTest, setMethodIdentifier)
+  {
+    JniMethod method{"getDay", "()B"};
+    method.setMethodIdentifier("getHour");
+
+    ASSERT_STREQ("getHour", method.getMethodIdentifier().c_str());
+  }
+
+  TEST_F(JniMethodTest, setMethodSignature)
+  {
+    JniMethod method{"getDay", "()B"};
+    method.setMethodSignature("()I");
+
+    ASSERT_STREQ("()I", method.getMethodSignature().c_str());
+  }
+}

+ 137 - 0
test/cases/core/jni/JniReturnValueTest.cpp

@@ -0,0 +1,137 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-08
+* Changed:         2023-04-11
+*
+* */
+
+#include <gtest/gtest.h>
+#include <ls-std/ls-std-core-jni.hpp>
+
+using ls::std::core::experimental::JniReturnValue;
+using testing::Test;
+
+namespace
+{
+  class JniReturnValueTest : public Test
+  {
+    public:
+
+      JniReturnValueTest() = default;
+      ~JniReturnValueTest() override = default;
+  };
+
+  TEST_F(JniReturnValueTest, getBooleanValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_FALSE(returnValue.getBooleanValue());
+  }
+
+  TEST_F(JniReturnValueTest, getByteValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_EQ(0, returnValue.getByteValue());
+  }
+
+  TEST_F(JniReturnValueTest, getCharValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_EQ(0, (int) returnValue.getCharValue());
+  }
+
+  TEST_F(JniReturnValueTest, getDoubleValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_FLOAT_EQ(0.0l, returnValue.getDoubleValue());
+  }
+
+  TEST_F(JniReturnValueTest, getFloatValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_FLOAT_EQ(0.0f, returnValue.getFloatValue());
+  }
+
+  TEST_F(JniReturnValueTest, getIntegerValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_EQ(0, returnValue.getIntegerValue());
+  }
+
+  TEST_F(JniReturnValueTest, getLongValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_EQ(0, returnValue.getLongValue());
+  }
+
+  TEST_F(JniReturnValueTest, getShortValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_EQ(0, returnValue.getShortValue());
+  }
+
+  TEST_F(JniReturnValueTest, setBooleanValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setBooleanValue(true);
+
+    ASSERT_TRUE(returnValue.getBooleanValue());
+  }
+
+  TEST_F(JniReturnValueTest, setByteValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setByteValue(22);
+
+    ASSERT_EQ(22, returnValue.getByteValue());
+  }
+
+  TEST_F(JniReturnValueTest, setCharValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setCharValue('P');
+
+    ASSERT_EQ('P', returnValue.getCharValue());
+  }
+
+  TEST_F(JniReturnValueTest, setDoubleValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setDoubleValue(3.14159265l);
+
+    ASSERT_FLOAT_EQ(3.14159265l, returnValue.getDoubleValue());
+  }
+
+  TEST_F(JniReturnValueTest, setFloatValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setFloatValue(13.56f);
+
+    ASSERT_FLOAT_EQ(13.56f, returnValue.getFloatValue());
+  }
+
+  TEST_F(JniReturnValueTest, setIntegerValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setIntegerValue(1989);
+
+    ASSERT_EQ(1989, returnValue.getIntegerValue());
+  }
+
+  TEST_F(JniReturnValueTest, setLongValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setLongValue(16992831);
+
+    ASSERT_EQ(16992831, returnValue.getLongValue());
+  }
+
+  TEST_F(JniReturnValueTest, setShortValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setShortValue(13);
+
+    ASSERT_EQ(13, returnValue.getShortValue());
+  }
+}

+ 0 - 1
test/cases/io/evaluator/FileExistenceEvaluatorTest.cpp

@@ -40,7 +40,6 @@ namespace
           {
             string actual = _exception.what();
             string expected = _exception.getName() + " thrown - \"" + GetParam() + "\" does not exist!";
-            ;
 
             ASSERT_STREQ(expected.c_str(), actual.c_str());
             throw;

+ 91 - 0
test/cases/time/common/DateParameterMapperTest.cpp

@@ -0,0 +1,91 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-31
+* Changed:         2023-04-01
+*
+* */
+
+#include <gtest/gtest.h>
+#include <ls-std/ls-std-time.hpp>
+#include <utility>
+#include <vector>
+#ifdef _WIN32
+  #include <windows.h>
+#endif
+
+using ls::std::time::DateParameter;
+using ls::std::time::DateParameterMapper;
+using ls::std::time::type::UnixTimestamp;
+using std::pair;
+using std::vector;
+using testing::TestWithParam;
+using testing::Values;
+
+namespace
+{
+#if defined(unix) || defined(__APPLE__)
+  class DateParameterMapperTest_Unix : public TestWithParam<pair<UnixTimestamp, DateParameter>>
+  {
+    public:
+
+      DateParameterMapperTest_Unix() = default;
+      ~DateParameterMapperTest_Unix() override = default;
+
+      static vector<pair<UnixTimestamp, DateParameter>> getTestParameterList()
+      {
+        vector<pair<UnixTimestamp, DateParameter>> testParameterList{};
+        testParameterList.emplace_back(656936700, DateParameter{1990, 10, 26, 11, 25, 00});
+        testParameterList.emplace_back(612694320, DateParameter{1989, 6, 1, 10, 52, 00});
+
+        return testParameterList;
+      }
+  };
+
+  TEST_P(DateParameterMapperTest_Unix, toUnixTimestamp)
+  {
+    DateParameter dateParameter = GetParam().second;
+    UnixTimestamp timestamp = DateParameterMapper::toUnixTimestamp(dateParameter);
+
+    ASSERT_EQ(GetParam().first, timestamp);
+  }
+
+  INSTANTIATE_TEST_SUITE_P(toUnixTimestamp, DateParameterMapperTest_Unix, Values(DateParameterMapperTest_Unix::getTestParameterList().at(0), DateParameterMapperTest_Unix::getTestParameterList().at(1)));
+#endif
+#ifdef _WIN32
+  class DateParameterMapperTest_Windows : public TestWithParam<DateParameter>
+  {
+    public:
+
+      DateParameterMapperTest_Windows() = default;
+      ~DateParameterMapperTest_Windows() override = default;
+
+      static vector<DateParameter> getTestParameterList()
+      {
+        vector<DateParameter> testParameterList{};
+        testParameterList.emplace_back(1990, 10, 26, 11, 25, 00);
+        testParameterList.emplace_back(1989, 6, 1, 10, 52, 00);
+
+        return testParameterList;
+      }
+  };
+
+  TEST_P(DateParameterMapperTest_Windows, toWindowsSystemTime)
+  {
+    DateParameter dateParameter = GetParam();
+    SYSTEMTIME systemTime = DateParameterMapper::toWindowsSystemTime(dateParameter);
+
+    ASSERT_EQ(systemTime.wYear, GetParam().getYear());
+    ASSERT_EQ(systemTime.wMonth, GetParam().getMonth());
+    ASSERT_EQ(systemTime.wDayOfWeek, 0);
+    ASSERT_EQ(systemTime.wDay, GetParam().getDay());
+    ASSERT_EQ(systemTime.wHour, GetParam().getHour());
+    ASSERT_EQ(systemTime.wMinute, GetParam().getMinute());
+    ASSERT_EQ(systemTime.wSecond, GetParam().getSecond());
+    ASSERT_EQ(systemTime.wMilliseconds, 0);
+  }
+
+  INSTANTIATE_TEST_SUITE_P(toWindowsSystemTime, DateParameterMapperTest_Windows, Values(DateParameterMapperTest_Windows::getTestParameterList().at(0), DateParameterMapperTest_Windows::getTestParameterList().at(1)));
+#endif
+}

+ 137 - 0
test/cases/time/common/DateParameterTest.cpp

@@ -0,0 +1,137 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-29
+* Changed:         2023-03-31
+*
+* */
+
+#include <gtest/gtest.h>
+#include <ls-std/ls-std-time.hpp>
+
+using ls::std::time::DateParameter;
+using testing::Test;
+
+namespace
+{
+  class DateParameterTest : public Test
+  {
+    public:
+
+      DateParameterTest() = default;
+      ~DateParameterTest() override = default;
+  };
+
+  TEST_F(DateParameterTest, constructor)
+  {
+    DateParameter parameter{1989, 6, 1, 10, 52, 13};
+
+    ASSERT_EQ(1989, parameter.getYear());
+    ASSERT_EQ(6, parameter.getMonth());
+    ASSERT_EQ(1, parameter.getDay());
+    ASSERT_EQ(10, parameter.getHour());
+    ASSERT_EQ(52, parameter.getMinute());
+    ASSERT_EQ(13, parameter.getSecond());
+  }
+
+  TEST_F(DateParameterTest, operator_equals)
+  {
+    DateParameter requiredBirthday{1989, 6, 1, 10, 52, 13};
+    DateParameter hisBirthday{1989, 6, 1, 10, 52, 13};
+
+    ASSERT_TRUE(requiredBirthday == hisBirthday);
+  }
+
+  TEST_F(DateParameterTest, operator_equals_not_equals)
+  {
+    DateParameter hisBirthday{1989, 6, 1, 10, 52, 00};
+    DateParameter herBirthday{1990, 10, 26, 11, 25, 00};
+
+    ASSERT_FALSE(herBirthday == hisBirthday);
+  }
+
+  TEST_F(DateParameterTest, getDay)
+  {
+    DateParameter parameter{};
+    ASSERT_EQ(0, parameter.getDay());
+  }
+
+  TEST_F(DateParameterTest, getHour)
+  {
+    DateParameter parameter{};
+    ASSERT_EQ(0, parameter.getHour());
+  }
+
+  TEST_F(DateParameterTest, getMinute)
+  {
+    DateParameter parameter{};
+    ASSERT_EQ(0, parameter.getMinute());
+  }
+
+  TEST_F(DateParameterTest, getMonth)
+  {
+    DateParameter parameter{};
+    ASSERT_EQ(0, parameter.getMonth());
+  }
+
+  TEST_F(DateParameterTest, getSecond)
+  {
+    DateParameter parameter{};
+    ASSERT_EQ(0, parameter.getSecond());
+  }
+
+  TEST_F(DateParameterTest, getYear)
+  {
+    DateParameter parameter{};
+    ASSERT_EQ(0, parameter.getYear());
+  }
+
+  TEST_F(DateParameterTest, setDay)
+  {
+    DateParameter parameter{};
+    parameter.setDay(1);
+
+    ASSERT_EQ(1, parameter.getDay());
+  }
+
+  TEST_F(DateParameterTest, setHour)
+  {
+    DateParameter parameter{};
+    parameter.setHour(10);
+
+    ASSERT_EQ(10, parameter.getHour());
+  }
+
+  TEST_F(DateParameterTest, setMinute)
+  {
+    DateParameter parameter{};
+    parameter.setMinute(52);
+
+    ASSERT_EQ(52, parameter.getMinute());
+  }
+
+  TEST_F(DateParameterTest, setMonth)
+  {
+    DateParameter parameter{};
+    parameter.setMonth(6);
+
+    ASSERT_EQ(6, parameter.getMonth());
+  }
+
+  TEST_F(DateParameterTest, setSecond)
+  {
+    DateParameter parameter{};
+    parameter.setSecond(13);
+
+    ASSERT_EQ(13, parameter.getSecond());
+  }
+
+  TEST_F(DateParameterTest, setYear)
+  {
+    DateParameter parameter{};
+    parameter.setYear(1989);
+
+    ASSERT_EQ(1989, parameter.getYear());
+  }
+}

+ 57 - 0
test/cases/time/system-time/SystemTimeParameterTest.cpp

@@ -0,0 +1,57 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-15
+* Changed:         2023-04-01
+*
+* */
+
+#include <gtest/gtest.h>
+#include <ls-std/ls-std-time.hpp>
+#include <memory>
+
+using ls::std::time::IClock;
+#if defined(unix) || defined(__APPLE__)
+using ls::std::time::PosixClock;
+#endif
+using ls::std::time::SystemTimeParameter;
+#ifdef _WIN32
+using ls::std::time::WindowsClock;
+#endif
+using std::make_shared;
+using std::shared_ptr;
+using testing::Test;
+
+namespace
+{
+  class SystemTimeParameterTest : public Test
+  {
+    public:
+
+      SystemTimeParameterTest() = default;
+      ~SystemTimeParameterTest() override = default;
+  };
+
+  TEST_F(SystemTimeParameterTest, getClock)
+  {
+    ASSERT_TRUE(SystemTimeParameter{}.getClock() == nullptr);
+  }
+
+  TEST_F(SystemTimeParameterTest, setClock)
+  {
+    SystemTimeParameter parameter{};
+    shared_ptr<IClock> clock{};
+
+#if defined(unix) || defined(__APPLE__)
+    clock = make_shared<PosixClock>();
+#endif
+#ifdef _WIN32
+    clock = make_shared<WindowsClock>();
+#endif
+
+    parameter.setClock(clock);
+
+    ASSERT_TRUE(parameter.getClock() == clock);
+  }
+}

+ 71 - 0
test/cases/time/system-time/SystemTimeTest.cpp

@@ -0,0 +1,71 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-15
+* Changed:         2023-04-01
+*
+* */
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <ls-std-time-test.hpp>
+#include <ls-std/ls-std-core.hpp>
+#include <ls-std/ls-std-time.hpp>
+#include <memory>
+
+using ls::std::core::IllegalArgumentException;
+using ls::std::time::DateParameter;
+using ls::std::time::SystemTime;
+using ls::std::time::SystemTimeParameter;
+using std::make_shared;
+using std::shared_ptr;
+using test::time::MockClock;
+using testing::AtLeast;
+using testing::Return;
+using testing::Test;
+
+namespace
+{
+  class SystemTimeTest : public Test
+  {
+    public:
+
+      SystemTimeTest() = default;
+      ~SystemTimeTest() override = default;
+  };
+
+  TEST_F(SystemTimeTest, constructor)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            SystemTime systemTime{nullptr};
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(SystemTimeTest, getClassName)
+  {
+    ASSERT_STREQ("SystemTime", SystemTime{}.getClassName().c_str());
+  }
+
+  TEST_F(SystemTimeTest, setTime)
+  {
+    shared_ptr<SystemTimeParameter> parameter = make_shared<SystemTimeParameter>();
+    shared_ptr<MockClock> posixClock = make_shared<MockClock>();
+    parameter->setClock(posixClock);
+    DateParameter birthday = DateParameter(1990, 10, 26, 11, 25, 00);
+
+    EXPECT_CALL(*posixClock, setTime(birthday)).Times(AtLeast(1));
+    ON_CALL(*posixClock, setTime(birthday)).WillByDefault(Return(true));
+
+    ASSERT_TRUE(SystemTime{parameter}.set(birthday));
+  }
+}

+ 16 - 0
test/classes/core/jni/MockJniApi.cpp

@@ -0,0 +1,16 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-07
+*
+* */
+
+#include "MockJniApi.hpp"
+
+using test::core::jni::MockJniApi;
+
+MockJniApi::MockJniApi() = default;
+
+MockJniApi::~MockJniApi() noexcept = default;

+ 38 - 0
test/classes/core/jni/MockJniApi.hpp

@@ -0,0 +1,38 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-11
+*
+* */
+
+#ifndef LS_STD_MOCK_JNI_API_HPP
+#define LS_STD_MOCK_JNI_API_HPP
+
+#include <gmock/gmock.h>
+#include <ls-std/core/interface/IJniApi.hpp>
+
+namespace test::core::jni
+{
+  class MockJniApi : public ls::std::core::experimental::interface_type::IJniApi
+  {
+    public:
+
+      MockJniApi();
+      ~MockJniApi() noexcept override;
+
+      MOCK_METHOD(jboolean, callBooleanMethod, (jobject _javaObject, jmethodID _methodId), (override));
+      MOCK_METHOD(jbyte, callByteMethod, (jobject _javaObject, jmethodID _methodINd), (override));
+      MOCK_METHOD(jchar, callCharMethod, (jobject _javaObject, jmethodID _methodId), (override));
+      MOCK_METHOD(jdouble, callDoubleMethod, (jobject _javaObject, jmethodID _methodId), (override));
+      MOCK_METHOD(jfloat, callFloatMethod, (jobject _javaObject, jmethodID _methodId), (override));
+      MOCK_METHOD(jint, callIntMethod, (jobject _javaObject, jmethodID _methodId), (override));
+      MOCK_METHOD(jlong, callLongMethod, (jobject _javaObject, jmethodID _methodId), (override));
+      MOCK_METHOD(jshort, callShortMethod, (jobject _javaObject, jmethodID _methodId), (override));
+      MOCK_METHOD(jclass, findClass, (const ::std::string &_classPath), (override));
+      MOCK_METHOD(jmethodID, getMethodId, (jclass _javaClass, const char *_methodIdentifier, const char *_methodSignature), (override));
+  };
+}
+
+#endif

+ 16 - 0
test/classes/time/system-time/MockClock.cpp

@@ -0,0 +1,16 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-15
+* Changed:         2023-04-01
+*
+* */
+
+#include "MockClock.hpp"
+
+using test::time::MockClock;
+
+MockClock::MockClock() = default;
+
+MockClock::~MockClock() noexcept = default;

+ 30 - 0
test/classes/time/system-time/MockClock.hpp

@@ -0,0 +1,30 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-15
+* Changed:         2023-04-01
+*
+* */
+
+#ifndef LS_STD_MOCK_CLOCK_HPP
+#define LS_STD_MOCK_CLOCK_HPP
+
+#include <gmock/gmock.h>
+#include <ls-std/time/common/DateParameter.hpp>
+#include <ls-std/time/system-time/IClock.hpp>
+
+namespace test::time
+{
+  class MockClock : public ls::std::time::IClock
+  {
+    public:
+
+      MockClock();
+      ~MockClock() noexcept override;
+
+      MOCK_METHOD(bool, setTime, (const ls::std::time::DateParameter &_dateParameter), (override));
+  };
+}
+
+#endif

+ 15 - 0
test/ls-std-core-jni-test.hpp

@@ -0,0 +1,15 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-04-07
+* Changed:         2023-04-07
+*
+* */
+
+#ifndef LS_STD_LS_STD_CORE_JNI_TEST_HPP
+#define LS_STD_LS_STD_CORE_JNI_TEST_HPP
+
+#include <classes/core/jni/MockJniApi.hpp>
+
+#endif

+ 15 - 0
test/ls-std-time-test.hpp

@@ -0,0 +1,15 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-03-15
+* Changed:         2023-04-01
+*
+* */
+
+#ifndef LS_STD_LS_STD_TIME_TEST_HPP
+#define LS_STD_LS_STD_TIME_TEST_HPP
+
+#include <classes/time/system-time/MockClock.hpp>
+
+#endif