Code · JavaScript

Julian date in JavaScript

Two different things are called a "Julian date." This page shows correct, UTC-safe JavaScript for both: the ordinal day-of-year code (YYYYDDD / YYDDD) used in manufacturing and IT, and the astronomical Julian Day (JD) and Modified Julian Date (MJD).

Before any code, fix the two meanings so you convert the right one:

  • Ordinal (day-of-year) date — a year joined to the day number 1-365/366, written 2026202 (YYYYDDD) or 26202 (YYDDD). July 21, 2026 is the 202nd day of the year.
  • Astronomical Julian Day — a continuous count of days since noon on 1 January 4713 BC. For July 21, 2026 at 00:00 UTC the JD is 2461242.5. See the Julian Day page for background.

Always use UTC methods

getFullYear(), getMonth() and getDate() read the browser's local time zone, so the same instant can land on a different calendar day for different users. Use the getUTC* methods and Date.UTC() so results are stable everywhere.

Day of year (the ordinal date)

Subtract the UTC midnight of "day 0" (December 31 of the previous year) from the target date and count whole days:

function dayOfYear(d) {
  const start = Date.UTC(d.getUTCFullYear(), 0, 0);
  const diff = Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()) - start;
  return Math.floor(diff / 86400000);
}

dayOfYear(new Date('2026-07-21')); // 202

Date.UTC(year, 0, 0) is a deliberate trick: month 0, day 0 resolves to the last midnight of the previous year, so the difference is exactly the day-of-year.

Formatting YYYYDDD and YYDDD

Zero-pad the day number to three digits and prepend the year (or its last two digits):

function toYYYYDDD(d) {
  const y = d.getUTCFullYear();
  return `${y}${String(dayOfYear(d)).padStart(3, '0')}`;
}

function toYYDDD(d) {
  const yy = String(d.getUTCFullYear() % 100).padStart(2, '0');
  return `${yy}${String(dayOfYear(d)).padStart(3, '0')}`;
}

toYYYYDDD(new Date('2026-07-21')); // "2026202"
toYYDDD(new Date('2026-07-21'));   // "26202"

Parsing a code back to a Date

Split the string, then let Date.UTC roll the day-of-year over the month boundaries for you — day 202 of January is simply July 21:

function fromYYYYDDD(code) {
  const year = +code.slice(0, 4);
  const doy = +code.slice(4);          // days 1-366
  return new Date(Date.UTC(year, 0, doy));
}

fromYYYYDDD('2026202').toISOString(); // "2026-07-21T00:00:00.000Z"

Astronomical Julian Day (JD) and MJD

A JavaScript Date is milliseconds since the Unix epoch (1970-01-01 00:00 UTC). The Unix epoch has a Julian Day of exactly 2440587.5, so converting is one line:

function toJulianDate(date) {
  return date.getTime() / 86400000 + 2440587.5;
}

function toMJD(date) {
  return toJulianDate(date) - 2400000.5;
}

const d = new Date('2026-07-21T00:00:00Z');
toJulianDate(d); // 2461242.5
toMJD(d);        // 61242

The constant 2440587.5 is the JD of 1970-01-01 00:00 UTC; adding the elapsed days gives the JD directly in the proleptic Gregorian / UTC system. The Modified Julian Date just removes the constant offset: MJD = JD − 2400000.5 (see MJD).

JD back to a Date

function fromJulianDate(jd) {
  return new Date((jd - 2440587.5) * 86400000);
}

fromJulianDate(2461242.5).toISOString(); // "2026-07-21T00:00:00.000Z"

Calendar math for dates outside the Date range

The millisecond approach only covers roughly ±273,000 years around 1970 and needs a real Date. For arbitrary year/month/day values — historical or far-future — use the standard Meeus formula, which works from the numbers alone:

// Meeus algorithm: JD at 00:00 UTC for any proleptic Gregorian
// Y/M/D, with no dependence on the JavaScript Date range.
function jdFromYMD(Y, M, D) {
  if (M <= 2) { Y -= 1; M += 12; }
  const A = Math.floor(Y / 100);
  const B = 2 - A + Math.floor(A / 4);
  return Math.floor(365.25 * (Y + 4716))
       + Math.floor(30.6001 * (M + 1))
       + D + B - 1524.5;
}

jdFromYMD(2026, 7, 21); // 2461242.5

Worked example — July 21, 2026 (00:00 UTC)

  • Day of year: 2022026202 / 26202
  • Julian Day: 2461242.5
  • Modified Julian Date: 61242

Using a date library

If a library is already in the project, day-of-year is built in. Both Luxon and Day.js expose an ordinal / dayOfYear value:

// Luxon
import { DateTime } from 'luxon';
DateTime.fromObject({ year: 2026, month: 7, day: 21 }, { zone: 'utc' }).ordinal; // 202

// Day.js (with the dayOfYear plugin)
import dayjs from 'dayjs';
import dayOfYearPlugin from 'dayjs/plugin/dayOfYear';
dayjs.extend(dayOfYearPlugin);
dayjs.utc('2026-07-21').dayOfYear(); // 202

Related