コード例 #1
0
 static void StrftimeFunc(FuncContext fctx, int argc, Mem[] argv)
 {
     {
         DateTime x = new DateTime();
         ulong n;
         int i, j;
         StringBuilder z;
         string fmt = Vdbe.Value_Text(argv[0]);
         StringBuilder zdtBuf = new StringBuilder(100);
         Mem[] argv1 = new Mem[argc - 1];
         for (i = 0; i < argc - 1; i++)
             argv[i + 1]._memcpy(ref argv1[i]);
         if (fmt == null || IsDate(fctx, argc - 1, argv1, out x)) return;
         Context ctx = Vdbe.Context_Ctx(fctx);
         for (i = 0, n = 1; i < fmt.Length; i++, n++)
         {
             if (fmt[i] == '%')
             {
                 switch ((char)fmt[i + 1])
                 {
                     case 'd':
                     case 'H':
                     case 'm':
                     case 'M':
                     case 'S':
                     case 'W':
                         n++;
                         break;
                     // fall thru
                     case 'w':
                     case '%':
                         break;
                     case 'f':
                         n += 8;
                         break;
                     case 'j':
                         n += 3;
                         break;
                     case 'Y':
                         n += 8;
                         break;
                     case 's':
                     case 'J':
                         n += 50;
                         break;
                     default:
                         return; // ERROR.  return a NULL
                 }
                 i++;
             }
         }
         C.ASSERTCOVERAGE(n == (ulong)(zdtBuf.Length - 1));
         C.ASSERTCOVERAGE(n == (ulong)zdtBuf.Length);
         C.ASSERTCOVERAGE(n == (ulong)ctx.Limits[(int)LIMIT.LENGTH] + 1);
         C.ASSERTCOVERAGE(n == (ulong)ctx.Limits[(int)LIMIT.LENGTH]);
         if (n < (ulong)zdtBuf.Capacity)
             z = zdtBuf;
         else if (n > (ulong)ctx.Limits[(int)LIMIT.LENGTH])
         {
             Vdbe.Result_ErrorOverflow(fctx);
             return;
         }
         else
         {
             z = new StringBuilder((int)n);
             if (z == null)
             {
               Vdbe.Result_ErrorNoMem(fctx);
               return;
             }
         }
         ComputeJD(x);
         ComputeYMD_HMS(x);
         for (i = j = 0; i < fmt.Length; i++)
         {
             if (fmt[i] != '%')
                 z.Append((char)fmt[i]);
             else
             {
                 i++;
                 _zdtTemp.Length = 0;
                 switch ((char)fmt[i])
                 {
                     case 'd': C.__snprintf(_zdtTemp, 3, "%02d", x.D); z.Append(_zdtTemp); j += 2; break;
                     case 'f':
                         {
                             double s = x.s;
                             if (s > 59.999) s = 59.999;
                             C.__snprintf(_zdtTemp, 7, "%06.3f", s);
                             z.Append(_zdtTemp);
                             j = z.Length;
                             break;
                         }
                     case 'H': C.__snprintf(_zdtTemp, 3, "%02d", x.h); z.Append(_zdtTemp); j += 2; break;
                     case 'W': // Fall thru
                     case 'j':
                         {
                             DateTime y = new DateTime();
                             x.memcopy(y);
                             y.ValidJD = false;
                             y.M = 1;
                             y.D = 1;
                             ComputeJD(y);
                             int days = (int)((x.JD - y.JD + 43200000) / 86400000); ; // Number of days since 1st day of year
                             if (fmt[i] == 'W')
                             {
                                 int wd = (int)(((x.JD + 43200000) / 86400000) % 7);  // 0=Monday, 1=Tuesday, ... 6=Sunday
                                 C.__snprintf(_zdtTemp, 3, "%02d", (days + 7 - wd) / 7);
                                 z.Append(_zdtTemp);
                                 j += 2;
                             }
                             else
                             {
                                 C.__snprintf(_zdtTemp, 4, "%03d", days + 1);
                                 z.Append(_zdtTemp);
                                 j += 3;
                             }
                             break;
                         }
                     case 'J':
                         {
                             C.__snprintf(_zdtTemp, 20, "%.16g", x.JD / 86400000.0);
                             z.Append(_zdtTemp);
                             j = z.Length;
                             break;
                         }
                     case 'm': C.__snprintf(_zdtTemp, 3, "%02d", x.M); z.Append(_zdtTemp); j += 2; break;
                     case 'M': C.__snprintf(_zdtTemp, 3, "%02d", x.m); z.Append(_zdtTemp); j += 2; break;
                     case 's':
                         {
                             C.__snprintf(_zdtTemp, 30, "%lld", (long)(x.JD / 1000 - 210866760000L));
                             z.Append(_zdtTemp);
                             j = z.Length;
                             break;
                         }
                     case 'S': C.__snprintf(_zdtTemp, 3, "%02d", (int)x.s); z.Append(_zdtTemp); j += 2; break;
                     case 'w':
                         {
                             z.Append((((x.JD + 129600000) / 86400000) % 7));
                             break;
                         }
                     case 'Y':
                         {
                             C.__snprintf(_zdtTemp, 5, "%04d", x.Y);
                             z.Append(_zdtTemp);
                             j = z.Length;
                             break;
                         }
                     default: z.Append('%'); break;
                 }
             }
         }
         Vdbe.Result_Text(fctx, z, -1, z == (zdtBuf ? DESTRUCTOR_TRANSIENT : DESTRUCTOR_DYNAMIC);
     }
 }