【问题标题】:Generate a .Net ticks in Oracle在 Oracle 中生成 .Net 报价
【发布时间】:2012-09-28 16:27:30
【问题描述】:

是否有人知道如何在 PL/SQL 存储过程中生成 .Net DateTime.Ticks,而无需在 Oracle 数据库中使用 .Net 程序集?

我在 .Net 中有一项服务,将 DateTime.Ticks 值存储在 [Oracle 数据库] 列中。 现在我必须创建一个存储过程来创建类似的信息,但我必须匹配该特定列中的 .Net 刻度。

【问题讨论】:

    标签: c# .net oracle plsql


    【解决方案1】:

    使用 Oracle 函数计算从纪元(0001 年 1 月 1 日午夜 12:00:00)开始的秒数,忽略闰秒,乘以 10e6(一千万)得到滴答声。

    .NET时间刻度的定义见here

    【讨论】:

    • @ColeJohnson:这是 Unix 时间戳的时代。但这个问题与生成 Unix 时间戳无关。
    【解决方案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;
    

    【讨论】:

      【解决方案3】:

      我不熟悉 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);
            }
      

      【讨论】:

        【解决方案4】:

        Ticks propertylong,因此您需要使用合适的 Oracle 类型:'Number'

        【讨论】:

        • 这个想法是在 oracle 中生成刻度。它不是来自任何 .Net 应用程序(我已经拥有)。
        猜你喜欢
        • 1970-01-01
        • 2014-01-03
        • 2014-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多