Time
Generates times of day, with no date.
Use it for a time that is the same on any day, such as an opening time, a shift start, an appointment
slot or a scheduled run. A time of day is on a 24-hour clock, so a sequence of times continues past
midnight from 00:00:00, and a window can run through midnight.
For a time with a date, use DateTime, or Timestamp for a value with
a UTC offset. For a duration, use Interval. For a start time and an end time, use
TimeRange.
Sub-field: value
Every JSON block on this page is a single field object, one entry in a table's fields array.
See Building a Request for the full request structure.
Properties
| Property | Type | Default | Description |
|---|---|---|---|
cultureLong |
string? |
none | A culture name, such as fr-FR, whose long time format is used for the value. en-US produces 1:05:00 PM. Produces text. Cannot be combined with exactFormat or cultureShort. See Formatting the output. |
cultureShort |
string? |
none | A culture name, such as fr-FR, whose short time format is used for the value. en-US produces 1:05 PM. Produces text. Cannot be combined with exactFormat or cultureLong. See Formatting the output. |
exactFormat |
string? |
none | A custom time format string, such as hh:mm tt. Produces text. Cannot be combined with cultureShort or cultureLong. See Formatting the output. |
lookupValues |
LookupValue[] |
none | The times for Lookup mode. Required in that mode. |
map |
object |
required | Maps the value sub-field to a destination column. See Building a Request and Formatting the output. |
max |
string? (time) |
23:59:59 |
Inclusive end of the window. Random and Clustered only. Earlier than min for a window through midnight. See Windows through midnight. |
mean |
string? (time) |
none | The center of the distribution in Clustered mode. Required in that mode, and must be within min to max. |
min |
string? (time) |
00:00:00 |
Inclusive start of the window. Random and Clustered only. |
mode |
"Sequential" / "Random" / "Lookup" / "Clustered" |
"Sequential" |
How values are generated. See Modes. |
nullPercentageMax |
number |
0 |
Upper bound (0-100) of the percentage of rows that should be null. See nullPercentageMin. |
nullPercentageMin |
number |
0 |
Lower bound (0-100) of the percentage of rows that should be null. The rate is fixed once for the whole field from this range, not recalculated per row. Set equal to nullPercentageMax for an exact rate. Has no effect in Sequential mode. |
percentInRange |
number? |
none | Percentage (0-100) of rows generated from percentMin to percentMax instead of the full window. Random only, and rejected in any other mode. See Random within a narrower window. |
percentMax |
string? (time) |
none | End of the window percentInRange applies to. Required with percentInRange, and must be within min to max. |
percentMin |
string? (time) |
none | Start of the window percentInRange applies to. Required with percentInRange, and must be within min to max. |
seed |
integer |
random | Per-field seed, overriding the request's own seed for this field only. |
start |
string? (time) |
00:00:00 |
The first row's value. Sequential only. |
stdDev |
number? |
none | The standard deviation of the distribution in Clustered mode, in seconds. Required in that mode, and must be greater than 0. |
stepMinutes |
number? |
none | Minutes added on each row in Sequential mode, together with stepSeconds. See Steps. |
stepSeconds |
number? |
none | Seconds added on each row in Sequential mode, together with stepMinutes. See Steps. |
unique |
boolean |
false |
Whether every generated value must differ from the others. See Unique times. |
Modes
Sequentialincreases by a fixed step. The first row isstart, and each row after it is one step later, continuing past midnight from00:00:00. The values are not random, so the same request always produces the same times, with or without aseed.Randomgenerates each row independently, with every whole second frommintomaxequally likely.percentInRangeconcentrates a percentage of the rows in a narrower window.Lookupselects from the times inlookupValues, optionally weighted. It never produces a time that is not in the list. See LookupValue.Clusteredgenerates a normal distribution aroundmean, withstdDevsetting its width. See Clustered distribution.
Properties by mode
A property that applies only to another mode is ignored, except percentInRange, which is rejected
outside Random.
| Property | Sequential | Random | Lookup | Clustered |
|---|---|---|---|---|
start, stepMinutes, stepSeconds |
Yes | |||
min, max |
Yes | Yes | ||
percentInRange, percentMin, percentMax |
Yes | |||
lookupValues |
Yes | |||
mean, stdDev |
Yes | |||
exactFormat, cultureShort, cultureLong |
Yes | Yes | Yes | Yes |
nullPercentageMin, nullPercentageMax |
Yes | Yes | Yes |
Sequential mode never produces nulls. Use another mode for a column with null values.
Each mode checks its own settings before any row is generated, so a missing mean or an empty
lookupValues list is rejected immediately.
Steps
stepMinutes and stepSeconds are added together, so stepMinutes: 1 with stepSeconds: 30 is a step
of 90 seconds. With neither set, the step is one second. The total must be a whole number of seconds,
because a time is written to the second. A step of 0 repeats start on every row, and a negative step
counts down.
A sequence continues past midnight: one second after 23:59:59 is 00:00:00, and counting down from
00:00:00 continues at 23:59:59.
LookupValue
Lookup mode selects from a list of times. Each entry is an object with a value and an optional
weight:
| Property | Type | Default | Description |
|---|---|---|---|
value |
string (time) |
required | The time. |
weight |
number |
1 |
The entry's weight relative to the other entries in the list. Must be greater than 0. |
Weights are relative, not percentages, so they do not need to total any particular number. 3 and 1
give the same distribution as 30 and 10: the first entry is selected three times as often as the
second. With no weights set, every entry is equally likely.
The list must contain at least one entry.
A departure time from a timetable, with the two morning departures the most frequent:
{
"type": "Time",
"mode": "Lookup",
"lookupValues": [
{ "value": "07:30:00", "weight": 3 },
{ "value": "08:00:00", "weight": 3 },
{ "value": "12:15:00" },
{ "value": "17:45:00", "weight": 2 }
],
"seed": 1,
"map": { "value": { "column": "departure", "dataType": "Time" } }
}
Sample output:
| departure |
|---|
| 07:30:00 |
| 07:30:00 |
| 08:00:00 |
| 12:15:00 |
| 08:00:00 |
| 08:00:00 |
| 08:00:00 |
| 17:45:00 |
The weights total 9, so each morning departure is selected for about a third of the rows, 17:45:00 for
about two rows in nine, and 12:15:00 for about one row in nine. Each row is selected separately, so the
proportions are approximate.
Clustered distribution
mean, stdDev, min and max affect the output. The curve is the number of rows with each value. Most values are near mean, and fewer are further away, at a rate set by stdDev. A value beyond min or max is set to that boundary, shown by the solid bar at each one.mean sets the center and stdDev sets the width, both in the field's own units. About 68% of values
are within one stdDev of mean, about 95% within two, and about 99.7% within three. A larger
stdDev spreads the values further from mean, and a smaller one keeps them closer to it.
min and max are optional. Without them, a value can be any distance from mean within the range
the field supports. With them, a value outside the range is set to the nearer of min or max. It is
not generated again. The solid bars in the diagram are these values.
When the range is narrow relative to stdDev, many rows have a value of exactly min or max. In the
diagram, the range is one and a half standard deviations either side of mean. To reduce the number of
rows on the boundaries, widen the range or reduce stdDev.
For a Time field, mean is a time of day and stdDev is a number of seconds. With a stdDev of 1800,
about 95% of rows are within an hour of mean.
Without min and max, the window is the whole day from 00:00:00 to 23:59:59. A value is not
continued past midnight, so with a mean close to midnight, a value that would be past midnight is
00:00:00 or 23:59:59. For a distribution around midnight, set a window through midnight. See
Windows through midnight.
Random within a narrower window
percentInRange generates a percentage of the rows of a Random field from a narrower window, and the
rest from the full window. percentMin and percentMax set the narrower window, which must be within
min to max.
For each row, the field first selects either the narrower window, with a probability of
percentInRange, or the full window from min to max. It then generates a time from the selected
window, with every second equally likely.
The rows generated from the full window can also be in the narrower window, so the proportion of rows in
it is higher than percentInRange. With percentInRange set to 70 and office hours as the narrower
window, about seven rows in ten are generated from office hours, and some of the remaining rows are in
office hours too.
Windows through midnight
min can be later in the day than max. The window then runs from min, through midnight, to max.
{
"type": "Time",
"mode": "Random",
"min": "21:00:00",
"max": "03:00:00",
"map": { "value": { "column": "shift_time", "dataType": "Time" } }
}
Sample output:
| shift_time |
|---|
| 22:51:05 |
| 23:07:13 |
| 01:25:10 |
| 21:18:40 |
| 22:24:59 |
| 23:10:36 |
The window is the six hours from 9 PM to 3 AM. With min and max the other way round, the window is the
eighteen hours from 3 AM to 9 PM.
In a window through midnight, mean, percentMin and percentMax are measured from min. A mean of
00:30:00 in a window from 21:00:00 to 03:00:00 has values on both sides of midnight, and percentMin
and percentMax can set a narrower window that also runs through midnight.
Unique times
With unique set, every row has a different time. A request for more rows than the field can produce is
rejected before any data is generated, stating how many are available:
| Mode | Distinct times available |
|---|---|
Sequential |
The steps around the clock before a time repeats: 86,400 for a step of one second, 4 for a step of six hours. Only one when the step is 0. |
Random |
The number of whole seconds from min to max. |
Clustered |
The number of seconds from min to max. |
Lookup |
The number of different times in lookupValues. |
With exactFormat, cultureShort or cultureLong set, two times can produce the same text, so there is
no fixed limit, and a request that runs out of distinct values is rejected during generation.
In Clustered mode, times far from mean are rare. A unique request close to the limit can run out of
distinct values during generation, even when the limit is not exceeded.
Formatting the output
Without a formatting property, value is a time and must be mapped to a Time column. The time is
written in the request's csvFormat.timeFormat. See CSV formatting.
exactFormat, cultureShort and cultureLong produce text instead, and a field that sets one must be
mapped to a text column such as VarChar. Only one of the three can be set.
exactFormattakes a custom time format string. The output is the same for every request. A format with a date part, such asyyyy, is rejected. See Custom date and time format strings for the format specifiers.cultureShortandcultureLongtake a culture name and write the time in that culture's short or long time format. The short format has no seconds. See Culture names for how the names are formed. An unknown culture name is rejected.
Examples
Each example below is a single field object, one entry in a table's fields array within a full
request, not a complete request on its own. See Building a Request for how it fits
into a full DatasetRequest.
Appointment slots every 15 minutes
{
"type": "Time",
"mode": "Sequential",
"start": "09:00:00",
"stepMinutes": 15,
"map": { "value": { "column": "slot_time", "dataType": "Time" } }
}
Sample output:
| slot_time |
|---|
| 09:00:00 |
| 09:15:00 |
| 09:30:00 |
| 09:45:00 |
| 10:00:00 |
| 10:15:00 |
A sequence through midnight
Six hours between rows from 9 PM, so the second row is 3 AM.
{
"type": "Time",
"mode": "Sequential",
"start": "21:00:00",
"stepMinutes": 360,
"map": { "value": { "column": "watch_start", "dataType": "Time" } }
}
Sample output:
| watch_start |
|---|
| 21:00:00 |
| 03:00:00 |
| 09:00:00 |
| 15:00:00 |
| 21:00:00 |
| 03:00:00 |
A random time of day
Without min and max, every second of the day is equally likely.
{
"type": "Time",
"mode": "Random",
"map": { "value": { "column": "alarm_time", "dataType": "Time" } }
}
Sample output:
| alarm_time |
|---|
| 17:21:50 |
| 13:24:35 |
| 13:37:07 |
| 09:51:04 |
| 01:49:06 |
| 10:51:08 |
Mostly office hours
{
"type": "Time",
"mode": "Random",
"percentInRange": 70,
"percentMin": "09:00:00",
"percentMax": "17:30:00",
"seed": 2,
"map": { "value": { "column": "logged_at", "dataType": "Time" } }
}
Sample output:
| logged_at |
|---|
| 00:24:28 |
| 18:34:09 |
| 11:08:31 |
| 12:19:57 |
| 16:23:48 |
| 15:17:49 |
Lunch orders clustered around noon
{
"type": "Time",
"mode": "Clustered",
"mean": "12:00:00",
"stdDev": 1800,
"min": "11:00:00",
"max": "14:00:00",
"map": { "value": { "column": "order_time", "dataType": "Time" } }
}
Sample output:
| order_time |
|---|
| 12:03:30 |
| 12:00:17 |
| 12:47:41 |
| 12:25:20 |
| 12:18:29 |
| 11:30:34 |
A 12-hour clock as text
{
"type": "Time",
"mode": "Random",
"min": "08:00:00",
"max": "20:00:00",
"exactFormat": "h:mm tt",
"map": { "value": { "column": "opens_at", "dataType": "VarChar" } }
}
Sample output:
| opens_at |
|---|
| 10:35 AM |
| 7:24 PM |
| 12:11 PM |
| 1:46 PM |
| 3:10 PM |
| 10:56 AM |
Null rows
{
"type": "Time",
"mode": "Random",
"min": "06:00:00",
"max": "22:00:00",
"nullPercentageMin": 20,
"nullPercentageMax": 20,
"seed": 2,
"map": { "value": { "column": "collected_at", "dataType": "Time" } }
}
Sample output:
| collected_at |
|---|
| 20:36:09 |
| 19:55:59 |
| 18:47:57 |
| 07:30:16 |