pic_clock Module

Two unrelated notions of time, kept apart on purpose.

Monotonic time (monotonic_ms, monotonic_us) counts from an unspecified origin and only ever moves forward. Use it to measure how long something took, or to pace a loop against real time. Differences are meaningful; the absolute value is not.

Wall-clock time (now_local, now_utc) is the calendar date and time. Use it to stamp a log line or name an output file. It can jump backwards when the system clock is corrected, so it must never be used to measure a duration.

Relationship to pic_timer

pic_timer measures intervals and reports real(dp) seconds, which is what a benchmark wants. This module reports whole milliseconds or microseconds as integer(int64), which is what a simulation pacing itself against the wall clock wants: integers compare and accumulate exactly, so a frame budget does not drift with rounding.

Determinism

Nothing here is reproducible between runs, by definition. Code whose results must replay identically from a seed must not call any of it. format_iso8601 is the exception: it is a pure function of its argument, and it builds its text with zfill rather than internal I/O so that the bytes are identical on every compiler.


Uses

  • module~~pic_clock~~UsesGraph module~pic_clock pic_clock module~pic_error pic_error module~pic_clock->module~pic_error module~pic_strings pic_strings module~pic_clock->module~pic_strings module~pic_types pic_types module~pic_clock->module~pic_types module~pic_error->module~pic_types module~pic_global_definitions pic_global_definitions module~pic_error->module~pic_global_definitions module~pic_strings->module~pic_types iso_c_binding iso_c_binding module~pic_strings->iso_c_binding module~pic_ascii pic_ascii module~pic_strings->module~pic_ascii module~pic_optional_value pic_optional_value module~pic_strings->module~pic_optional_value module~pic_string_type pic_string_type module~pic_strings->module~pic_string_type module~pic_types->iso_c_binding iso_fortran_env iso_fortran_env module~pic_types->iso_fortran_env module~pic_ascii->module~pic_types module~pic_global_definitions->module~pic_types module~pic_optional_value->module~pic_types module~pic_string_type->module~pic_types module~pic_string_type->module~pic_ascii module~pic_string_type->module~pic_optional_value

Variables

Type Visibility Attributes Name Initial
integer(kind=int64), public, parameter :: PIC_CLOCK_NO_CLOCK = -1_int64

Returned by monotonic_ms and monotonic_us on a processor that has no clock. Zero is deliberately not used: it is a valid reading, and pic_timer already returns zero elapsed time for the same condition, which a caller cannot distinguish from “no time passed”. A negative value can never be a real monotonic reading.

integer(kind=default_int), private, parameter :: DATE_AND_TIME_VALUES = 8_default_int

Length of the VALUES array date_and_time fills: year, month, day, minutes from UTC, hour, minute, second, millisecond (F2018 16.9.59).

integer(kind=int64), private, parameter :: DAYS_EPOCH_SHIFT = 719468_int64
integer(kind=int64), private, parameter :: MS_PER_DAY = 86400000_int64

Offset between the civil-calendar epoch used by days_from_civil (0000-03-01) and the Unix epoch (1970-01-01), in days.

integer(kind=int64), private, parameter :: MS_PER_HOUR = 3600000_int64
integer(kind=int64), private, parameter :: MS_PER_MINUTE = 60000_int64
integer(kind=int64), private, parameter :: MS_PER_SECOND = 1000_int64
integer(kind=int64), private, parameter :: US_PER_SECOND = 1000000_int64

Derived Types

type, public ::  datetime_t

A broken-down calendar date and time.

Read more…

Components

Type Visibility Attributes Name Initial
integer(kind=default_int), public :: day = 1
integer(kind=default_int), public :: hour = 0
integer(kind=default_int), public :: millisecond = 0
integer(kind=default_int), public :: minute = 0
integer(kind=default_int), public :: month = 1
integer(kind=default_int), public :: second = 0
logical, public :: utc_offset_known = .true.

False when the processor could not supply an offset from UTC. The date and time are still valid; only their relation to UTC is not.

integer(kind=default_int), public :: utc_offset_min = 0
integer(kind=default_int), public :: year = 1970

Functions

public pure function datetime_from_unix_ms(ms) result(dt)

Inverse of unix_time_ms, producing a UTC datetime_t.

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: ms

Return Value type(datetime_t)

public pure function format_iso8601(dt) result(text)

ISO 8601, for example 2026-09-14T09:46:00.123Z.

Read more…

Arguments

Type IntentOptional Attributes Name
type(datetime_t), intent(in) :: dt

Return Value character(len=:), allocatable

public function monotonic_ms() result(t)

Milliseconds from an unspecified origin, or PIC_CLOCK_NO_CLOCK.

Read more…

Arguments

None

Return Value integer(kind=int64)

public function monotonic_us() result(t)

Microseconds from an unspecified origin, or PIC_CLOCK_NO_CLOCK.

Arguments

None

Return Value integer(kind=int64)

public pure function unix_time_ms(dt) result(ms)

Milliseconds since 1970-01-01T00:00:00Z.

Read more…

Arguments

Type IntentOptional Attributes Name
type(datetime_t), intent(in) :: dt

Return Value integer(kind=int64)

private pure function days_from_civil(y_in, m, d) result(days)

Days from 1970-01-01 to the given proleptic Gregorian date.

Read more…

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: y_in
integer(kind=int64), intent(in) :: m
integer(kind=int64), intent(in) :: d

Return Value integer(kind=int64)

private function monotonic_scaled(units_per_second) result(t)

Shared body of monotonic_ms and monotonic_us.

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: units_per_second

Return Value integer(kind=int64)

private pure function offset_text(offset_min) result(text)

The trailing zone designator of an ISO 8601 timestamp.

Arguments

Type IntentOptional Attributes Name
integer(kind=default_int), intent(in) :: offset_min

Return Value character(len=:), allocatable

private pure function pad(value, width) result(text)

value in decimal, zero filled on the left to width characters. A value too wide to fit is not truncated; the field simply grows.

Read more…

Arguments

Type IntentOptional Attributes Name
integer(kind=default_int), intent(in) :: value
integer, intent(in) :: width

Return Value character(len=:), allocatable


Subroutines

public subroutine now_local(dt, err)

The current local date and time.

Read more…

Arguments

Type IntentOptional Attributes Name
type(datetime_t), intent(out) :: dt
type(error_t), intent(inout), optional :: err

public subroutine now_utc(dt, err)

The current date and time in UTC, with utc_offset_min zero.

Read more…

Arguments

Type IntentOptional Attributes Name
type(datetime_t), intent(out) :: dt
type(error_t), intent(inout), optional :: err

private pure subroutine civil_from_days(days, y, m, d)

Inverse of days_from_civil.

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: days
integer(kind=int64), intent(out) :: y
integer(kind=int64), intent(out) :: m
integer(kind=int64), intent(out) :: d