Datetime
Datetimes are used to record an absolute date and time, for example the date and time that the application was first run.
The device's offset from UTC is recorded and sent with the Datetime value in the ping.
To record a single elapsed time, see Timespan. To measure the distribution of multiple timespans, see Timing Distributions.
Configuration
Datetimes have a required time_unit
parameter to specify the smallest unit of resolution that the metric will record. The allowed values for time_unit
are:
nanosecond
microsecond
millisecond
second
minute
hour
day
Carefully consider the required resolution for recording your metric, and choose the coarsest resolution possible.
You first need to add an entry for it to the metrics.yaml
file:
install:
first_run:
type: datetime
time_unit: day
description: >
Records the date when the application was first run
lifetime: user
...
API
import org.mozilla.yourApplication.GleanMetrics.Install
Install.firstRun.set() // Records "now"
Install.firstRun.set(Calendar(2019, 3, 25)) // Records a custom datetime
There are test APIs available too.
import org.mozilla.yourApplication.GleanMetrics.Install
// Was anything recorded?
assertTrue(Install.firstRun.testHasValue())
// Was it the expected value?
// NOTE: Datetimes always include a timezone offset from UTC, hence the
// "-05:00" suffix.
assertEquals("2019-03-25-05:00", Install.firstRun.testGetValueAsString())
// Was the value invalid?
assertEquals(0, Install.firstRun.testGetNumRecordedErrors(ErrorType.InvalidValue))
import org.mozilla.yourApplication.GleanMetrics.Install;
Install.INSTANCE.firstRun.set(); // Records "now"
Install.INSTANCE.firstRun.set(Calendar(2019, 3, 25)); // Records a custom datetime
There are test APIs available too:
import org.mozilla.yourApplication.GleanMetrics.Install;
// Was anything recorded?
assertTrue(Install.INSTANCE.firstRun.testHasValue());
// Was it the expected value?
// NOTE: Datetimes always include a timezone offset from UTC, hence the
// "-05:00" suffix.
assertEquals("2019-03-25-05:00", Install.INSTANCE.firstRun.testGetValueAsString());
// Was the value invalid?
assertEquals(0, Install.INSTANCE.firstRun.testGetNumRecordedErrors(ErrorType.InvalidValue));
Install.firstRun.set() // Records "now"
let dateComponents = DateComponents(
calendar: Calendar.current,
year: 2004, month: 12, day: 9, hour: 8, minute: 3, second: 29
)
Install.firstRun.set(dateComponents.date!) // Records a custom datetime
There are test APIs available too:
@testable import Glean
// Was anything recorded?
XCTAssert(Install.firstRun.testHasValue())
// Does the datetime have the expected value?
XCTAssertEqual(6, try Install.firstRun.testGetValue())
// Was the value invalid?
XCTAssertEqual(0, Install.firstRun.getNumRecordedErrors(.invalidValue))
import datetime
from glean import load_metrics
metrics = load_metrics("metrics.yaml")
# Records "now"
metrics.install.first_run.set()
# Records a custom datetime
metrics.install.first_run.set(datetime.datetime(2019, 3, 25))
There are test APIs available too.
# Was anything recorded?
assert metrics.install.first_run.test_has_value()
# Was it the expected value?
# NOTE: Datetimes always include a timezone offset from UTC, hence the
# "-05:00" suffix.
assert "2019-03-25-05:00" == metrics.install.first_run.test_get_value_as_str()
# Was the value invalid?
assert 0 == metrics.install.test_get_num_recorded_errors(
ErrorType.INVALID_VALUE
)
using static Mozilla.YourApplication.GleanMetrics.Install;
// Records "now"
Install.firstRun.Set();
// Records a custom datetime
Install.firstRun.Set(new DateTimeOffset(2018, 2, 25, 11, 10, 0, TimeZone.CurrentTimeZone.BaseUtcOffset));
There are test APIs available too:
using static Mozilla.YourApplication.GleanMetrics.Install;
// Was anything recorded?
Assert.True(Install.firstRun.TestHasValue());
// Was it the expected value?
// NOTE: Datetimes always include a timezone offset from UTC, hence the
// "-05:00" suffix.
Assert.Equal("2019-03-25-05:00", Install.firstRun.TestGetValueAsString());
// Was the value invalid?
Assert.Equal(0, Install.firstRun.TestGetNumRecordedErrors(ErrorType.InvalidValue));
use glean::ErrorType;
use glean_metrics;
use chrono::{FixedOffset, TimeZone};
// Records "now"
install::first_run.set(None);
// Records a custom datetime
let custom_date = FixedOffset::east(0).ymd(2019, 3, 25).and_hms(0, 0, 0);
install::first_run.set(Some(custom_date));
There are test APIs available too.
// Was anything recorded?
assert!(metrics.install.first_run.test_get_value(None).is_some());
// Was it the expected value?
let expected_date = FixedOffset::east(0).ymd(2019, 3, 25).and_hms(0, 0, 0);
assert_eq!(expected_date, metrics.install.first_run.test_get_value(None));
// Was the value invalid?
assert_eq!(0, install::first_run.test_get_num_recorded_errors(
ErrorType::InvalidValue
));
Note: C++ APIs are only available in Firefox Desktop.
#include "mozilla/glean/GleanMetrics.h"
PRExplodedTime date = {0, 35, 10, 12, 6, 10, 2020, 0, 0, {5 * 60 * 60, 0}};
mozilla::glean::install::first_run.Set(&date);
There are test APIs available too:
#include "mozilla/glean/GleanMetrics.h"
// Does it have the expected value?
ASSERT_STREQ(
mozilla::glean::install::first_run.TestGetValue().value(),
"2020-11-06T12:10:35+05:00"_ns
);
// Did it run across any errors?
// TODO: https://bugzilla.mozilla.org/show_bug.cgi?id=1683171
Note: JS APIs are only available in Firefox Desktop.
const value = new Date("2020-06-11T12:00:00");
Glean.install.firstRun.set(value.getTime() * 1000);
There are test APIs available too:
Assert.ok(Glean.install.firstRun.testGetValue().startsWith("2020-06-11T12:00:00"));
// Did it run across any errors?
// TODO: https://bugzilla.mozilla.org/show_bug.cgi?id=1683171
Limits
- None.
Examples
- When did the user first run the application?
Recorded errors
invalid_value
: Setting the date time to an invalid value.