2012-09-28 74 views
1

有沒有人知道如何在PL/SQL存儲過程中生成.Net DateTime.Ticks,而Oracle數據庫中沒有.Net程序集?在Oracle中生成.Net標記

我在.Net中有一個服務,它將DateTime.Ticks值存儲在列[Oracle數據庫]中。 現在我必須創建一個存儲過程來創建類似的信息,但我必須在該特定列中匹配.Net刻度。

回答

2

我想出了整個算法,並構建了一個函數。它的工作原理就像一個魅力...

這裏有雲:

CREATE OR REPLACE FUNCTION GLOBAL.Get_DotNet_Ticks 
(
     inTimestamp IN TIMESTAMP 
) RETURN NUMBER AS 
-- ********************************************************************************** 
-- File name:   Get_DotNet_Ticks 
-- Original Author: Roberto Lopes 
-- Creation Date:  October 2012 
-- Description:  Returns the number of ticks for the provided timestamp, based 
--     on the Microsoft .Net algorithm 
-- ********************************************************************************** 
BeginDate TIMESTAMP := TO_TIMESTAMP('0001-01-03', 'YYYY-MM-DD'); --.Net Ticks are counted starting from this date 
BEGIN 
    RETURN (EXTRACT(DAY FROM(inTimestamp - BeginDate)) * 86400000 + (TO_NUMBER(TO_CHAR(inTimestamp, 'SSSSSFF3'))))*10000; 
END Get_DotNet_Ticks; 
0

Ticks propertylong,所以你需要使用一個配件的Oracle類型:「Number

+0

的想法是產生在oracle中的蜱。它不是來自任何.Net應用程序(我已經擁有)。 – Roberto

2

使用Oracle函數來計算從紀元(12:00:00午夜的秒數,1月1日,0001 ),忽略閏秒,並乘以10e6(千萬)得到蜱。

.NET時間滴答的定義被發現here

+0

這個時代是1970年 –

+0

@ColeJohnson:這是Unix時間戳的時代。但是這個問題不是關於生成Unix時間戳的。 –

1

我不熟悉Oracle PL/SQL,但以下DateToTicks() C#函數(直接從Mono的開源DateTime實現中獲取)揭示了計算滴答的細節,給出了DateTime值的各個組成部分。也許它有幫助。

祝你好運!

 public const long TicksPerDay = 864000000000L; 
     private static readonly int[] daysmonth = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 
     private static readonly int[] daysmonthleap = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 

     private static int AbsoluteDays(int year, int month, int day) { 
     int[] days; 
     int temp = 0, m = 1; 

     days = (IsLeapYear(year) ? daysmonthleap : daysmonth); 

     while(m < month) 
      temp += days[m++]; 
     return ((day - 1) + temp + (365 * (year - 1)) + ((year - 1)/4) - ((year - 1)/100) + ((year - 1)/400)); 
     } 

     public static bool IsLeapYear(int year) { 
     if(year < 1 || year > 9999) 
      throw new ArgumentOutOfRangeException(); 
     return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0); 
     } 


     internal static bool CalculateTicks(int days, int hours, int minutes, int seconds, int milliseconds, out long result) { 
     // there's no overflow checks for hours, minutes, ... 
     // so big hours/minutes values can overflow at some point and change expected values 
     int hrssec = (hours * 3600); // break point at (Int32.MaxValue - 596523) 
     int minsec = (minutes * 60); 
     long t = ((long)(hrssec + minsec + seconds) * 1000L + (long)milliseconds); 
     t *= 10000; 

     result = 0; 

     bool overflow = false; 
     // days is problematic because it can overflow but that overflow can be 
     // "legal" (i.e. temporary) (e.g. if other parameters are negative) or 
     // illegal (e.g. sign change). 
     if(days > 0) { 
      long td = TicksPerDay * days; 
      if(t < 0) { 
       long ticks = t; 
       t += td; 
       // positive days -> total ticks should be lower 
       overflow = (ticks > t); 
      } else { 
       t += td; 
       // positive + positive != negative result 
       overflow = (t < 0); 
      } 
     } else if(days < 0) { 
      long td = TicksPerDay * days; 
      if(t <= 0) { 
       t += td; 
       // negative + negative != positive result 
       overflow = (t > 0); 
      } else { 
       long ticks = t; 
       t += td; 
       // negative days -> total ticks should be lower 
       overflow = (t > ticks); 
      } 
     } 

     if(overflow) { 
      return false; 
     } 

     result = t; 
     return true; 
     } 

     public static bool DateToTicks (int year, int month, int day, int hour, int minute, int second, int millisecond, out long result) { 
     return CalculateTicks(AbsoluteDays(year, month, day), hour, minute, second, millisecond, out result); 
     }