Каково точное определение формата JDE's Julian Date?

Я пишу код для преобразования григорианской даты в юлианскую дату JDE ( JDEdwards).

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

Насколько я могу понять из Google, определение юлианской даты в JDE:

1000*(year-1900) + dayofyear

где year - это четырехзначный год (например, 2009), а dayofyear равен 1 на 1 января и отсчитывает весь год до 365 или 366 за 31 декабря (в зависимости от того, является ли это високосным годом).

У меня такой вопрос: поддерживаются ли годы до 1900 года? Если так, то вышеупомянутая формула все еще держится, или это должно быть так:

1000*(year-1900) - dayofyear

(отметьте минус вместо плюса.)

или что-то другое?

У кого-нибудь есть ссылка на официальную документацию для этого формата даты?

9 ответов

Юлианская дата JDE состоит из CYYDDD, который является Веком, Годом, Днем года.

Century - ноль для 20-го, например, 19XX и один для 21-го, например, 20XX.

Год состоит из двух цифр. Итак, 101001 - 1 января 2001 года.

Как вы можете видеть, это не будет поддерживать даты до 1900 года.

См. Эту страницу Oracle для простого и официального объяснения: о юлианском формате даты

"JDE Julian Date Converter" возвращает отрицательное значение для:

1809/07/23 : -90635

В отличие от классической юлианской даты:

The Julian date for CE  1809 July 23 00:00:00.0 UT is
JD 2381986.50000

Вот пример JD EDWARDS (программное обеспечение AS/400) Джулиана Дейта, но это не "официальная" документация, и, похоже, она не поддерживает даты до 1900 года...

Примечание: этот " ACC: Как преобразовать юлианские дни в даты в Access и Back" также не поддерживает дату до 1900 года... так как он говорит о "неформальном" юлианском дне, обычно используемом государственными органами и подрядчиками.

Неофициальный формат юлианского дня, используемый в этой статье, является порядковым днем ​​года (например, юлианский день 032 представляет 1 февраля или 32-й день года).
Вариации в неформальных форматах юлианских дней включают использование предыдущего двухзначного года (например, 96032 для 2/1/96) и разделение года тире (например, 96-032).
Другой, менее популярный формат юлианского дня использует год из одной цифры (например, 6-032). Эти дополнительные форматы не однозначно определяют век или десятилетие. Вы должны внимательно рассмотреть последствия при использовании этих форматов; например, юлианский день 00061 можно интерпретировать как 3/1/2000 или 3/2/1900.

Может быть, от вопроса, вы можете конвертировать в Excel, используя следующую формулу:

Конвертировать Джулиан в дату в Excel

В ячейке A2 поместите юлианскую дату, например 102324
в ячейке B2 поместите эту формулу: (скопируйте ее в)
=DATE(YEAR("01/01/"&TEXT(1900+INT(A2/1000),0)),MONTH("01/01/"&TEXT(1900+INT(A2/1000),0)),DAY("01/01/"&TEXT(1900+INT(A2/1000),0)))+MOD(A2,1000)-1

Дата 20.11.02 дата появится в ячейке B2

Конвертировать дату в юлианский в Excel

В ячейке C2 скопируйте эту формулу:
=(YEAR(B2)-2000+100)*1000+B2-DATE(YEAR(B2),"01","01")+1

Это преобразует B2 обратно в 102324

Сохраните приведенный ниже исходный код в исходном элементе с именем JDEDATES. Используйте runqlstm в первой строке для создания функций. Затем вы можете делать такие вещи, как

select  jde2date(A1UPMJ), f.* from f00095 f                            

и увидеть реальную дату.

Источник:

--RUNSQLSTM SRCFILE(qtxtsrc) SRCMBR(JDEDATES) COMMIT(*NONE)  NAMING(*SQL) 
 -- jde 2 date                                                                    

 create function QGPL/jde2date ( d decimal(7,0))                                  
 returns date                                                                     
 language sql                                                                     
 deterministic                                                                    
 contains sql                                                                     
    SET OPTION DATFMT=*ISO                                                        
 BEGIN                                                                            
  if d=0 then return null;                                                        
  else                                                                            
       return date(digits(decimal(d+1900000,7,0)));                               
  end if;                                                                         
 end;                                                                            -- date 2 jde                                     
 create function QGPL/date2jde ( d date)           
 returns decimal(7,0)                              
 language sql                                      
 deterministic                                     
 contains sql                                      
    SET OPTION DATFMT=*ISO                         
 BEGIN                                             
  if d is null then return 0;                      
  else                                             
  return (YEAR(D)-1900)*1000+DAYOFYEAR(D);         
  end if;                                          
 end ;                                              

Обновление: Извините, JDE, вероятно, что-то еще. Но для справки:

Я знаю, что JDE другой. Со страницы 59 в книге "Астрономические алгоритмы" (Жан Миус, ISBN 0-943396-35-2):

"Если JD соответствует моменту, измеренному в шкале динамического времени (или эфемеридного времени), обычно используется выражение" Юлианский день эфемерид "(JDE). (Не JED, как
это иногда пишется. "E" - это своего рода индекс, добавленный к "JD")

JD и JDE (для одного и того же момента времени) близки по значению, поскольку разница UT и ET составляет порядка минут. Например, ET-UT составлял 56,86 секунды в 1990 году и -2,72 секунды в 1900 году.

Есть также MJD (модифицированный юлианский день):

MJD = JD - 2400000,5

Нулевая точка для MJD - 1858-11-17, 0ч UT.


Обратите внимание, что JD, как юлианская дата, является неправильным. Это юлианский день. JD не имеет ничего общего с юлианским календарем. (Это противоречит статье в Википедии, автором упомянутой выше книги, Джин Миус - бельгийский астроном, специализирующийся на небесной механике.)

Я опоздал на вечеринку на несколько лет, но для других людей вроде меня, которые обнаруживают, что работают с такими устаревшими системами, я надеюсь, что некоторые из моих фрагментов Java могут помочь. Я использую тот факт, что вы можете преобразовать этот формат CYYDDD в формат yyyyDDD и проанализировать его на основе этого.

          import java.util.Date;
    import java.util.GregorianCalendar;
    import java.util.Calendar;
    import java.util.SimpleDateFormat;
    
    String jdeJulianDate = "099365"; //Testing with December 31, 1999
    
    // Compile what the year number is
    int centIndex = Integer.parseInt(jdeJulianDate.substring(0,1));
    int yearIndex = Integer.parseInt(jdeJulianDate.substring(1,3));
    int yearNumber = 1900 + (100 * centIndex) + yearIndex;
    
    // Put the year number together with date ordinal to get yyyyDDD format
    String fullDate = String.valueOf(yearNumber) + jdeJulianDate.substring(3,6);
    
    // Date parsing, so need to wrap in try/catch block
    try {
        Date dt = new SimpleDateFormat("yyyyDDD").parse(fullDate);
        // Validate it parses to a date in the same year...
        Calendar cal = new GregorianCalendar();
        cal.setTime(dt);
        if (cal.get(Calendar.YEAR) != yearNumber) {
            // Cases happen where things like 121366 (should be invalid) get parsed, yielding 2022-01-01.
            // Throw exception or what-not here.
        }
    }
    catch (Exception e) {
        // Date parsing error handling here
    }

Пример кода VBA для преобразования туда и обратно между JDE Julian Date и Gregorian:

Public Const Epoch = 1900
Public Const JDateMultiplier = 1000
Public Const FirstJan = "01/01/"

Public Function Julian2Date(ByVal vDate As Long) As Date

    Dim Year As Long
    Dim Days As Long
    Dim SeedDate As Date

    '   Day Number
    Days = vDate - (Int(vDate / JDateMultiplier) * JDateMultiplier) - 1
    '   Calendar Year
    Year = ((vDate - Days) / JDateMultiplier) + Epoch
    '   First Day of Calendar Year
    SeedDate = CDate(FirstJan + CStr(Year))

    '   Add Number of Days to First Day in Calendar Year
    Julian2Date = DateAdd("d", Days, SeedDate)

End Function

Public Function Date2Julian(ByVal vDate As Date) As Long

    Dim JYear As String
    Dim BeginDate As Date
    Dim JDays As Long

    '   Calendar Year
    JYear = Format(Year(vDate), "0000")
    '   First Day of Calendar Year
    BeginDate = CDate(FirstJan + JYear)
    '   Day Number
    JDays = DateDiff("d", BeginDate, vDate) + 1

    '   Add Number of Days to Year Number
    Date2Julian = ((CLng(JYear) - Epoch) * JDateMultiplier) + JDays

End Function

Я постарался сделать это как можно более ясным и простым, и с этой целью я намеренно исключил возможность обнаружения ошибок. Однако вы должны иметь возможность добавлять код в модуль VBA и вызывать их непосредственно из собственного кода.

Я также включил несколько полезных фрагментов T-SQL:

Сегодняшняя дата как JDE Юлианская дата:

 (datepart(yy,getdate())-1900) * 1000 + datepart(dy, getdate())

Преобразуйте JDE Julian Date в григорианский (DD/MM/YYYY), замените XXXXXX на имя столбца, содержащего JDE Julian Date:

convert (varchar, dateadd (day,convert (int, right(XXXXXX,3)) - 1, convert (datetime, ('1/1/' + convert ( varchar, (cast(left(right(XXXXXX+1000000,6),3) as varchar) + 1900))))),103)

Если вам требуется другой григорианский формат, замените значение 103 (справа в конце) на соответствующее значение, найденное здесь: https://msdn.microsoft.com/en-us/library/ms187928.aspx

Вау, в некоторых из этих ответов много сложного кода, предназначенного только для преобразования в JDE-даты JDE. В Excel и VBA есть простые способы добраться туда.

ИЗ ДЖУЛИАНА

Excel (при условии, что юлианская дата в A1):

=DATE(1900+LEFT(A1,LEN(A1)-3),1,RIGHT(A1,3))

VBA (с юлианской даты, j, хранится в виде строки):

d = DateSerial(1900 + Left$(j, Len(j) - 3), 1, Right$(j, 3))

VBA (от юлианской даты j хранится как Long):

d = DateSerial(1900 + Left$(j, Len(CStr(j)) - 3), 1, Right$(j, 3))

В юлианском

Excel (при условии, что дата в A1):

=(YEAR(A1)-1900)*1000+A1-DATE(YEAR(A1),1,0)

VBA (Лонг, Дж):

j = (Year(d) - 1900) * 1000 + DatePart("y", d)

У меня есть простой способ для C использовать время сейчас и эпоху 1970, 01, 01, если кому-то интересно. Но это для юлианских чисел дня, которые не совпадают с JDE, но они похожи на использование математики для вычисления дней, и я уверен, что эта идея может быть адаптирована для JDE. Иногда люди просто путают их, как я. Сожалею. Но, тем не менее, это пример использования эталона времени, который всегда следует делать, и, поскольку большинство компьютеров используют его, для нас было бы так же просто не перегружаться датами и просто использовать дни до или после этой эпохи.

Поскольку JDE теперь принадлежит Oracle, они также теперь поддерживают Julian_Day. см.: https://docs.oracle.com/javase/8/docs/api/java/time/temporal/JulianFields.html

#include <stdio.h>
#include <time.h>
#define EPOCH (double)  2440587.5 /* Julian Day number for Jan. 01, 1970 midnight */
int main ()
{
 double days = time(0)/86400.0;

 printf ("%f days since January 1, 1970\n", days);

 printf ("%f\n", days + EPOCH);

 return 0;  
}
Другие вопросы по тегам