diff --git a/qthing/include/qthing.hpp b/qthing/include/qthing.hpp
index 9b2950b0e3c80b26978da71d0b322c55b5f7df01..7708b3b444e71051ce7d78f1cbc170c4f89c2270 100644
--- a/qthing/include/qthing.hpp
+++ b/qthing/include/qthing.hpp
@@ -6,6 +6,7 @@
 #include "network.hpp"
 #include "power.hpp"
 #include "qthing_legacy.hpp"
+#include "time.hpp"
 #include "util.hpp"
 
 #undef QTHING_HIDE_PRIVATE_API
diff --git a/qthing/include/time.hpp b/qthing/include/time.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..8aa8fcd0d906b0717380cf87e53a75846a68428b
--- /dev/null
+++ b/qthing/include/time.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <ctime>
+#include <optional>
+
+namespace qthing {
+
+#if __cplusplus >= 201703L
+std::optional<tm> get_localtime();
+#endif
+bool get_localtime(tm& tm);
+
+}  // namespace qthing
diff --git a/qthing/ntp.cpp b/qthing/ntp.cpp
index 6cb985f18c14f4b2ee4b8e706d12adc21987bf14..5fe9ae684a1dfc57c723ec73449c18945723cd2e 100644
--- a/qthing/ntp.cpp
+++ b/qthing/ntp.cpp
@@ -37,9 +37,13 @@ void ntp_task(void* ignored) {
     localtime_r(&now, &timeinfo);
   } while (timeinfo.tm_year < 100);
 
-  ESP_LOGI(TAG, "Time synchronized: %i:%i:%i %i-%i-%i", timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec,
-           timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday);
-  if (parameter.callback != NULL) parameter.callback();
+  if (timeinfo.tm_year == 100) {
+    ESP_LOGE(TAG, "Failed to aquire NTP time for 100 years");
+  } else {
+    ESP_LOGI(TAG, "Time synchronized: %i:%i:%i %i-%i-%i", timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec,
+             timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday);
+    if (parameter.callback != NULL) parameter.callback();
+  }
 
   vTaskDelete(NULL);
 }
diff --git a/qthing/system/time.cpp b/qthing/system/time.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1d84af8c0173c71876a0f6ba4920b85dd85c1e6c
--- /dev/null
+++ b/qthing/system/time.cpp
@@ -0,0 +1,16 @@
+#include "time.hpp"
+
+bool qthing::get_localtime(tm& result) {
+  time_t now = time(NULL);
+  localtime_r(&now, &result);
+  return result.tm_year > 100;
+}
+
+std::optional<tm> qthing::get_localtime() {
+  tm result;
+  if (qthing::get_localtime(result)) {
+    return result;
+  } else {
+    return {};
+  }
+}