Каково точное определение формата 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;
}