Julian Date Conversion — Robotics/Coordinate Transforms
Robotics/Coordinate_Transforms/Julian_Date_Conversion · 1 input / 1 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text
Description#
The block's own DESCRIPTION_HTML, rendered verbatim — the same text the config dialog's info panel and the library navigator show. Fix a wrong sentence in the block's .cpp (R-D9), never here.
Julian Date Conversion
Robotics / Coordinate Transforms
Converts a configured calendar date and time, shifted by the time increment on its input, into a Julian date – or, with the modified flag, a modified Julian date (MJD = JD − 2400000.5). With y and m the year and month (January and February counted as months 13 and 14 of the previous year) and A = floor(y/100):
- JD = floor(365.25·(y + 4716)) + floor(30.6001·(m + 1)) + d + 2 − A + floor(A/4) − 1524.5 + (h + min/60 + s/3600)/24
The increment is added to exactly one of d, h, min and s before the conversion, chosen by Time Increment.
Ports
- Input – the time increment, a scalar [1,1] in the unit Time Increment names. It may be fractional and negative.
- Output – the Julian (or modified Julian) date in days, a scalar [1,1].
Parameters
- Year – a whole number of 1 or more; a fractional year is truncated. Defaults to 2013, as Simulink's does.
- Month – January to December. Defaults to January.
- Day – the day of the month, a whole number from 1 to 31. Defaults to 1.
- Hour – 0 up to (not including) 24; a fractional hour is truncated. Defaults to 0.
- Minutes – 0 up to (not including) 60; a fractional minute is truncated. Defaults to 0.
- Seconds – 0 up to (not including) 60, fractions kept. Defaults to 0.
- Modified Julian Date – off (the default) gives the Julian date, on the modified Julian date.
- Time Increment – the unit of the input, and so the field it is
added to:
- Day – added to the day (the default).
- Hour – added to the hour.
- Min – added to the minutes.
- Sec – added to the seconds.
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. Everything the configured date contributes that is a whole number of days is folded to one constant at export time, so a core adds the increment to its field and evaluates the fractional-day sum – in the same association Simulink uses, which is what keeps the software targets identical to the last bit.
The three HDL targets are simulation-only real
arithmetic, quantized at the port, and a Q16.16 port cannot carry a Julian
date at all: it saturates past about 32767 days, while a Julian date in the
modern era is around 2.46 million and a modified one around 61000. A hardware
export of this block is therefore only meaningful as a modified Julian date before
1948; the suite checks the HDL targets on exactly that shape and reports the
unmodified one as not comparable.
Simulink bridge
Import and export, mapped to Aerospace Blockset's
aerolibconvert2/Julian Date Conversion: Year →
year, Month → month, Day →
day, Hour → hour, Minutes →
min, Seconds → sec, Modified Julian
Date → modflag and Time Increment →
deltaT, every combo 1:1. Simulink's fifth increment value,
None, is not offered: it removes that block's input port, and a port
list here is fixed, so an imported None is reported rather than
mapped. errorflag is always emitted as None: this block
never stops a run over the increment's range. "Sampling Time (s)" does not
cross: the Simulink block defines no SampleTime parameter,
measured on R2026a.
Notes
- Stateless and algebraic: the output depends only on this sample's increment.
- The Gregorian rule is applied to every year, before 1582 included, exactly as the Simulink block does.
- A day number beyond the month's end is not an error: an increment that pushes the day past the 28th of February simply lands in March.
Code facts#
| Fact | Value |
|---|---|
| registered type | Robotics/Coordinate_Transforms/Julian_Date_Conversion |
| family | Robotics/Coordinate_Transforms |
| solver environment class | ICoreBlock_0_Robotics_1_Coordinate_Transforms_2_Julian_Date_Conversion |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Coordinate_Transforms/Julian_Date_Conversion/ICoreBlock_0_Robotics_1_Coordinate_Transforms_2_Julian_Date_Conversion.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Coordinate_Transforms/Julian_Date_Conversion/ICoreBlock_0_Robotics_1_Coordinate_Transforms_2_Julian_Date_Conversion.h |
| default size on canvas | 120 × 80 px |
| ports at insert | 1 in, 1 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | in | ICoreDouble | — |
| 2 | out | ICoreDouble | — |
Ports the constructor creates. A block whose port list changes with its configuration adds or removes ports at load time; the count above is the one a freshly inserted block has.
Configuration variables#
| Config variable | Default | Simulink parameter |
|---|---|---|
Year | 2013 | year |
Month | monthCombo() | month |
Day | 1 | day |
Hour | 0 | hour |
Minutes | 0 | min |
Seconds | 0 | sec |
Modified Julian Date | off%~%on~~off | modflag |
Time Increment | Day%~%Hour%~%Min%~%Sec~~Day | deltaT |
Every block also carries Sampling Time (s) from ICoreBlockSolverEnvironment: zero or less inherits the solver's rate, a positive value runs the block at that period.
Simulink bridge#
| support | Support::Both |
| Simulink path | aerolibconvert2/Julian Date Conversion |
| port-count rule | PortsParam::None |
SampleTime parameter | no — the counterpart defines none; the rate stays on the ICore side |
| always set | errorflag = None |
| ICore config | Simulink parameter | Value translation |
|---|---|---|
Year | year | passes through |
Month | month | passes through |
Day | day | passes through |
Hour | hour | passes through |
Minutes | min | passes through |
Seconds | sec | passes through |
Modified Julian Date | modflag | off → off, on → on |
Time Increment | deltaT | Day → Day, Hour → Hour, Min → Min, Sec → Sec |
Caveat (shown to the user): aerolibconvert2/Julian Date Conversion has NO SampleTime parameter (verified against the R2026a block dialog), so "Sampling Time (s)" does not cross. Its deltaT value 'None' removes the block's input port and is not offered here; 'errorflag' is pinned to None because this block never stops a run over the increment's range
Catalog contract: src/ICoreBlocks/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h
Description vs code#
The lists agree. check_block_descriptions.py finds no disagreement between the description's Ports, Parameters, Code export and Simulink bridge lists and the code's.
The verdict above is
tools/docs/check_block_descriptions.py(P7.1), which compares LISTS. It cannot read a sentence: "stateless" on a block with a state, an initial-value semantic the recursion does not implement, a "not synthesizable" caveat the HDL banner contradicts. That is the agent audit (P7.3) on BLOCK_DESCRIPTION_AUDIT.md, and this tool's green is not a substitute for one.
File banner (developer view)#
The top comment of the block's .cpp — the maths, the realization and the export strategy, addressed to whoever changes it. It must not contradict the description above (P7.5).
Julian Date Conversion — a configured date, shifted by the input, as a (modified) Julian date For month <= 2 take y - 1 and m + 12, then (Meeus, and exactly the masked subsystem's wiring):
K = floor(365.25 (y + B)) + floor(30.6001 (m + 1)) + 2 - A + floor(A / 4), A = floor(y/100) JD = ((K + day) + D) + ((hour + min*(1/60)) + sec*(1/3600)) * (1/24)
with B = 4716, D = -1524.5 for a Julian date, and B = 0, D = -679006 for a MODIFIED one. The input is a time increment added to ONE of day / hour / min / sec before any of that.
⚠ MEASURED AGAINST R2026a -- every Gain, Bias, Rounding Function, If and Sum of aerolibconvert2/Julian Date Conversion read out of the masked subsystem, then the chain above reproduced the block BIT FOR BIT at 1903-02-27 13:41:17.25 with an increment of 1.37 in each of the four units, both flags (eight values, all ==). Three things that measurement settled and a paraphrase gets wrong:
- floor(floor(y/100)/4) is TWO floors; the mask has two Rounding Functions on that arm.
- y/100 is y*(1/100) -- a Gain of 1/100, not a division -- and the fractional day is
((hour + min*(1/60)) + sec*(1/3600))*(1/24) in THAT association. Every product is by the double the Gain holds, which is what makes the software targets agree to the last bit.
- The modified flag rewrites two biases (4716 -> 0, -1524.5 -> -679006) rather than
subtracting 2400000.5 at the end, so the large offset never touches the fraction.
K is a whole number and a constant of the configuration, so it is folded at export time; the emitted arithmetic is the second line alone, with the increment added to its one field.
Sample results#
| t | in ICoreDouble-Out-0 | out ICoreDouble-Out-0 |
|---|---|---|
| 0 | -2 | 2.456e6 |
| 0.4 | 0.5 | 2.456e6 |
| 0.8 | -2 | 2.456e6 |
| 1.2 | 0.5 | 2.456e6 |
| 1.6 | -2 | 2.456e6 |
| 2 | 0.5 | 2.456e6 |
| 2.4 | -2 | 2.456e6 |
| 2.8 | 0.5 | 2.456e6 |
| 3.2 | -2 | 2.456e6 |
| 3.6 | 0.5 | 2.456e6 |
| 4 | -2 | 2.456e6 |
| 4.4 | 0.5 | 2.456e6 |
| 4.8 | -2 | 2.456e6 |
| 5.2 | 0.5 | 2.456e6 |
Every 4th of 60 samples, from the table stimulus.
The same rig also ran:
| Stimulus | What it is | Output range |
|---|---|---|
impulse | Impulse: one sample of 1 at k = 5, 0 elsewhere (Repeating Sequence Stair) | 2.456e6 … 2.456e6 |
ramp | Ramp: slope 1 from t = 0 | 2.456e6 … 2.456e6 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | 2.456e6 … 2.456e6 |
step | Step: 0 -> 1 at t = 1 s | 2.456e6 … 2.456e6 |
Plotted: table — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample
Category static · sample time 0.1 · 60 steps · commit fc85ac64df179e0aadfcbe797a2731524d14cbb9 · produced by docsSample --out <folder> --blocks Linear_Second_Order_Actuator Nonlinear_Second_Order_Actuator Wind_Shear_Model Discrete_Wind_Gust_Model Julian_Date_Conversion --steps 60 · data docs/generated/samples/Robotics__Coordinate_Transforms__Julian_Date_Conversion.json · the SVG is generated from those numbers by tools/docs/plot_svg.py, so it is a run and not a drawing (R-D10).