---
title: Convert a Julian date string to a DateTime
summary: Decode a Julian-format date string into a DateTime.
status: draft
owner: saif-docgen
last_reviewed: 2026-09-15
library: SAIF.Framework.Common
reference_type: package
operation_id: OP-007
trigger: Caller decodes a Julian-formatted date from a fixed-format interchange file*
---

# Convert a Julian date string to a DateTime

Decode a Julian-format date string into a DateTime, triggered when caller decodes a Julian-formatted date from a fixed-format interchange file*.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-007 |
| **Trigger** | Caller decodes a Julian-formatted date from a fixed-format interchange file* |
| **Inputs** | `julian` (e.g. `25001`, `2025001`), optional `millenium` |
| **Outputs** | `DateTime` |
| **Primary components** | ``SAIF.Common.Julian.ToDate(string julian, int millenium = 0)`` |
| **Entry point** | `Common/SAIF.Common/Classes/Julian.cs` |

## Steps

1. Call `IsValid(julian, out message)`; that overload converts the string to `Int32` inside a try/catch (returning `false` on conversion failure), then requires the numeric form to have more than 3 digits. ([BR-022](../business-rules.md#br-022-a-julian-date-must-contain-at-least-4-digits), [BR-023](../business-rules.md#br-023-a-julian-string-that-cannot-be-converted-to-int32-is-invalid))
2. If invalid, throw `ApplicationException(message)` — either "The julian must contain at least 4 numbers" or an empty message when the numeric conversion failed. ([BR-022](../business-rules.md#br-022-a-julian-date-must-contain-at-least-4-digits), [BR-023](../business-rules.md#br-023-a-julian-string-that-cannot-be-converted-to-int32-is-invalid))
3. Call `GetYear(julian, out isLeapYear, millenium)` (OP-008) to resolve the calendar year and its leap status. ([BR-024](<../business-rules.md#br-024-when-no-millennium-is-supplied-(or-it-is-below-1000)%2C-the-millennium-is-derived-from-the-current-system-year's-first-digit-x-1000%2C-and-a-1--or-2-digit-julian-year-is-offset-by-it>), [BR-025](<../business-rules.md#br-025-leap-year-status-is-determined-using-the-julian-calendar-(system.globalization.juliancalendar)%2C-not-the-gregorian-calendar>))
4. Set the valid day count to 366 for a leap year, otherwise 365. ([BR-025](<../business-rules.md#br-025-leap-year-status-is-determined-using-the-julian-calendar-(system.globalization.juliancalendar)%2C-not-the-gregorian-calendar>))
5. Parse the last three characters of the input as the day-of-year.
6. If the day-of-year exceeds the valid day count, throw `ApplicationException("The julian day must be < {validDaysInYear}.")`. ([BR-026](../business-rules.md#br-026-the-day-of-year-portion-of-a-julian-date-must-not-exceed-365%2C-or-366-in-a-leap-year))
7. Return `new DateTime(year, 1, 1).AddDays(dayOfYear - 1)`.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([ToDate called]) --> S1["Call IsValid(julian,<br>out message)"]
	S1 --> D1{"Julian string<br>valid?"}
	D1 -->|No| Err1(["Throw ApplicationException<br>with validation message"])
	D1 -->|Yes| S2["Call GetYear to resolve<br>year and leap status"]
	S2 --> D2{"Is leap<br>year?"}
	D2 -->|Yes| S3a["Set valid day<br>count to 366"]
	D2 -->|No| S3b["Set valid day<br>count to 365"]
	S3a --> S4
	S3b --> S4["Parse last three chars<br>as day-of-year"]
	S4 --> D3{"Day-of-year exceeds<br>valid day count?"}
	D3 -->|Yes| Err2(["Throw ApplicationException:<br>invalid julian day"])
	D3 -->|No| S5["Compute DateTime(year,1,1)<br>.AddDays(dayOfYear - 1)"]
	S5 --> End([Return DateTime])
```

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.

## Sources
- `Common/SAIF.Common/Classes/Julian.cs`
