Datetime C#:将AS/400日期转换为日期时间

Datetime C#:将AS/400日期转换为日期时间,datetime,db2,ibm-midrange,Datetime,Db2,Ibm Midrange,DB2AS/400中的日期是一个整数,包含自20世纪之交以来的天数 问题1:有人知道IBM DB2/AS400的“零”日期吗?e、 g: 1899年12月30日 1899年12月31日 1900年1月1日 问题2:给定“AS/400”日期(例如40010),如何将其转换为CLR日期时间 DateTime d = new DateTime(40010); //invalid 其他一些“零”日期包括: OLE自动化:12/30/1899 SQL Server:1/1/1900 marc_s

DB2AS/400中的日期是一个整数,包含自20世纪之交以来的天数


问题1:有人知道IBM DB2/AS400的“零”日期吗?e、 g:

  • 1899年12月30日
  • 1899年12月31日
  • 1900年1月1日
问题2:给定“AS/400”日期(例如40010),如何将其转换为CLR日期时间

DateTime d = new DateTime(40010); //invalid

其他一些“零”日期包括:

  • OLE自动化:12/30/1899
  • SQL Server:1/1/1900

marc_s的一条评论将SQL Server中的“零”日期与“最小”日期混淆了。这样每个人都可以看到这个例子:

SELECT 
   CAST(0 AS datetime) AS dateTimeZero,
   CAST(0 AS smalldatetime) AS smallDateTimeZero

dateTimeZero              smallDateTimeZero
=======================   ===================     
1900-01-01 00:00:00.000   1900-01-01 00:00:00
select date(15+719892) as date1 from library1.file1

marc_s的评论将SQL Server中的“零”日期与“最小”日期混淆。所以大家都能看到这个例子:

SELECT 
   CAST(0 AS datetime) AS dateTimeZero,
   CAST(0 AS smalldatetime) AS smallDateTimeZero

dateTimeZero              smallDateTimeZero
=======================   ===================     
1900-01-01 00:00:00.000   1900-01-01 00:00:00
select date(15+719892) as date1 from library1.file1
问题1: 我不知道DB2的开始日期是什么。不管怎么说,谷歌也帮不上什么忙。你没有任何可以用来计算的样本数据吗

更新:您确定日期存储为天数吗?我发现这表明情况并非如此

问题2: 在本例中,假设1900-01-01为开始日期,其中天为as/400日期值

DateTime myDate = new DateTime(1900, 1, 1).AddDays(days);
问题1: 我不知道DB2的开始日期是什么。不管怎么说,谷歌也帮不上什么忙。你没有任何可以用来计算的样本数据吗

更新:您确定日期存储为天数吗?我发现这表明情况并非如此

问题2: 在本例中,假设1900-01-01为开始日期,其中天为as/400日期值

DateTime myDate = new DateTime(1900, 1, 1).AddDays(days);

我不知道答案。但对于2,您可以这样做:

private DateTime AS400 = new DateTime(1900, 1, 1);

...


DateTime myClrDT = AS400.AddDays(days);

我不知道答案。但对于2,您可以这样做:

private DateTime AS400 = new DateTime(1900, 1, 1);

...


DateTime myClrDT = AS400.AddDays(days);

问题1:

据我所知,As/400 PHSYIC文件中没有“零日期”。如果我对包含时间戳字段的PHSYIC文件执行DSPPFM,则该值将以yyyy-MM-ddhh.MM.ss格式存储为可读时间戳。例如:2005年2月8日上午7:06:33的“2005-08-0207.06.33”。在一种特定的编程语言中可能有一个零日期,这正是您需要关注的地方。AS/400 ODBC驱动程序返回SQL_TYPE_时间戳字段中的日期

问题2:

它应该简单到:

DateTime d = Convert.ToDateTime(reader["DateField"]);

我邀请其他C#专家用更好的C#代码编辑回复。

问题1:

据我所知,As/400 PHSYIC文件中没有“零日期”。如果我对包含时间戳字段的PHSYIC文件执行DSPPFM,则该值将以yyyy-MM-ddhh.MM.ss格式存储为可读时间戳。例如:2005年2月8日上午7:06:33的“2005-08-0207.06.33”。在一种特定的编程语言中可能有一个零日期,这正是您需要关注的地方。AS/400 ODBC驱动程序返回SQL_TYPE_时间戳字段中的日期

问题2:

它应该简单到:

DateTime d = Convert.ToDateTime(reader["DateField"]);

我邀请其他C#专家用更好的C#代码编辑回复。

我不认为AS/400日期在内部存储为从纪元日期开始的天数1(这是您称为“零日期”的更常见术语)。正如Tracy Probst所说,这绝对不是本机As/400物理文件中日期字段的样子。2

但是,如果你用什么方法提取数据,并把它作为一个时代以来的天数给你,那就无关紧要了。理想情况下,您应该通过直接查看AS/400,或询问能够访问的人来了解预定日期。如果AS/400上的日期是2009-07-30,而您得到的是40022,那么您可以非常有信心纪元日期是1900年1月1日。如果你得到的是40024,那么纪元是1899年12月30日。(当然,最好比较一组日期,最好是不同年份的日期,以防使用朱利安日期。)

此外,正如Tracy在自己的回答中所评论的那样,将日期存储在通用数字字段中是非常常见的(如果您的检索方法将Decimal报告为数据类型,我会这么想),在这种情况下,它实际上与DB2的内部日期格式无关。您应该知道,到目前为止,存储在AS/400数字字段中最常见的日期格式如下所示,或其变体:

  • yyyymmdd(公历,ISO 4位年份)
  • mmddyy(美国公历2位数年份)
  • yyyyddd(所谓的朱利安,4位数年份)
  • yyddd(所谓的朱利安,2位数年份)
  • 年月日
  • cyymmdd(IBM带世纪旗帜的疯狂发明)
儒略日期中的ddd是从年初算起的天数。IBM的疯狂日期中的c是0表示19年或1表示20年。我还没有听说有人在“四百”上存储了自大纪元以来的天,但也许你遇到了另一个平台的转换。AS/400的大型机传统强烈支持人类可读的日期


1AS/400(现在称为IBM i)有自己的日期数据类型,这种数据类型实际上在内部由一个历元的天数组成。但那个时代并不接近20世纪之交,甚至也不接近20世纪之初。IBM喜欢将这个天数称为Scaliger数,但对于大多数研究这个问题的人来说,它被称为Julian日数。正如您可能已经从我的答案的主要部分注意到的,IBM使用“Julian”一词来表示完全不同的意思(甚至与IBM无关)。也就是说,IBM所谓的“朱利安日期”实际上是

2日期数据类型的内部格式非常低级,大部分对用户(包括大多数程序员)隐藏。表面上显示文件“实际内容”的DSPPFM命令至少有一步“太晚了”:它报告的值已经从内部的4字节“Scaliger编号”转换为人类可读的形式