Generated reference › Julian Date Conversion — Robotics/Coordinate Transforms
kind: generated#block#robotics-coordinate-transforms

Julian Date Conversion — Robotics/Coordinate Transforms

JD

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#

FactValue
registered typeRobotics/Coordinate_Transforms/Julian_Date_Conversion
familyRobotics/Coordinate_Transforms
solver environment classICoreBlock_0_Robotics_1_Coordinate_Transforms_2_Julian_Date_Conversion
sourcesrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Coordinate_Transforms/Julian_Date_Conversion/ICoreBlock_0_Robotics_1_Coordinate_Transforms_2_Julian_Date_Conversion.cpp
headersrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Coordinate_Transforms/Julian_Date_Conversion/ICoreBlock_0_Robotics_1_Coordinate_Transforms_2_Julian_Date_Conversion.h
default size on canvas120 × 80 px
ports at insert1 in, 1 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1inICoreDouble—
2outICoreDouble—

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 variableDefaultSimulink parameter
Year2013year
MonthmonthCombo()month
Day1day
Hour0hour
Minutes0min
Seconds0sec
Modified Julian Dateoff%~%on~~offmodflag
Time IncrementDay%~%Hour%~%Min%~%Sec~~DaydeltaT

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.

supportSupport::Both
Simulink pathaerolibconvert2/Julian Date Conversion
port-count rulePortsParam::None
SampleTime parameterno — the counterpart defines none; the rate stays on the ICore side
always seterrorflag = None
ICore configSimulink parameterValue translation
Yearyearpasses through
Monthmonthpasses through
Daydaypasses through
Hourhourpasses through
Minutesminpasses through
Secondssecpasses through
Modified Julian Datemodflagoff → off, on → on
Time IncrementdeltaTDay → 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#

Julian Date Conversion — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sampleJulian Date Conversion — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample2.456e62.456e62.456e6-2-10123inputoutput
tin ICoreDouble-Out-0out ICoreDouble-Out-0
0-22.456e6
0.40.52.456e6
0.8-22.456e6
1.20.52.456e6
1.6-22.456e6
20.52.456e6
2.4-22.456e6
2.80.52.456e6
3.2-22.456e6
3.60.52.456e6
4-22.456e6
4.40.52.456e6
4.8-22.456e6
5.20.52.456e6

Every 4th of 60 samples, from the table stimulus.

The same rig also ran:

StimulusWhat it isOutput range
impulseImpulse: one sample of 1 at k = 5, 0 elsewhere (Repeating Sequence Stair)2.456e6 … 2.456e6
rampRamp: slope 1 from t = 02.456e6 … 2.456e6
sineSine Wave: amplitude 1, 2 rad/s, no phase, no bias2.456e6 … 2.456e6
stepStep: 0 -> 1 at t = 1 s2.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).