GUIDES Time How Time and Timezone are Initialized
About
Binary Data
Captive Portal
DNS
DNS Service Discovery
EventSource
Files
HTTP
HTTP Server
Implementing ECMA-419 Modules
Key-Value Storage
Logging
MQTT
Optimizing Embedded JavaScript
Streams
Time
Time Callbacks
Transport Layer Security (TLS)
WebSocket
WebSocket Server
Wi-Fi
Wi-Fi Access Point
Overview
Get Unix Time
Get Time of Day
Get Date
Get Time Since System Start
Get Microseconds
Set System Date and Time
How Time and Timezone are Initialized
Get Time and Date from Real-Time Clock
Set Real-Time Clock Time
Get Time and Date from Network
Sleep
About
Binary Data
Overview
Convert String to ArrayBuffer
Convert ArrayBuffer to String
Convert ArrayBuffers to String
Handle Errors Converting ArrayBuffer to String
Immutable ArrayBuffers
Resize an ArrayBuffer
Combine ArrayBuffers
Convert Base64 to Binary Data
Convert Binary Data to Base64
Convert Binary Data to Hex
Convert Hex to Binary Data
Calculate CRC for Binary Data
Compress Binary Data – One Buffer
Compress Binary Data – Streaming
Decompress Binary Data – One Buffer
Decompress Binary Data – Streaming
Captive Portal
Overview
Create Captive Portal
Close Captive Portal
Provide Web Pages for Captive Portal
Get Information from Captive Portal
DNS
Overview
Resolve Name
Resolve Multiple Names
DNS Service Discovery
Overview
Claim Local Name
Advertise Services
Discover Services
EventSource
Overview
Connect
Connect Securely
Close
Receive
Connection Information
Files
Overview
Create, Open, and Close File
Read File
Write File
Delete File
Get File Information
Create Directory
Enumerate Directory
Delete Directory
Open Directory
HTTP
Overview
Make Request using fetch()
Make Secure Request using fetch()
Send Request Headers using fetch()
Receive Response Headers using fetch()
Send Request Body using fetch()
Make Request using HTTP Client
Make Secure Request using HTTP Client
Send Request Headers using HTTP Client
Receive Response Headers using HTTP Client
Send Request Body using HTTP Client
HTTP Server
Overview
Create Server
Route Request
Respond to Request
Respond to Request with File
Receive Request Body
Receive Request Body to File
Implementing ECMA-419 Modules
Overview
Constructor Sets target
Constructor IO
Constructor Clean-up on Failure
close() and [Symbol.dispose]
Calling Callbacks
Setting Options with configure()
Keep Instance Surface Clean
Key-Value Storage
Overview
Read and Write Values using Web Storage
Delete Keys using Web Storage
Enumerate Keys using Web Storage
Read and Write Values using Key-Value Pair
Change Data Formats using Key-Value Pair
Delete Keys using Key-Value Pair
Enumerate Keys using Key-Value Pair
Logging
Overview
Logging with Console
Logging with trace()
MQTT
Overview
Connect to MQTT Server using MQTT()
Connect Securely to MQTT Server using MQTT()
Close Connection using MQTT()
Publish Message using MQTT()
Subscribe to Topic using MQTT()
Receive Messages using MQTT()
Get Connection Information using MQTT()
Connect to MQTT Server using MQTT Client
Connect Securely to MQTT Server using MQTT Client
Close Connection using MQTT Client
Publish Message using MQTT Client
Subscribe to Topic using MQTT Client
Receive Messages using MQTT Client
Optimizing Embedded JavaScript
Overview
When to Optimize
Know Where to Optimize
Loop through an Array
Iterate Over a String
Build a String
Avoid Copying Buffers
Accessing Properties
Map versus Object
Append to an Array
Operate on Bits
Define Class Methods
Streams
Overview
Time
Overview
Get Unix Time
Get Time of Day
Get Date
Get Time Since System Start
Get Microseconds
Set System Date and Time
How Time and Timezone are Initialized
Get Time and Date from Real-Time Clock
Set Real-Time Clock Time
Get Time and Date from Network
Sleep
Time Callbacks
Overview
One-Time Callback
Repeating Callback
Repeating Callback with Initial Delay
Immediate Callback
Reschedule Callback
Cancel Callback
Suspend Callback
Transport Layer Security (TLS)
Overview
Include Public Certificates
Include Private Certificates
Diagnostics
DER and PEM Certificates
WebSocket
Overview
Connect to Server using WebSocket()
Connect Securely to Server using WebSocket()
Close Connection using WebSocket()
Send Message using WebSocket()
Receive Message using WebSocket()
Get Connection Information using WebSocket()
Connect to Server using WebSocket Client
Connect Securely to Server using WebSocket Client
Close Connection using WebSocket Client
Send Message using WebSocket Client
Receive Message using WebSocket Client
Control Messages using WebSocket Client
Connect to Server using WebSocketStream
Connect Securely to Server using WebSocketStream
Close Connection using WebSocketStream
Send Message using WebSocketStream
Receive Message using WebSocketStream
WebSocket Server
Overview
Create WebSocket Server Endpoint
Accept WebSocket Request
Wi-Fi
Overview
Scan for Access Points
Scan Continuously for Access Points
Connect
Reconnect Automatically
Disconnect
Get Connection Information
Use Static IP Address
Wi-Fi Access Point
Overview
Create Access Point
Close Access Point
Get Information
Manage Stations
DNS Redirect
Provide HTTP Server

How Time and Timezone are Initialized

The system time needs to be set when the microcontroller starts up. In addition, many projects require the system's timezone and daylight saving time to be set. These are done in a variety of different ways, depending on the capabilities of the device hardware, the device firmware, and your project. In some cases, the host firmware takes care of them; in others, your project must initialize these values.

When developing with the Moddable SDK, the JavaScript debugger connection automatically initializes the microcontroller's system time, timezone, and daylight saving time offset from the corresponding values on the development computer. This behavior is convenient. It can, however, lead developers to believe they don't need to manage these values in their own projects. Try running an instrumented build on the device to test without the debugger (run an instrumented build by replacing -d with -i when running mcconfig).

If your project uses the default Wi-Fi set-up by passing SSID and password to mcconfig, the Wi-Fi set-up code attempts to initialize the system time using NTP before your project's main runs. This ensures an accurate system time, which is essential for validating certificates when using secure network communication with TLS. NTP cannot, however, initialize the timezone and daylight saving time. If your project manages the Wi-Fi connection itself, you may also want to initialize the system time using NTP.

If your development board includes a battery-backed real-time clock (RTC), a host may initialize the system time from the real-time clock at start-up. If the host does not do that, you can set the system time from the RTC. Your code may still need to perform a one-time initialization of the RTC, if it has not yet been set. An RTC does not usually provide the timezone or daylight saving time offset.

Note that when running the simulator, the system time, timezone, and daylight saving time offset are initialized from the computer running the simulator and may not be changed. Consequently, it is necessary to test time initialization code on the device, preferably with an instrumented build.

A common way to determine if the system time has been initialized is to compare the system time to the time your code was developed. This guide was written at Unix time 1787160049 (in seconds).

if (Date.now() >= 1787160049_000)
	trace(`Time initialized: ${new Date()}\n`);
else
	trace(`Time uninitialized.\n`);

The timezone and daylight saving time offset are unnecessary for many microcontroller projects. An accurate system time is enough. However, for projects which display a date or time value to the user, such as those with a display, they are essential. Fortunately, such devices typically have an interactive user interface where the user can set the timezone and daylight savings offset.

These may be set explicitly by the user or implicitly. For example, during provisioning, the timezone and daylight saving time offset might be transferred from the phone or computer used to provision.

Once the timezone and daylight saving time offset are known, they can be set for the runtime:

import Time from "time";

Time.timezone = -8 * 60 * 60;		// seconds
Time.dst = 60 * 60;		// seconds

The Time module changes the runtime values for the timezone and daylight saving offset, but does not restore them after the device restarts. To do that, use Key-Value Storage. This example saves the values.

import Time from "time";

using timeSettings = device.keyValue.open({
	path: "time",
	format: "int32"
});

timeSettings.write("timezone", Time.timezone);
timeSettings.write("dst", Time.dst);

You can restore the timezone and daylight saving offset from key-value storage. This example applies the values only if they have been set.

import Time from "time";

using timeSettings = device.keyValue.open({
	path: "time",
	format: "int32"
});

let value = timeSettings.read("timezone");
if (undefined !== value)
	Time.timezone = value;
value = timeSettings.read("dst");
if (undefined !== value)
	Time.dst = value;