Install
$ agentstack add skill-impertio-studio-cesiumjs-claude-skill-package-cesium-syntax-time ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
CesiumJS Time and Clock
Overview
CesiumJS is time-dynamic. A Clock advances a simulation time each frame, and Property objects evaluate their value at that time. JulianDate is the time type. SampledPositionProperty interpolates a position between time-stamped samples. TimeIntervalCollection defines when an entity exists.
Core principle: ALWAYS represent simulation time as a JulianDate, NEVER a JavaScript Date or a raw number. An animation advances ONLY when viewer.clock.shouldAnimate is true.
When to Use This Skill
Use this skill when ANY of these apply:
- An entity with a time-varying position does not move
- An animation is added but stays frozen
- A clock or timeline shows the wrong time
- A
SampledPositionPropertyreturnsundefinedor the wrong position - Choosing an interpolation algorithm for a track
- Controlling when an entity is visible with
availability
Do NOT use this skill for glTF model animation playback detail; that is cesium-syntax-gltf-model. Do NOT use it for the Property abstraction or CallbackProperty; that is cesium-syntax-entity. Both skills share the clock described here.
JulianDate: the time type
JulianDate stores whole days and seconds-of-day separately, internally in International Atomic Time (TimeStandard.TAI). That storage makes its arithmetic leap-second-safe. NEVER build a JulianDate from raw day numbers by hand; ALWAYS use a factory.
const fromIso = Cesium.JulianDate.fromIso8601("2026-05-20T14:30:00Z");
const fromJsDate = Cesium.JulianDate.fromDate(new Date());
const rightNow = Cesium.JulianDate.now();
ALWAYS parse ISO 8601 strings with JulianDate.fromIso8601. It accepts every ISO 8601 form and is correct where Date.parse is unreliable.
JulianDate arithmetic uses static methods that write into a result argument and return it. They do NOT change their input.
const start = Cesium.JulianDate.fromIso8601("2026-05-20T00:00:00Z");
const oneHourLater = Cesium.JulianDate.addSeconds(
start,
3600,
new Cesium.JulianDate(),
);
const order = Cesium.JulianDate.compare(start, oneHourLater); // negative
const gapSeconds = Cesium.JulianDate.secondsDifference(oneHourLater, start);
NEVER add time by writing to secondsOfDay directly; that field does not roll over into dayNumber. ALWAYS use JulianDate.addSeconds, addMinutes, addHours, or addDays.
| Method | Purpose | |--------|---------| | JulianDate.fromIso8601(str, result) | Parse an ISO 8601 string | | JulianDate.fromDate(date, result) | Convert a JavaScript Date | | JulianDate.now(result) | Current system time | | JulianDate.addSeconds(date, seconds, result) | Offset by seconds | | JulianDate.compare(left, right) | Sort order, negative or positive | | JulianDate.secondsDifference(left, right) | Elapsed seconds | | JulianDate.toIso8601(date, precision) | Format back to a string | | JulianDate.clone(date, result) | Independent copy |
Clock: driving simulation time
A Clock advances simulation time. The Viewer owns one, reachable as viewer.clock.
const viewer = new Cesium.Viewer("cesiumContainer");
const start = Cesium.JulianDate.fromIso8601("2026-05-20T00:00:00Z");
const stop = Cesium.JulianDate.addSeconds(start, 3600, new Cesium.JulianDate());
viewer.clock.startTime = start;
viewer.clock.stopTime = stop;
viewer.clock.currentTime = Cesium.JulianDate.clone(start);
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
viewer.clock.multiplier = 60; // 60 simulated seconds per real second
viewer.clock.shouldAnimate = true;
viewer.timeline.zoomTo(start, stop);
shouldAnimate is false by default. NEVER expect a track or animation to move until viewer.clock.shouldAnimate is true, or shouldAnimate: true is passed to the Viewer constructor.
ALWAYS assign currentTime a JulianDate.clone of startTime. The clock mutates its currentTime object on each tick; a shared reference would corrupt startTime.
ClockRange controls behavior when currentTime reaches stopTime:
| Value | Behavior at stopTime | |-------|----------------------| | UNBOUNDED | Keeps advancing past stopTime (default) | | CLAMPED | Stops at stopTime, playback halts | | LOOP_STOP | Jumps back to startTime and replays |
ClockStep controls how much time each tick() adds:
| Value | tick advances by | |-------|------------------| | SYSTEM_CLOCK_MULTIPLIER | Real elapsed time times multiplier (default) | | TICK_DEPENDENT | A fixed multiplier seconds per frame | | SYSTEM_CLOCK | The real system time, multiplier ignored |
ALWAYS use TICK_DEPENDENT for deterministic, frame-rate-independent playback, such as a recorded video export.
ClockViewModel
ClockViewModel is the binding layer between a Clock and the Animation and Timeline widgets. The Viewer creates one; reach it as viewer.clockViewModel. Construct a standalone one with new Cesium.ClockViewModel(clock), where the Clock argument is optional. Call synchronize() to refresh the view model after changing the underlying clock outside the tick loop.
SampledPositionProperty: time-dynamic position
A SampledPositionProperty holds time-stamped positions and interpolates between them. Assign it to entity.position and the entity moves as the clock advances.
const positionProperty = new Cesium.SampledPositionProperty();
const samples = [
{ time: "2026-05-20T00:00:00Z", lon: 4.9, lat: 52.37, height: 1000 },
{ time: "2026-05-20T00:10:00Z", lon: 4.95, lat: 52.4, height: 1500 },
{ time: "2026-05-20T00:20:00Z", lon: 5.0, lat: 52.45, height: 1200 },
];
for (const s of samples) {
positionProperty.addSample(
Cesium.JulianDate.fromIso8601(s.time),
Cesium.Cartesian3.fromDegrees(s.lon, s.lat, s.height),
);
}
const aircraft = viewer.entities.add({
position: positionProperty,
point: { pixelSize: 12, color: Cesium.Color.YELLOW },
path: { width: 2, material: Cesium.Color.CYAN },
});
viewer.trackedEntity = aircraft;
A SampledPositionProperty with one sample is constant; it can NEVER interpolate. ALWAYS add two or more samples for motion.
The constructor is new Cesium.SampledPositionProperty(referenceFrame, numberOfDerivatives). referenceFrame defaults to ReferenceFrame.FIXED. Set numberOfDerivatives to 1 ONLY when you also pass velocity vectors as the third addSample argument and intend to use Hermite interpolation.
Interpolation algorithms
By default a sampled property uses LinearApproximation at interpolationDegree 1. Change it with setInterpolationOptions.
positionProperty.setInterpolationOptions({
interpolationAlgorithm: Cesium.LagrangePolynomialApproximation,
interpolationDegree: 2,
});
| Algorithm | Use for | Samples needed | |-----------|---------|----------------| | LinearApproximation | Straight segments, the default | Degree 1 needs 2 | | LagrangePolynomialApproximation | Smooth curved paths | Degree N needs N+1 | | HermitePolynomialApproximation | Paths with known velocity data | Degree N needs N+1 |
ALWAYS keep interpolationDegree below the in-range sample count. A LagrangePolynomialApproximation at degree 5 needs at least 6 samples around the query time; with fewer, CesiumJS falls back to a lower degree and the curve is not the one configured. HermitePolynomialApproximation is correct ONLY when the property carries derivatives (numberOfDerivatives is above 0).
Extrapolation
Outside the sample range a sampled property extrapolates according to forwardExtrapolationType and backwardExtrapolationType. Both default to ExtrapolationType.NONE.
| ExtrapolationType | Value outside the sample range | |---------------------|--------------------------------| | NONE | The property returns undefined (default) | | HOLD | The first or last sample value is held | | EXTRAPOLATE | The value is projected from the trend |
A track that vanishes before its first sample or after its last is the default NONE behavior. Set HOLD to park the entity at its endpoint.
positionProperty.forwardExtrapolationType = Cesium.ExtrapolationType.HOLD;
positionProperty.backwardExtrapolationType = Cesium.ExtrapolationType.HOLD;
TimeIntervalCollection and Entity.availability
A TimeIntervalCollection is a sorted, non-overlapping set of TimeIntervals. Assign one to entity.availability and the entity is shown ONLY while the clock is inside an interval.
const availability = new Cesium.TimeIntervalCollection([
Cesium.TimeInterval.fromIso8601({
iso8601: "2026-05-20T00:05:00Z/2026-05-20T00:18:00Z",
}),
]);
aircraft.availability = availability;
Build intervals from ISO 8601 with TimeInterval.fromIso8601 for a single interval, or TimeIntervalCollection.fromIso8601 for a start, stop, or duration spec. A TimeInterval exposes isStartIncluded and isStopIncluded, both default true.
An entity whose availability excludes the current clock time is hidden even when its position is valid. When an entity will not appear during playback, ALWAYS check availability against viewer.clock.currentTime.
Decision: which time property
digraph time_property {
rankdir=TB;
node [shape=box, fontname="Helvetica"];
start [label="A value that changes over time"];
q_pos [shape=diamond, label="Is the value a position\non the globe?"];
q_step [shape=diamond, label="Does the value jump\nbetween fixed states?"];
use_spp [label="SampledPositionProperty\n(interpolated motion)"];
use_sp [label="SampledProperty\n(interpolated scalar or vector)"];
use_tivp [label="TimeIntervalCollectionProperty\n(discrete, no interpolation)"];
start -> q_pos;
q_pos -> use_spp [label="yes"];
q_pos -> q_step [label="no"];
q_step -> use_tivp [label="yes"];
q_step -> use_sp [label="no, it interpolates"];
}
For controlling visibility windows rather than a value, use a TimeIntervalCollection on entity.availability.
Common Mistakes
| Mistake | Consequence | Fix | |---------|-------------|-----| | shouldAnimate left false | Clock and every track frozen | Set viewer.clock.shouldAnimate = true | | One sample in a SampledPositionProperty | Entity never moves | Add two or more samples | | interpolationDegree at or above sample count | Silent fallback, wrong curve | Keep degree below the in-range sample count | | Hermite without derivatives | Interpolation wrong or throws | Use Linear or Lagrange, or pass derivatives | | Query outside samples with NONE | Track disappears at the ends | Set forwardExtrapolationType and backward to HOLD | | availability excludes currentTime | Entity hidden though position is valid | Widen the TimeIntervalCollection | | Date.parse for ISO 8601 strings | Wrong or invalid time | Use JulianDate.fromIso8601 | | Writing to secondsOfDay to add time | No day rollover, wrong date | Use JulianDate.addSeconds | | clockRange CLAMPED then expecting a loop | Playback stops at stopTime | Use ClockRange.LOOP_STOP | | Shared JulianDate for startTime and currentTime | Clock tick corrupts startTime | Assign a JulianDate.clone to currentTime |
Reference Files
references/methods.md: the fullJulianDate,Clock,ClockViewModel,
SampledPositionProperty, SampledProperty, TimeIntervalCollection, and TimeInterval API, with enum members.
references/examples.md: complete recipes for an animated track, a looping
clock, interpolation tuning, extrapolation, and availability windows.
references/anti-patterns.md: each time failure with symptom, root cause,
and fix.
Related Skills
cesium-syntax-entity: thePropertyabstraction,CallbackProperty, and
path graphics that visualize a track.
cesium-syntax-gltf-model: glTF model animations driven by this same clock.cesium-core-coordinates:Cartesian3positions used as samples.cesium-syntax-viewer: the Animation and Timeline widgets on theViewer.cesium-syntax-datasources: CZML, the time-dynamic data format.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Impertio-Studio
- Source: Impertio-Studio/CesiumJS-Claude-Skill-Package
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.