Convert Datetime to Julian Date in C# (Tooadate Safe)

Convert DateTime to Julian Date in C# (ToOADate Safe?)

OADate is similar to Julian Dates, but uses a different starting point (December 30, 1899 vs. January 1, 4713 BC), and a different 'new day' point. Julian Dates consider noon to be the beginning of a new day, OADates use the modern definition, midnight.

The Julian Date of midnight, December 30, 1899 is 2415018.5. This method should give you the proper values:

public static double ToJulianDate(this DateTime date)
{
return date.ToOADate() + 2415018.5;
}

As for the algorithm:

  • if (Month < 3) ...: To make the magic numbers work our right, they're putting February at the 'end' of the year.
  • (153 * Month - 457) / 5: Wow, that's some serious magic numbers.
    • Normally, the number of days in each month is 31 28 31 30 31 30 31 31 30 31 30 31, but after that adjustment in the if statement, it becomes 31 30 31 30 31 31 30 31 30 31 31 28. Or, subtract 30 and you end up with 1 0 1 0 1 1 0 1 0 1 1 -2. They're creating that pattern of 1s and 0s by doing that division in integer space.
    • Re-written to floating point, it would be (int)(30.6 * Month - 91.4). 30.6 is the average number of days per month, excluding February (30.63 repeating, to be exact). 91.4 is almost the number of days in 3 average non-February months. (30.6 * 3 is 91.8).
    • So, let's remove the 30, and just focus on that 0.6 days. If we multiply it by the number of months, and then truncate to an integer, we'll get a pattern of 0s and 1s.
      • 0.6 * 0 = 0.0 -> 0
      • 0.6 * 1 = 0.6 -> 0 (difference of 0)
      • 0.6 * 2 = 1.2 -> 1 (difference of 1)
      • 0.6 * 3 = 1.8 -> 1 (difference of 0)
      • 0.6 * 4 = 2.4 -> 2 (difference of 1)
      • 0.6 * 5 = 3.0 -> 3 (difference of 1)
      • 0.6 * 6 = 3.6 -> 3 (difference of 0)
      • 0.6 * 7 = 4.2 -> 4 (difference of 1)
      • 0.6 * 8 = 4.8 -> 4 (difference of 0)
    • See that pattern of differences in the right? That's the same pattern in the list above, the number of days in each month minus 30. The subtraction of 91.8 would compensate for the number of days in the first three months, that were moved to the 'end' of the year, and adjusting it by 0.4 moves the successive differences of 1 (0.6 * 4 and 0.6 * 5 in the above table) to align with the adjacent months that are 31 days.
    • Since February is now at the 'end' of the year, we don't need to deal with its length. It could be 45 days long (46 on a leap year), and the only thing that would have to change is the constant for the number of days in a year, 365.
    • Note that this relies on the pattern of 30 and 31 month days. If we had two months in a row that were 30 days, this would not be possible.
  • 365 * Year: Days per year
  • (Year / 4) - (Year / 100) + (Year / 400): Plus one leap day every 4 years, minus one every 100, plus one every 400.
  • + 1721119: This is the Julian Date of March 2nd, 1 BC. Since we moved the 'start' of the calendar from January to March, we use this as our offset, rather than January 1st. Since there is no year zero, 1 BC gets the integer value 0. As for why March 2nd instead of March 1st, I'm guessing that's because that whole month calculation was still a little off at the end. If the original writer had used - 462 instead of - 457 (- 92.4 instead of - 91.4 in floating point math), then the offset would have been to March 1st.

Convert Julian Date with Time (H/m/s) to Date Time in C#

Thanks to Mr. Zator answer here I was able to solve my problem like so:

public DateTime JulianToDateTime(double julianDate) {
double unixTime = (julianDate - 2440587.5) * 86400;

DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
dtDateTime = dtDateTime.AddSeconds(unixTime).ToLocalTime();

return dtDateTime;
}

It is worth mentioning though, that this only works for CE Julian Date types, if the Julian Date is in BCE type it will not work, someother function is needed for that. I also made the opposite version of this method that looks like this:

public double DateTimeToJulian(DateTime dateTime) {
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
TimeSpan diff = dateTime.ToUniversalTime() - origin;
double unixTime = Math.Floor(diff.TotalSeconds);
double julianDate = (unixTime / 86400) + 2440587.5;

return julianDate;
}

ASP.NET get Julian Date from current date

Since, if you're working with Julian dates, you probably will need to do this again and again, I suggest writing an extension function for System.DateTime, which would execute something like the following:

return (DateTime.Year % 100) * 1000 + DateTime.DayOfYear

ETA: If what you want to do is convert a DateTime to the Julian date format (create a formatted string in Julian date format), I still suggest an extension function, but it would look like this:

public static string ToJulianDate(this DateTime date) 
{
return string.Format("{0:00000}", (date.Year % 100) * 1000 + date.DayOfYear);
}

Combining Julian 'Days' with DateTime.Now

Can't you format it manually? DateTime has a DayOfYear property:

DateTime now = DateTime.Now;
Date1.Text = String.Format("{0},{1}/{2}",
now.Year,
now.DayOfYear.ToString("d3"),
now.ToString("HHmmss"));

MM-dd-yyyy to Julian yyddd

Unfortunately the date time formats do not include anything for day of the year so you'll have to create this yourself. You can format a number to have leading zeros using the D format where you specify the length you want. You can however use the date formats to get the last two digits of the year. So the following should give you the desired formatted string for a date.

public string ToYYJJJ(DateTime date)
{
return date.ToString("yy") + date.DayOfYear.ToString("D3");
}

ToOADate(); Convert Julian Date Excel

If you are converting numbers to Framework DateTime instances, it is likely you are after the static method on the DateTime struct.

        DateTime dt = DateTime.FromOADate(23456);

This method needs to be scoped to DateTime. In my example, the result is 20 March 1963.

There is also an instance method on DateTime which does the reverse...

        double d = dt.ToOADate();

The result in this case is 23456.

Your code indicates that you are trying to call it as an instance method on a int, and this will not work. The compiler is telling you that there is no such method on the int primitive.

Try instead...

 var test = 41725;
DateTime test2 = DateTime.FromOADate(test);

And you'll get 27 March 2014.

Julian date string to DateTime

This is the simplest solution I can think of:

string julianDate = "13324";

int jDate = Convert.ToInt32(julianDate);
int day = jDate % 1000;
int year = (jDate - day) / 1000;
var date1 = new DateTime(year, 1, 1);
var result = date1.AddDays(day - 1);

(Note: this is all from memory; verify the syntax, etc.)



Related Topics



Leave a reply



Submit