Как форматировать даты в формате yyddd без начальных нулей - PullRequest
2 голосов
/ 07 сентября 2011

Я имею дело с датами из AS / 400, которые являются формой юлианской даты. 1 января 2000 года возвращается как строковое значение «1». Если бы дата была в истинной юлианской форме, она бы выглядела как 2000001. Дата 31.12.2049 возвращается из AS / 400 как «49365». Есть ли способ отформатировать эти даты в моем коде C #, чтобы они выглядели как стандартные короткие даты?

Ответы [ 4 ]

3 голосов
/ 07 сентября 2011

Как выглядит 1 января 2001 года?

Если это выглядит как «1001», вы можете заполнить слева нулями до 5 цифр, а затем извлечь двухзначный год в качестве первых двух цифр и номер дня года в качестве последних 3. Это должно сделать тогда будет просто преобразовать число дня в году в месяц и день; если ничего другого, вы можете сделать это с кучей if операторов на дневных диапазонах.

Если это выглядит как "11", потому что в номере дня нет ведущих нулей, вам просто не повезло, так как нет возможности провести различие между многими датами, такими как 1 января 2001 г. и 11 января 2000 г. .

P.S. Это не юлианские даты , а вариация порядковых дат .

2 голосов
/ 09 сентября 2011

IBM определяет * формат даты JUL как гг / ддд . Обычно он не используется, но является доступным стандартным форматом, поддерживаемым в AS / 400. Вы говорите, что у вас есть строка, поэтому предполагается, что она хранится в виде CHAR (5) или 5A в DDS.

Если ваш столбец называется jdt , получите правильное количество цифр в вашей строке в SQL с помощью:

  RIGHT(('00000' || TRIM(jdt)),5)

Теперь вставьте косую черту в:

  INSERT( RIGHT(('00000'||TRIM(jdt)),5) ,3,0,'/')

DB2 / 400 может привести это поле к реальной дате, но оно будет работать правильно, только если вы сможете SET OPTION DATFMT=*JUL. Как это сделать из C # в Windows будет зависеть от того, как вы подключаетесь.

Предположим, вы не можете найти способ установить формат даты в вашем соединении.

Решение: Создать пользовательскую функцию [UDF] в DB2.

Сначала выберите подходящую библиотеку для хранения функции и установите ее в качестве текущей библиотеки. В OS / 400 CL CHGCURLIB yourlib или в SQL SET SCHEMA = yourlib. Таким образом, по умолчанию все, что вы создадите, попадет в эту библиотеку.

Я рекомендую хранить определение SQL для вашей UDF в исходном члене. (Спросите, если незнаком). Вы можете выполнить источник с помощью команды RUNSQLSTM.

Ваше определение функции может выглядеть примерно так:

CREATE FUNCTION  CvtJul2Date( jdtin char(5) ) RETURNS DATE            
        LANGUAGE SQL                                                  
        SPECIFIC CVTJUL2DT                                            
        DETERMINISTIC NO EXTERNAL ACTION                              
        CONTAINS SQL                                                  
        RETURNS NULL ON NULL INPUT                                    
        SET OPTION DATFMT = *JUL                                      
  BEGIN                                                               
    RETURN(                                                           
          date( insert( right(('00000'||trim(jdtin)),5) ,3,0,'/') )   
    );                                                                
  END                                                                 

Параметр * JUL распространяется на UDF. Любой запрос SQL, выполняемый в AS / 400, должен иметь возможность выполнять это преобразование независимо от DATFMT задания (при условии, что вы поместили эту функцию в библиотеку, которая находится в списке библиотек этого задания).

2 голосов
/ 08 сентября 2011

IF ваши даты всегда имеют формат 'yyddd':

Если вы можете написать свой оператор SQL напрямую, сработает следующее ...

SELECT CAST('20' || julianDate as date)
FROM table

Если вы этого не сделаете, подумайте над написанием представления, которое включает это поведение (это одна из причин, по которой представления существуют ...).

По понятным причинам все даты будут считаться годом 2000 и более поздними..

ЕСЛИ (по какой-либо причине) он удаляет все ведущие нули в каждой части (как указано в комментариях к ответу @ Anomie), вы действительно просто тост.Честно говоря, весь набор данных, вероятно, потерян, поскольку я не уверен, как даже RPG сможет правильно провести различие между определенными датами в этой точке.

1 голос
/ 07 сентября 2011

Упс ... мой плохой.Метод все еще вероятно должен быть написан.

Исходя из вашего описания, увеличение на 1 - это новый день?Похоже, вам придется сделать некоторые математические вычисления, чтобы вычислить дату.Может быть, создать такую ​​функцию, как

public DateTime ConvertDate(int julianDate)
{

}

Это не проверено и может потребоваться некоторые изменения.Но это было бы мое предложение.

...