Microsoft.JScript.DatePrototype.ParseDate C# (CSharp) Méthode

ParseDate() static private méthode

static private ParseDate ( String str ) : double
str String
Résultat double
      internal static double ParseDate(String str){
        long Nil = 0x80000000;

        int AmPm = 0;
        int BcAd = 0;
        Ps ps = Ps.Initial;
        long Year = Nil;
        long Month = Nil;
        long Date = Nil;
        long Time = Nil;
        long Zone = Nil;
        long Offset = Nil;

        str = str.ToLowerInvariant();

        int i = 0, n = str.Length;
        while (i < n){
          char ch = str[i++];
          if (ch <= ' ')
            continue;
          switch (ch){
            case '(':
              // skip stuff in parens
              for (int depth = 1; i < n; ){
                ch = str[i++];
                if (ch == '(')
                  depth++;
                else if (ch == ')' && --depth <= 0)
                  break;
              }
              continue;
            case ',':
              continue;
            case ':':
              continue;
            case '/':
              continue;
            case '+':
              if (Nil != Year)
                ps = Ps.AddOffset;
              continue;
            case '-':
              if (Nil != Year)
                ps = Ps.SubOffset;
              continue;
            default:
              break;
          }

          if (isalpha(ch)){  //scan an alpha token
            int j = i-1; //remember start of token
            while (i < n){
              ch = str[i++];
              if (isalpha(ch) || '.' == ch) continue;
              break;
            }

            int cch = i - j - (i < n ? 1 : 0);
            if ('.' == str[i-(i < n ? 2 : 1)]) //Exclude a trailing dot from the token
              cch--;

            // skip over any spaces
            while (ch == ' ' && i < n) ch = str[i++];

            // have an alphabetic token - look it up

            if (1 == cch){
              // military version of time zone
              // z = GMT
              // j isn't used
              // a to m are -1 to -12
              // n to y are 1 to 12
              if (Nil != Zone)
                return Double.NaN;
              char chj = str[j];
              if (chj <= 'm'){
                if (chj == 'j' || chj < 'a')
                  return Double.NaN;
                Zone = -(long)(chj - 'a' + (chj < 'j'?1:0)) * 60;
              }else if (chj <= 'y')
                Zone = (long)(chj - 'm') * 60;
              else if (chj == 'z')
                Zone = 0;
              else
                return Double.NaN;

              // look for a time zone offset
              if ('+' == ch){
                ps = Ps.AddOffset;
              }else if ('-' == ch){
                ps = Ps.SubOffset;
              }else
                ps = Ps.Initial;

              continue;
            }

            for (int kk = Strings.Length-1; kk >= 0; kk--){
              String tkstr = Strings[kk];
              if (tkstr.Length < cch) continue;
              if (0 != String.CompareOrdinal(str, j, tkstr, 0, cch)){
                if (kk == 0) return Double.NaN; //The current token does not match anything. Date string cannot be parsed by this routine.
              }else{
                switch (Tokens[kk]){
                  case Tk.BcAd :
                    if (0 != BcAd) return Double.NaN;
                    BcAd = Values[kk];
                    break;
                  case Tk.AmPm :
                    if (0 != AmPm) return Double.NaN;
                    AmPm = Values[kk];
                    break;
                  case Tk.Month :
                    if (Nil != Month) return Double.NaN;
                    Month = Values[kk];
                    break;
                  case Tk.Zone :
                    if (Nil != Zone) return Double.NaN;
                    Zone = Values[kk];

                    // look for a time zone offset
                    if ('+' == ch){
                      ps = Ps.AddOffset; i++;
                    }else if ('-' == ch){
                      ps = Ps.SubOffset; i++;
                    }else
                      ps = Ps.Initial;
                    break;
                }
                break; //out of the loop matching the current token with known tokens
              }
            }
            if (i < n) i--;
            continue; //with overall loop, looking for next bit of date
          }

          if (!isdigit(ch))
            return Double.NaN;

          int T = 0, k = i;
          do{
            T = T * 10 + ch - '0';
            if (i >= n) break;
            ch = str[i++];
          }while (isdigit(ch));

          // to avoid overflow
          if (i - k > 6)
            return Double.NaN;

          // skip over any spaces
          while (ch == ' ' && i < n) ch = str[i++];

          switch (ps){
            case Ps.AddOffset:
              if (Nil != Offset)
                return Double.NaN;
              Offset = T < 24 ? T * 60 : (T % 100) + (T / 100) * 60; //> 24 implies hhmm
              ps = Ps.Initial;
              if (i < n) i--;
              break;

            case Ps.SubOffset:
              if (Nil != Offset)
                return Double.NaN;
              Offset = T < 24 ? -T * 60 : -((T % 100) + (T / 100) * 60); //> 24 implies hhmm
              ps = Ps.Initial;
              if (i < n) i--;
              break;

            case Ps.Minutes:
              if (T >= 60)
                return Double.NaN;
              Time += T * 60;
              if (ch == ':'){
                ps = Ps.Seconds;
              }else{
                ps = Ps.Initial;
                if (i < n) i--;
              }
              break;

            case Ps.Seconds:
              if (T >= 60)
                return Double.NaN;
              Time += T;
              ps = Ps.Initial;
              if (i < n) i--;
              break;

            case Ps.Date:
              if (Nil != Date)
                return Double.NaN;
              Date = T;
              if ('/' == ch || '-' == ch){
                ps = Ps.Year;
              }else{
                ps = Ps.Initial;
                if (i < n) i--;
              }
              break;

            case Ps.Year:
              if (Nil != Year)
                return Double.NaN;
              Year = T;
              ps = Ps.Initial;
              if (i < n) i--;
              break;

            default:
              //Assert(ps == Ps.Initial);
              if (T >= 70){
                // assume it's a year
                if (Nil != Year)
                  return Double.NaN;
                Year = T;
                if (i < n) i--;
                break;
              }

              switch (ch){
                case ':':
                  // hour
                  if (Nil != Time)
                    return Double.NaN;
                  if (T >= 24)
                    return Double.NaN;
                  Time = T * 3600;
                  ps = Ps.Minutes;
                  break;

                case '/': goto case '-';

                case '-':
                  // month
                  if (Nil != Month)
                    return Double.NaN;
                  Month = T - 1;
                  ps = Ps.Date;
                  break;

                default:
                  // date
                  if (Nil != Date)
                    return Double.NaN;
                  Date = T;
                  if (i < n) i--;
                  break;
              }
            break;
          }
        }

        if (Nil == Year || Nil == Month || Nil == Date)
          return Double.NaN;

        if (0 != BcAd){
          if (BcAd < 0)
            // BC. Note that 1 BC is year 0 and 2 BC is year -1.
            Year = -Year + 1;
        }else if (Year < 100)
          Year += 1900;

        if (0 != AmPm){
          if (Nil == Time)
            return Double.NaN;
          if (Time >= 12 * 3600 && Time < 13 * 3600){
            // In the 12:00 hour. AM means subtract 12 hours and PM means
            // do nothing.
            if (AmPm < 0)
              Time -= 12 * 3600;
          }else{
            // Not in the 12:00 hour. AM means do nothing and PM means
            // add 12 hours.
            if (AmPm > 0){
              if (Time >= 12 * 3600)
                return Double.NaN;
              Time += 12 * 3600;
            }
          }
        }else if (Nil == Time)
          Time = 0;

        bool Utc = false;
        if (Nil != Zone){
          Time -= Zone * 60;
          Utc = true;
        }
        if (Nil != Offset)
          Time -= Offset * 60;

        // Rebuild time.
        double result = MakeDate(MakeDay(Year, Month, Date), Time*1000);
        if (!Utc)
          result = UTC(result);
        return result;
      }

Usage Example

Exemple #1
0
 public static double parse(String str)
 {
     return(DatePrototype.ParseDate(str));
 }