Конвертировать дату (год, месяц, день) в юлианский номер дня и обратно в дату - PullRequest
0 голосов
/ 28 мая 2018

Я пытаюсь реализовать две функции: 1) преобразование даты в юлианский номер дня и 2) преобразование юлианского дня обратно в дату (год, месяц и день).Результат, который возвращает мой код, отключен на один день.Я не знаком с тем, как работает алгоритм, но я вижу, что если я возьму Math.Ceiling юлианского числа, он работает, но я не уверен, что это лучший способ исправить код.Любая помощь будет принята с благодарностью.Спасибо.

public class Program
{
    /// <summary>
    /// Converts year, month and day to a Julian number
    /// </summary>
    /// <param name="year"></param>
    /// <param name="month"></param>
    /// <param name="day"></param>
    /// <returns></returns>
    public static decimal JulianNumber(int year, int month, int day)
    {
        decimal a, b, c, e, f;

        if (month == 1 || month == 2)
        {
            year -= 1;
            month += 12;
        }
        a = Math.Truncate((decimal) year / 100);
        b = Math.Truncate(a / 4);
        c = 2 - a + b;
        e = Math.Truncate((365.25m * (year + 4716)));
        f = Math.Truncate((30.6001m * (month + 1)));

        return (c + day + e + f - 1524.5m);
        // return Math.Ceiling(c + day + e + f - 1524.5m);
    }

    /// <summary>
    /// Converts Julian number to year, month and day
    /// </summary>
    /// <param name="julianNumber"></param>
    /// <returns></returns>
    public static (int year, int month, int day) GregorianDate(decimal julianNumber)
    {
        int l, n, i, j, k;

        l = (int)julianNumber + 68569;
        n = 4 * l / 146097;
        l = l - (146097 * n + 3) / 4;
        i = 4000 * (l + 1) / 1461001;
        l = l - 1461 * i / 4 + 31;
        j = 80 * l / 2447;
        k = l - 2447 * j / 80;
        l = j / 11;
        j = j + 2 - 12 * l;
        i = 100 * (n - 49) + i + l;

        return (i, j, k);
    }

    public static void Main(string[] args)
    {
        var (year1, month1, day1) = (2010, 1, 2);

        var (year2, month2, day2) = GregorianDate(JulianNumber(year1, month1, day1));

        Console.WriteLine(year1 == year2);     // True
        Console.WriteLine(month1 == month2);   // True
        Console.WriteLine(day1 == day2);       // False!
    }
}

1 Ответ

0 голосов
/ 28 мая 2018

Проблема в определении юлианского дня.Взято со страницы, на которую вы ссылались:

После того, как ведущие астрономы Гершеля приняли эту систему и приняли полдень GMT -4712-01-01 JC (1 января 4713 г. до н.э.) в качестве своей нулевой точки

Таким образом, 2018-05-28 в 00.00 - 2458266.5, а 2018-05-28 в 12.00 - 2458267. Если вы смотрите ваш JulianNumber без Math.Ceiling, фактически возвращается 2458266.5.Теперь на странице, на которую вы ссылались (с которой вы взяли метод second , GregorianDate, используются только целые числа, поэтому он работает для дат в полдень (12.00).округляя (потолок) результат JulianNumber, вы перемещаете дату в 12.00 часов и делаете ее «совместимой» с GregorianDate.

Возможные решения: используйте для JulianNumber алгоритм, которыйприсутствует на той же странице и везде используется только int (чтобы показать тот факт, что вы игнорируете часы, минуты, секунды) или ищите другой алгоритм для GregorianDate.

...