Юлианский день года на Яве

Я видел "решение" на http://www.rgagnon.com/javadetails/java-0506.html, но работает некорректно. Например. вчера (8 июня) должно было быть 159, но там сказано, что было 245.

Итак, есть ли у кого-нибудь решение на Java для получения трехзначного юлианского дня текущей даты (не юлианской даты - мне нужен день в этом году)?

Спасибо! отметка


person Mark    schedule 09.06.2010    source источник
comment
Привет, Марк, я тоже хотел бы знать это, потому что я хочу использовать это в астрономической программе, над которой я работаю, и я предпочитаю делать это напрямую на java, а не кодировать это сам :)   -  person Andreas Hornig    schedule 12.06.2010
comment
Этот день года (1–366), более известный как Порядковая дата . Использование здесь «Джулиана» является обычным, но, насколько мне известно, неверным. Очевидно совпадение с Julian Day, которое является целым числом, присвоенным полный солнечный день по юлианскому календарю, отсчитываемый с полудня по всемирному времени, с номером 0 по юлианскому дню, присвоенным дню, начинающемуся в полдень 1 января 4713 года до нашей эры, по пролептическому юлианскому календарю (24 ноября 4714 года до нашей эры по пролептическому григорианскому календарю) . Пример: 2000-01-01T12: 00: 00Z = 2,451,545.   -  person Basil Bourque    schedule 29.05.2017


Ответы (8)


Если вам нужен только день года, почему бы вам просто не использовать поле GregorianCalendars DAY_OF_YEAR?

import java.util.GregorianCalendar;
public class CalTest {
    public static void main(String[] argv) {
        GregorianCalendar gc = new GregorianCalendar();
        gc.set(GregorianCalendar.DAY_OF_MONTH, 8);
        gc.set(GregorianCalendar.MONTH, GregorianCalendar.JUNE);
        gc.set(GregorianCalendar.YEAR, 2010);
        System.out.println(gc.get(GregorianCalendar.DAY_OF_YEAR));
}

}

Кроме того, вы можете рассчитать разницу между сегодняшней датой по юлианскому календарю и датой 1 января этого года. Но не забудьте добавить к результату 1, поскольку 1 января - не нулевой день в году:

int[] now = {2010, 6, 8};
int[] janFirst = {2010, 1, 1};
double dayOfYear = toJulian(now) - toJulian(janFirst) + 1
System.out.println(Double.valueOf(dayOfYear).intValue());
person wallenborn    schedule 09.06.2010
comment
Большое спасибо! Это сработало отлично - я знал, что должен быть простой ответ. - person Mark; 09.06.2010
comment
К вашему сведению, ужасно ошибочные классы даты и времени, такие как _ 1_, _ 2_ и java.text.SimpleDateFormat теперь являются устаревшими , замененный java.time классы, встроенные в Java 8 и новее. - person Basil Bourque; 29.04.2020

tl;dr

LocalDate.now().getDayOfYear()

…or…

org.threeten.extra.DayOfYear.now() 

Терминология «юлианского дня»

Термин «юлианский день» иногда используется в широком смысле для обозначения порядкового дня года или Порядковая дата, что означает число от 1 до 365 или 366 ( високосные годы). 1 января - 1, 2 января - 2, 31 декабря - 365 (или 366 в високосные годы).

Это вольное (неправильное) использование Julian, вероятно, связано с использованием в астрономии и другие поля отслеживания дат в виде непрерывного подсчета дней с полудня по всемирному времени 1 января 4713 г. до н.э. (на Юлианский календарь). В настоящее время юлианская дата приближается к двум с половиной миллионам 2,457,576 сегодня.

java.time

Фреймворк java.time, встроенный в Java 8 и более поздних версий, предоставляет простой способ получения дня года.

Класс LocalDate представляет значение только даты без времени суток и часового пояса. Вы можете опросить по дню года.

LocalDate localDate = LocalDate.of ( 2010 , Month.JUNE , 8 );
int dayOfYear = localDate.getDayOfYear ();

Выгрузить в консоль. Результаты показывают, что 8 июня 2010 года действительно день №159.

System.out.println ( "localDate: " + localDate + " | dayOfYear: " + dayOfYear );

localDate: 2010-06-08 | dayOfYear: 159

Часовой пояс имеет решающее значение при определении даты. В любой момент дата меняется в зависимости от зоны земного шара. Например, несколько минут после полуночи в Париже Франция - это новый день, в то время как в Монреаль-Квебеке все еще «вчера».

ZoneId z = ZoneId.of( “America/Montreal” );
LocalDate today = LocalDate.now( z );
int dayOfYear = today.getDayOfYear ();

Идем в другую сторону, от числа к свиданию.

LocalDate ld = Year.of( 2017 ).atDay( 159 ) ;

org.threeten.extra.DayOfYear

Библиотека ThreeTen-Extra добавляет функциональность к java.time классы, встроенные в Java.

Эта библиотека предлагает класс для явного представления порядкового дня любого года: _ 15_. Использование этого класса вместо простого целого числа делает ваш код более самодокументированным, обеспечивает безопасность типов и гарантирует допустимые значения.

DayOfYear dayOfYear = DayOfYear.from( LocalDate.of ( 2010 , Month.JUNE , 8 ) ) ;

Получите дату на DayOfYear с конкретным годом.

LocalDate localDate = dayOfYear.atYear( 2023 ) ;

О java.time

< em> java.time встроен в Java 8 и новее. Эти классы заменяют неудобные старые устаревшие классы даты и времени, такие как _ 19_, _ 20_, & _ 21_.

Чтобы узнать больше, см. Учебник Oracle . И поищите в Stack Overflow множество примеров и объяснений. Спецификация - JSR 310.

Проект Joda-Time теперь в режим обслуживания, советует перейти на java.time.

Вы можете обмениваться объектами java.time непосредственно с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или новее. Нет необходимости в строках, нет необходимости в java.sql.* классах. Hibernate 5 и JPA 2.2 поддерживают java.time.

Где взять классы java.time?

Проект ThreeTen-Extra расширяет java.time дополнительными классами. . Этот проект является испытательной площадкой для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, например _23 _, YearWeek, _ 25_ и подробнее.

person Basil Bourque    schedule 07.07.2016

import java.util.Calendar;
// ...
final int julianDay = Calendar.getInstance().get(Calendar.DAY_OF_YEAR);

Обратите внимание, что это не принимает во внимание сделку «начинается в полдень», заявленную этим странным сайтом, на который вы ссылались. Конечно, это можно исправить, просто проверив время.

person Pointy    schedule 09.06.2010
comment
В моей системе System.out.println(Calendar.getInstance().getClass()); печатает class java.util.GregorianCalendar, но, возможно, это то же самое, что и julian. - person aioobe; 09.06.2010
comment
Юлианская дата или юлианский день всегда означали для меня день в году. Я думаю, что это верно для всех, за исключением, пожалуй, серьезных ученых-классиков. Если кто-то ищет дату по догригорианскому календарю, мое решение не сработает. Обратите внимание, что вопрос включает предложение, мне нужен день в этом году. - person Pointy; 09.06.2010
comment
Перед расчетом сделайте setGregorianChange( new Date( Long.MAX_VALUE) ). Тогда это будет Julian день. - person Alexander Pogrebnyak; 09.06.2010
comment
Я думаю, вы все неправильно понимаете, что означает Джулиан Дэй в этом контексте. Это не об исторических календарях. Термин «юлианский день» или «юлианская дата» в современных приложениях для обработки данных означает просто день года. Погуглите, если не верите мне. - person Pointy; 09.06.2010
comment
@Pointy Нет, Джулиан Дэйт существует уже несколько лет. Юлианский день года не является стандартным термином. А православных христиан не волнует, какая дата по юлианскому календарю, поскольку они не признают авторитет римского папы Григория. - person Pete Kirkham; 09.06.2010
comment
Что ж, Марк, пользователь, задавший вопрос, отсутствует в действии, но если серьезно, то Юлианский день - это то, что стало популярным около тридцати лет назад для хранения дат в базах данных. Фактически, это было серьезным аспектом проблемы 2000 года: базы данных хранят даты в виде 5-значных чисел, с 3-мя цифрами для юлианского дня и 2-мя цифрами для года. В старых библиотеках были подпрограммы toJulianDate и fromJulianDate (конечно, с перемежением стилистически для COBOL :-) Я подозреваю, что это и есть то, о чем был исходный вопрос. - person Pointy; 09.06.2010
comment
Также обратите внимание, что в исходном вопросе говорится, что 8 июня 2010 года должно быть 159, что правильно, если юлианский день означает просто день года. - person Pointy; 09.06.2010
comment
Да, я имел в виду Юлианский ДЕНЬ года (три цифры, например, 159 для 8 июня 2010 г.). ЕСТЬ Юлианская ДАТА, которая относится к некоторой дате до нашей эры и является большим числом - это НЕ то, что я ищу. - person Mark; 09.06.2010
comment
извините, ребята - был очень занят Ответ: Calendar today = GregorianCalendar.getInstance (); int todayJulian = сегодня.get (GregorianCalendar.DAY_OF_YEAR); Это дает день года, он же юлианский день (а не дату). - person Mark; 22.06.2010

Я прочитал все сообщения, и мне кажется, что-то непонятно.

user912567 упомянул Жана Мееуса, и он абсолютно прав

Наиболее точное определение, которое я нашел, дано Жаном Миусом в его книге «Астрономические алгоритмы» (действительно, необходимо иметь ...).

Юлианская дата - это дата, выраженная как обычно, с годом, месяцем и днем.

Юлианский день - это число (действительное число), отсчитываемое с -4712 года и представляющее собой «... непрерывный счет дней ...» (и долю дня). Полезная шкала времени, используемая для точных астрономических расчетов.

Жан Миус: «Юлианский день не имеет ничего общего с юлианским календарем» («Астрономические алгоритмы», 2-е издание, стр. 59)

person bendeg    schedule 27.02.2016
comment
Точно так. Стоит отметить, что, вопреки многим здесь ответам и комментариям, юлианский день остается полезным в современных вычислениях, так как вы можете рассчитать с его помощью различия даты в днях с очень небольшими усилиями. - person user207421; 29.05.2017

если мы получим двойную юлианскую дату, например, хордиантный менеджер по принятию решений

http://java.ittoolbox.com/groups/technical-functional/java-l/java-function-to-convert-julian-date-to-calendar-date-1947446

Следующее работает, но второе не заботится о Как преобразовать дату Java в число дня по юлианскому календарю?

общедоступная статическая строка julianDate (String julianDateStr) {

    try{
        // Calcul date calendrier Gr?gorien ? partir du jour Julien ?ph?m?ride 
        // Tous les calculs sont issus du livre de Jean MEEUS "Calcul astronomique" 
        // Chapitre 3 de la soci?t? astronomique de France 3 rue Beethoven 75016 Paris 
        // Tel 01 42 24 13 74 
        // Valable pour les ann?es n?gatives et positives mais pas pour les jours Juliens n?gatifs
        double jd=Double.parseDouble(julianDateStr);
          double z, f, a, b, c, d, e, m, aux;
            Date date = new Date();
            jd += 0.5;
            z = Math.floor(jd);
            f = jd - z;

            if (z >= 2299161.0) {
              a = Math.floor((z - 1867216.25) / 36524.25);
              a = z + 1 + a - Math.floor(a / 4);
            } else {
              a = z;
            }

            b = a + 1524;
            c = Math.floor((b - 122.1) / 365.25);
            d = Math.floor(365.25 * c);
            e = Math.floor((b - d) / 30.6001);
            aux = b - d - Math.floor(30.6001 * e) + f;
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(date);
            calendar.set(Calendar.DAY_OF_MONTH, (int) aux);

            double hhd= aux-calendar.get(Calendar.DAY_OF_MONTH);                
            aux = ((aux - calendar.get(Calendar.DAY_OF_MONTH)) * 24);




            calendar.set(Calendar.HOUR_OF_DAY, (int) aux);

            calendar.set(Calendar.MINUTE, (int) ((aux - calendar.get(Calendar.HOUR_OF_DAY)) * 60));



         // Calcul secondes 
            double mnd = (24 * hhd) - calendar.get(Calendar.HOUR_OF_DAY);
            double ssd = (60 * mnd) - calendar.get(Calendar.MINUTE); 
            int ss = (int)(60 * ssd);
            calendar.set(Calendar.SECOND,ss);



            if (e < 13.5) {
              m = e - 1;
            } else {
              m = e - 13;
            }
            // Se le resta uno al mes por el manejo de JAVA, donde los meses empiezan en 0.
            calendar.set(Calendar.MONTH, (int) m - 1);
            if (m > 2.5) {
              calendar.set(Calendar.YEAR, (int) (c - 4716));
            } else {
              calendar.set(Calendar.YEAR, (int) (c - 4715));
            }


        SimpleDateFormat sdf=new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        //System.out.println("Appnumber= "+appNumber+" TimeStamp="+timeStamp+" Julian Date="+julianDateStr+" Converted Date="+sdf.format(calendar.getTime()));
        return sdf.format(calendar.getTime());

}catch(Exception e){
    e.printStackTrace();
}
return null;

}  
person user912567    schedule 25.08.2011

После ответа @Basil Bourque ниже представлена ​​моя реализация для получения юлианского дня года с использованием системного идентификатора зоны по умолчанию.

LocalDate localDate = LocalDate.now(ZoneId.systemDefault());
int julianDay = localDate.getDayOfYear();
person Arpit Aggarwal    schedule 12.11.2019

Если вы ищете юлианский день, как в подсчете дней с 4713 г. до н.э., то вы можете вместо этого используйте следующий код:

private static int daysSince1900(Date date) {
    Calendar c = new GregorianCalendar();
    c.setTime(date);

    int year = c.get(Calendar.YEAR);
    if (year < 1900 || year > 2099) {
        throw new IllegalArgumentException("daysSince1900 - Date must be between 1900 and 2099");
    }
    year -= 1900;
    int month = c.get(Calendar.MONTH) + 1;
    int days = c.get(Calendar.DAY_OF_MONTH);

    if (month < 3) {
        month += 12;
        year--;
    }
    int yearDays = (int) (year * 365.25);
    int monthDays = (int) ((month + 1) * 30.61);

    return (yearDays + monthDays + days - 63);
}

/**
 * Get day count since Monday, January 1, 4713 BC
 * https://en.wikipedia.org/wiki/Julian_day
 * @param date
 * @param time_of_day percentage past midnight, i.e. noon is 0.5
 * @param timezone in hours, i.e. IST (+05:30) is 5.5
 * @return
 */
private static double julianDay(Date date, double time_of_day, double timezone) {
    return daysSince1900(date) + 2415018.5 + time_of_day - timezone / 24;
}

Приведенный выше код основан на https://stackoverflow.com/a/9593736 и поэтому ограничен датами между 1900 и 2099 годами. .

person chaitan94    schedule 20.05.2020

Вы также можете получить "юлианскую дату" или "порядковую дату" следующим образом:

import java.util.Calendar;
import java.util.Date;

public class MyClass {

  public static void main(String[] args) {
    Calendar cal = Calendar.getInstance();
    LocalDate myObj = LocalDate.now();
    System.out.println(myObj);
    System.out.println("Julian Date:" + cal.get(Calendar.DAY_OF_YEAR));

  }
}
person J_A    schedule 27.08.2019
comment
Хотя мы благодарим вас за ваш ответ, было бы лучше, если бы он предоставил дополнительную ценность помимо других ответов. В этом случае ваш ответ не дает дополнительной ценности, поскольку принятый ответ содержит это решение. Если предыдущий ответ был вам полезен, вы должны проголосовать за него, а не повторять ту же информацию. - person Toby Speight; 27.08.2019