简体   繁体   English

在Oracle中生成.Net报价

[英]Generate a .Net ticks in Oracle

Does anybody knows how to generate a .Net DateTime.Ticks in a PL/SQL stored procedure, without having a .Net assembly in the Oracle database? 没有人知道如何在PL / SQL存储过程中生成.Net DateTime.Ticks,而在Oracle数据库中没有.Net程序集吗?

I have a service in .Net storing the DateTime.Ticks value in a column [Oracle database]. 我在.Net中有一项服务,该服务将DateTime.Ticks值存储在[Oracle数据库]列中。 Now I have to create a stored procedure to create similar information, but I have to match .Net ticks in that particular column. 现在,我必须创建一个存储过程来创建类似的信息,但必须在该特定列中匹配.Net滴答。

Use Oracle functions to calculate the number of seconds since the epoch (12:00:00 midnight, January 1, 0001), ignoring leap seconds, and multiply by 10e6 (ten million) to get ticks. 使用Oracle函数计算自纪元(0001年1月1日午夜12:00:00)以来的秒数,忽略leap秒,然后乘以10e6(一千万)以获取刻度。

The definition of .NET time ticks is found here . .NET时间刻度的定义在这里找到。

I figured out the whole algorithm and built a function. 我弄清楚了整个算法并构建了一个函数。 It works like a charm... 它就像一个魅力...

Here it goes: 它去了:

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;

I'm not familiar with Oracle PL/SQL, but the following DateToTicks() C# function (taken directly from Mono's open source DateTime implementation) reveals the details of how ticks are computed given the individual components of a DateTime value. 我不熟悉Oracle PL / SQL,但是下面的DateToTicks() C#函数(直接从Mono的开源DateTime实现中获取)揭示了给定DateTime值的各个组成部分时如何计算DateToTicks()的细节。 Perhaps it is of help. 也许有帮助。

Good Luck! 祝好运!

      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);
      }

Ticks属性long因此您需要使用合适的Oracle类型:' Number '

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM