コード例 #1
0
 private static string CompletionTimeSql(SiteSettings ss)
 {
     return(Def.Sql.CompletionTimeColumn.Replace(
                "#DifferenceOfDates#",
                TimeExtensions.DifferenceOfDates(
                    ss.GetColumn("CompletionTime")?.EditorFormat, minus: true).ToString()));
 }
コード例 #2
0
ファイル: Log.cs プロジェクト: csaam/thebreeze
        protected void WriteLog(int id, TraceEventType eventType, string message, Guid correlationId, string context,
                                Exception exception)
        {
            long filetime;

            TimeExtensions.GetSystemTimePreciseAsFileTime(out filetime);
            // string stackTrace = new StackTrace(4, true).ToString();

            var dateTime = DateTime.FromFileTimeUtc(filetime).ToString("HH:mm:ss.ffff");

            string output;

            if (exception == default(Exception))
            {
                output = string.Format("Time={0}, Message={1}, CorrelationId={2}, Context={3}", dateTime, message,
                                       correlationId, context);
            }
            else
            {
                output = string.Format("Time={0}, Message={1}, CorrelationId={2}, Context={3}, Exception={4}", dateTime,
                                       message, correlationId, context, exception);
            }

            output = output.Replace(Environment.NewLine, string.Empty);
            traceSource.TraceEvent(eventType, id, output);
        }
コード例 #3
0
        public void It_should_sleep_if_we_rollover_twice_in_the_same_millisecond()
        {
            var worker = new WakingIdWorker(1, 1);
            var iter   = new List <long>()
            {
                2, 2, 3
            };
            int         idx      = 0;
            Func <long> timeFunc = () =>
            {
                var res = iter[idx++];
                if (idx > iter.Count - 1)
                {
                    idx = 0;
                }
                return(res);
            };

            using (TimeExtensions.StubCurrentTime(timeFunc))
            {
                worker.Sequence = 4095;
                worker.NextId();
                worker.Sequence = 4095;
                worker.NextId();
            }
            Assert.That(worker.Slept, Is.EqualTo(1));
        }
コード例 #4
0
 public override void OnActionExecuting(HttpActionContext actionContext)
 {
     Metadata.CorrelationId = Guid.Empty;
     Metadata.TimeOffset    = TimeSpan.MaxValue;
     Metadata.CallStartTime = TimeExtensions.GetPreciseUTCNow();
     foreach (var header in actionContext.Request.Headers)
     {
         if (header.Key == "CorrelationId")
         {
             Guid correlationId;
             if (Guid.TryParse(header.Value.FirstOrDefault(), out correlationId))
             {
                 Metadata.CorrelationId = correlationId;
             }
         }
         else if (header.Key == "TimeOffset")
         {
             TimeSpan timeOffset;
             if (TimeSpan.TryParse(header.Value.FirstOrDefault(), out timeOffset))
             {
                 Metadata.TimeOffset = timeOffset;
             }
         }
     }
 }
コード例 #5
0
ファイル: Act4Ship.cs プロジェクト: McIks/NosTale4All
        public static void GenerateAct4Ship(byte faction)
        {
            EventHelper.Instance.RunEvent(new EventContainer(ServerManager.Instance.GetMapInstance(ServerManager.Instance.GetBaseMapInstanceIdByMapId(261)), EventActionType.NPCSEFFECTCHANGESTATE, true));
            Act4ShipThread shipThread = new Act4ShipThread();
            DateTime       result     = TimeExtensions.RoundUp(DateTime.Now, TimeSpan.FromMinutes(5));

            Observable.Timer(result - DateTime.Now).Subscribe(X => shipThread.Run(faction));
        }
        private DateTime getIosUtcDateTime(LocalNotification iOSNotification)
        {
            var userInfo = iOSNotification.userInfo;

            if (userInfo != null && userInfo.Contains(UTC_DATE_KEY))
            {
                return(TimeExtensions.utcDateTimeFromFileTimeString((string)userInfo[UTC_DATE_KEY], DateTime.MinValue));
            }
            return(DateTime.MinValue);
        }
コード例 #7
0
ファイル: ControllerBase.cs プロジェクト: csaam/thebreeze
        public async Task <T> ProtectedPutAsync([FromBody] T employee,
                                                CancellationToken cancellationToken = default(CancellationToken))
        {
            DateTimeOffset now = TimeExtensions.GetPreciseUTCNow();

            employee.ModifiedTime = now;
            DynamoDBContext context = new DynamoDBContext(Settings.AmazonDynamoDBClient);
            await context.SaveAsync(employee, cancellationToken);

            return(employee);
        }
コード例 #8
0
        public async Task <TenTwentyAgency> PutAsync([FromBody] TenTwentyAgency tenTwentyAgency,
                                                     CancellationToken cancellationToken = default(CancellationToken))
        {
            var now = TimeExtensions.GetPreciseUTCNow();

            tenTwentyAgency.ModifiedTime = now;
            var context = new DynamoDBContext(Settings.AmazonDynamoDBClient);
            await context.SaveAsync(tenTwentyAgency, cancellationToken);

            return(tenTwentyAgency);
        }
コード例 #9
0
ファイル: ControllerBase.cs プロジェクト: csaam/thebreeze
        protected async Task <T> ProtectedPostAsync(Guid agencyId, [FromBody] T employee, CancellationToken cancellationToken = default(CancellationToken))
        {
            DateTimeOffset now = TimeExtensions.GetPreciseUTCNow();

            employee.AgencyId    = agencyId;
            employee.CreatedTime = employee.ModifiedTime = now;
            employee.InstanceId  = prefix + Guid.NewGuid().ToString();
            DynamoDBContext context = new DynamoDBContext(Settings.AmazonDynamoDBClient);
            await context.SaveAsync(employee, cancellationToken);

            return(employee);
        }
コード例 #10
0
        public async Task <TenTwentyAgency> PostAsync([FromBody] TenTwentyAgency tenTwentyAgency,
                                                      CancellationToken cancellationToken = default(CancellationToken))
        {
            var now = TimeExtensions.GetPreciseUTCNow();

            tenTwentyAgency.AgencyId    = Guid.NewGuid();
            tenTwentyAgency.CreatedTime = tenTwentyAgency.ModifiedTime = now;
            tenTwentyAgency.InstanceId  = Settings.AgenciesRangeKeyValue;
            var context = new DynamoDBContext(Settings.AmazonDynamoDBClient);
            await context.SaveAsync(tenTwentyAgency, cancellationToken);

            return(tenTwentyAgency);
        }
コード例 #11
0
        public void It_should_generate_1_million_ids_quickly()
        {
            var worker = new IdWorker(31, 31);
            var t      = TimeExtensions.CurrentTimeMillis();

            for (int i = 0; i < 1000000; i++)
            {
                var id = worker.NextId();
            }
            var t2 = TimeExtensions.CurrentTimeMillis();

            Console.WriteLine("generated 1000000 ids in {0} ms, or {1} ids/second", t2 - t, 1000000000.0 / (t2 - t));
        }
コード例 #12
0
        public void It_should_properly_mask_timestamp()
        {
            var worker = new IdWorker(31, 31);

            for (var i = 0; i < 100; i++)
            {
                var t = TimeExtensions.CurrentTimeMillis();
                using (TimeExtensions.StubCurrentTime(t))
                {
                    var id       = worker.NextId();
                    var actual   = (((ulong)id & TimestampMask) >> 22);
                    var expected = (t - IdWorker.Twepoch);
                    Assert.That(expected, Is.EqualTo(actual));
                }
            }
        }
コード例 #13
0
ファイル: Cruise.cs プロジェクト: Tmalmborg85/Hankies.Domain
        internal Status <Avatar> ExtendTime(Status <Avatar> response, Avatar sender
                                            , TimeExtension extension)
        {
            try
            {
                response = IsCorrectSender(response, sender);
                if (response.IsSuccess())
                {
                    TimeExtensions.Add(extension);
                }
            }
            catch (Exception ex)
            {
                response.AddException(ex);
            }

            return(response);
        }
コード例 #14
0
        public void scheduleLocalNotification(LocalNotificationData notificationData)
        {
            if (!isInitialized)
            {
                return;
            }
            var timeSpan    = TimeExtensions.hoursToTimeSpan(notificationData.triggerInHours);
            var timeTrigger = new iOSNotificationTimeIntervalTrigger()
            {
                TimeInterval = timeSpan,
                Repeats      = notificationData.isRepeatingNotification
            };

            notificationData.utcScheduledTime = TimeExtensions.currentUtcTime.Add(timeSpan);
            iOSNotification notification = createNotification(notificationData, timeTrigger);

            iOSNotificationCenter.ScheduleNotification(notification);
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
                                        JsonSerializer serializer)
        {
            if (objectType != typeof(TradeOverlayItem))
            {
                throw new NotImplementedException("Custom json converter wrong type.");
            }
            JToken jToken = JToken.Load(reader);
            var    arr    = jToken.ToObject <JToken[]>();
            var    res    = new TradeOverlayItem();

            res.DateTime = TimeExtensions.FromUniversalDateTime(arr[0].ToObject <double>());
            res.Price    = arr[1].ToObject <double>();
            res.Type     = arr[2].ToObject <TradeMarkerType>();
            if (arr.Length > 3)
            {
                res.Label = arr[3].ToObject <string>();
            }
            return(res);
        }
コード例 #16
0
 public void scheduleLocalNotification(LocalNotificationData notificationData)
 {
     if (isInitialized)
     {
         if (!notificationData.isRepeatingNotification)
         {
             Manager.Instance.ScheduleNotification(notificationData.triggerInHours.hoursToSeconds(),
                                                   notificationData.title, notificationData.text, notificationData.id,
                                                   notificationProfile: notificationData.profile, badgeNumber: notificationData.badge);
         }
         else
         {
             Manager.Instance.ScheduleNotificationRepeating(notificationData.triggerInHours.hoursToSeconds(),
                                                            notificationData.intervalInHours.hoursToSeconds(), notificationData.title, notificationData.text,
                                                            notificationData.id, notificationProfile: notificationData.profile, badgeNumber: notificationData.badge);
         }
         var timeSpan = TimeExtensions.hoursToTimeSpan(notificationData.triggerInHours);
         notificationData.utcScheduledTime = TimeExtensions.currentUtcTime.Add(timeSpan);
     }
 }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
                                        JsonSerializer serializer)
        {
            if (objectType != typeof(OverlayItem))
            {
                throw new NotImplementedException("Custom json converter wrong type.");
            }
            JToken jToken = JToken.Load(reader);
            var    arr    = jToken.ToObject <double[]>();
            var    res    = new OverlayItem();

            if (arr.Length > 0)
            {
                res.DateTime = TimeExtensions.FromUniversalDateTime(arr[0]);
            }
            if (arr.Length > 1)
            {
                res.Value = arr[1];
            }
            return(res);
        }
コード例 #18
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
                                        JsonSerializer serializer)
        {
            if (objectType != typeof(OhlcvItem))
            {
                throw new NotImplementedException("Custom json converter wrong type.");
            }
            var jToken = JToken.Load(reader);
            var arr    = jToken.ToObject <double[]>();
            var res    = new OhlcvItem();

            if (arr.Length > 0)
            {
                res.DateTime = TimeExtensions.FromUniversalDateTime(arr[0]);
            }
            if (arr.Length > 1)
            {
                res.Open = arr[1];
            }
            if (arr.Length > 2)
            {
                res.High = arr[2];
            }
            if (arr.Length > 3)
            {
                res.Low = arr[3];
            }
            if (arr.Length > 4)
            {
                res.Close = arr[4];
            }
            if (arr.Length > 5)
            {
                res.Volume = arr[5];
            }
            return(res);
        }
コード例 #19
0
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            TimeSpan        duration  = TimeExtensions.GetPreciseUTCNow() - Metadata.CallStartTime;
            IUnityContainer container = UnityConfig.GetConfiguredContainer();
            ILog            log       = container.Resolve <ILog>();

            var context = new
            {
                RequestUri   = actionExecutedContext.Request.RequestUri,
                Content      = actionExecutedContext.Request.Content.ReadAsStringAsync(),
                CallDuration = duration,
                HttpMethod   = actionExecutedContext.Request.Method,
                MethodName   = ((System.Web.Http.Controllers.ReflectedHttpActionDescriptor)actionExecutedContext.ActionContext.ActionDescriptor).MethodInfo.ToString(),
            };

            if (actionExecutedContext.Exception != null)
            {
                log.LogError(LogTags.EmptyTag, "Exception Invoking action", Metadata.CorrelationId, context, actionExecutedContext.Exception);
            }
            else
            {
                log.LogInfo(LogTags.EmptyTag, "Call completed successfully.", Metadata.CorrelationId, context);
            }
        }
コード例 #20
0
    static void Main()
    {
        var myTime = new Time2();   // call Time constructor

        myTime.SetTime(11, 34, 15); // set the time to 11:34:15

        // test the DisplayTime extension method
        Console.Write("Use the DisplayTime extension method: ");
        myTime.DisplayTime();

        // test the AddHours extension method
        Console.Write("Add 5 hours with the AddHours extension method: ");
        var timeAdded = myTime.AddHours(5); // add five hours

        timeAdded.DisplayTime();            // display the new Time2 object

        // add hours and display the time in one statement
        Console.Write("Add 15 hours with the AddHours extension method: ");
        myTime.AddHours(15).DisplayTime(); // add hours and display time

        // use fully qualified extension-method name to display the time
        Console.Write("Use fully qualified extension-method name: ");
        TimeExtensions.DisplayTime(myTime);
    }
コード例 #21
0
        private void InitilizeCooldownLabelUI(ref CuiElementContainer container, string kitname, TimeSpan time)
        {
            container.Add(new CuiElement
            {
                Name       = Layer + $".BlockPanel.{kitname}.Btn.Time",
                Parent     = Layer + $".BlockPanel.{kitname}",
                Components =
                {
                    new CuiRawImageComponent      {
                        Color = "0.98 0.36 0.36 1", Png = (string)ImageLibrary.Call("GetImage", "kits_item_btn_open")
                    },
                    new CuiRectTransformComponent {
                        AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "-70 25", OffsetMax = "70 60"
                    }
                }
            });

            container.Add(new CuiButton
            {
                Button        = { Color = "0 0 0 0", Command = $"kit {kitname}" },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
                Text          = { Text = TimeExtensions.FormatShortTime(time), FontSize = 18, Align = TextAnchor.MiddleCenter }
            }, Layer + $".BlockPanel.{kitname}.Btn.Time", Layer + $".BlockPanel.{kitname}.BtnCMD.Time");
        }
コード例 #22
0
        private static void updateScheduledTime(LocalNotificationData notificationData)
        {
            var timeSpan = TimeExtensions.hoursToTimeSpan(notificationData.triggerInHours);

            notificationData.utcScheduledTime = TimeExtensions.currentUtcTime.Add(timeSpan);
        }
コード例 #23
0
        private bool GiveKit(BasePlayer player, string kitname)
        {
            if (string.IsNullOrEmpty(kitname))
            {
                return(false);
            }

            if (Interface.Oxide.CallHook("canRedeemKit", player) != null)
            {
                return(false);
            }
            if (!_kits.Exists(x => x.Name == kitname))
            {
                Message(player, "ERROR.INVALID");
                return(false);
            }

            var kit = _kits.First(x => x.Name == kitname);

            if (!string.IsNullOrEmpty(kit.Permission) && !permission.UserHasPermission(player.UserIDString, kit.Permission))
            {
                Message(player, "ERROR.NOACCESS");
                return(false);
            }

            var playerData = GetPlayerData(player.userID, kitname);

            if (kit.Amount > 0 && playerData.Amount >= kit.Amount)
            {
                Message(player, "ERROR.LIMIT");
                return(false);
            }

            if (kit.Cooldown > 0)
            {
                var currentTime = GetCurrentTime();
                if (playerData.Cooldown > currentTime)
                {
                    Message(player, "ERROR.COOLDOWN", TimeExtensions.FormatTime(TimeSpan.FromSeconds(playerData.Cooldown - currentTime)));
                    return(false);
                }
            }

            int beltcount  = kit.Items.Where(i => i.Container == "belt").Count();
            int wearcount  = kit.Items.Where(i => i.Container == "wear").Count();
            int maincount  = kit.Items.Where(i => i.Container == "main").Count();
            int totalcount = beltcount + wearcount + maincount;

            if ((player.inventory.containerBelt.capacity - player.inventory.containerBelt.itemList.Count) < beltcount || (player.inventory.containerWear.capacity - player.inventory.containerWear.itemList.Count) < wearcount || (player.inventory.containerMain.capacity - player.inventory.containerMain.itemList.Count) < maincount)
            {
                if (totalcount > (player.inventory.containerMain.capacity - player.inventory.containerMain.itemList.Count))
                {
                    Message(player, "ERROR.INVENTORYFULL");
                    return(false);
                }
            }
            GiveItems(player, kit);

            if (kit.Amount > 0)
            {
                playerData.Amount += 1;
            }

            if (kit.Cooldown > 0)
            {
                playerData.Cooldown = GetCurrentTime() + kit.Cooldown;
            }

            Message(player, "KITS.GIVED", kit.DisplayName);
            return(true);
        }
コード例 #24
0
        /// <summary>
        /// This method reads the given XML file and stores each of the timeseries described
        /// therein to the database.  For each timeseries that it stores, it adds an item to
        /// list 'tsImportList', which records metadata of the timeseries that is not processed
        /// directly by TimeSeriesLibrary.  Therefore, the process that calls TimeSeriesLibrary
        /// can process tsImportList to complete the importation of the timeseries.
        /// </summary>
        /// <param name="xmlFileName">Name of the file that will be read.  If xmlText is null,
        /// then this parameter must be non-null, and vice-versa.</param>
        /// <param name="xmlText">The text of an XML file that will be read.  If xmlFileName is null,
        /// then this parameter must be non-null, and vice-versa.</param>
        /// <param name="tsImportList">List of TSImport objects that this function records for
        /// each series that is imported.  This method appends the list.</param>
        /// <param name="shouldStoreToDatabase">If true, then this method will write the timeseries from
        /// the XML file to database.  If false, then this method does not write to database.</param>
        /// <param name="shouldRecordDetails">If true, then this method stores the BLOB and detailed
        /// elements to the list of TSImport objects.  If false, then this method does not store
        /// the BLOB to the TSImport object, and all fields that TimeSeriesLibrary does not process
        /// are stored to the TSImport object's UnprocessedElements field.</param>
        /// <returns>The number of time series records that were successfully stored</returns>
        public int ReadAndStore(
            String xmlFileName, String xmlText,
            List <TSImport> tsImportList,
            Boolean shouldStoreToDatabase, Boolean shouldRecordDetails)
        {
            String s;                                                                               // ephemeral String object
            int    numTs = 0;                                                                       // The # of time series successfuly processed by this method

            TSDateCalculator.TimeStepUnitCode TimeStepUnit = TSDateCalculator.TimeStepUnitCode.Day; // to be read from XML
            short    TimeStepQuantity = 1;                                                          // to be read from XML
            DateTime StartDate        = _defaultTime;                                               // to be read from XML

            double[] valueArray   = null;                                                           // to be read from XML
            var      elementNames = new List <String> {
                "TimeSeries", "Pattern"
            };

            // Flags will indicate if the XML is missing any data
            Boolean foundTimeStepUnit, foundTimeStepQuantity, foundStartDate, foundValueArray;

            // Error checks
            if (xmlFileName == null && xmlText == null)
            {
                throw new TSLibraryException(ErrCode.Enum.Xml_Memory_File_Exclusion,
                                             "The method's xmlFileName and xmlText parameters can not both be null.");
            }
            if (xmlFileName != null && xmlText != null)
            {
                throw new TSLibraryException(ErrCode.Enum.Xml_Memory_File_Exclusion,
                                             "The method's xmlFileName and xmlText parameters can not both be non-null.");
            }
            if (shouldStoreToDatabase && TSConnection == null)
            {
                throw new TSLibraryException(ErrCode.Enum.Xml_Connection_Not_Initialized,
                                             "The method is directed to store results to database, " +
                                             "but a database connection has not been assigned in the constructor.");
            }

            // Initialize a Stream object for the XmlReader object to read from.  This method can
            // be called with either the file name of an XML file, or with a string containing the
            // complete text of the XML to be parsed.  The type of Stream object that we initialize
            // depends on which parameter the method was called with.
            Stream xmlStream;

            if (xmlFileName == null)
            {
                xmlStream        = new MemoryStream(Encoding.ASCII.GetBytes(xmlText));
                ReportedFileName = "The given XML text ";
            }
            else
            {
                xmlStream        = new FileStream(xmlFileName, FileMode.Open);
                ReportedFileName = "The XML file '" + xmlFileName + "' ";
            }

            try
            {
                // Loop once for "TimeSeries" and once for "Pattern".  Note that the approach of looping
                // through the entire file twice seems undesirable, but no better option was evident because
                // methods of XmlReader such as 'ReadToNextSibling' do not have an equivalent that could
                // seek *either* "TimeSeries" or "Pattern".
                foreach (String elementName in elementNames)
                {
                    Boolean isPattern = elementName == "Pattern";
                    // Start at the beginning of the XML file
                    xmlStream.Seek(0, SeekOrigin.Begin);
                    // This XmlReader object opens the XML file and parses it for us.  The 'using'
                    // statement ensures that the XmlReader's resources are properly disposed.
                    using (XmlReader xmlReader = XmlReader.Create(xmlStream))
                    {
                        // All of the data that we'll read is contained inside an element named 'Import'
                        try
                        {
                            if (!xmlReader.ReadToFollowing("Import"))
                            {
                                throw new TSLibraryException(ErrCode.Enum.Xml_File_Empty,
                                                             ReportedFileName + "does not contain an <Import> element.");
                            }
                        }
                        catch
                        {
                            throw new TSLibraryException(ErrCode.Enum.Xml_File_Empty,
                                                         ReportedFileName + "does not contain an <Import> element.");
                        }
                        // The file must contain at least one element named 'TimeSeries'.  Move to the first
                        // such element now.
                        if (!xmlReader.ReadToDescendant(elementName))
                        {
                            // if no such element is found then there is nothing to process in this iteration
                            // of the loop.  After the loop is finished, an exception is thrown if no elements
                            // were read.
                            continue;
                        }
                        // do-while loop through all elements named 'TimeSeries'.  There will be one iteration
                        // of this loop for each timeseries in the XML file.
                        do
                        {
                            // Get a new XmlReader object that can not read outside
                            // of the current 'TimeSeries' element.
                            XmlReader oneSeriesXmlReader = xmlReader.ReadSubtree();
                            // A new TSImport object will store properties of this time series
                            // that the TimeSeriesLibrary is not designed to handle.
                            TSImport tsImport = new TSImport(shouldRecordDetails)
                            {
                                IsPattern = isPattern
                            };
                            // Flags will indicate if the XML is missing any data
                            foundTimeStepUnit = foundTimeStepQuantity = foundStartDate = foundValueArray = false;
                            // This default trace number will be used if the "Trace" attribute is not used on a <Data>
                            // element. The default trace value may be reassigned if a <TraceNumber> element is read.
                            int defaultTraceNumber = 1;
                            // Collection of Strings that hold the unparsed DataSeries.  The key of the
                            // Dictionary is the trace number of the DataSeries
                            Dictionary <int, String> DataStrings = new Dictionary <int, String>();

                            // advance the reader past the outer element
                            oneSeriesXmlReader.ReadStartElement();
                            // Read one timeseries from XML
                            while (oneSeriesXmlReader.Read())
                            {
                                Boolean binaryEncoded = false;
                                // If the current position of the reader is on an element's start tag (e.g. <Name>)
                                if (oneSeriesXmlReader.NodeType == XmlNodeType.Element)
                                {
                                    // Note that XML standard is case sensitive
                                    switch (oneSeriesXmlReader.Name)
                                    {
                                    case "Name":
                                        // <Name> is not processed by TimeSeriesLibrary.  Record it on a list
                                        // so another module can process the <Name> field.  Presumably,
                                        // the process will distinguish timeseries based on the <Name> field.
                                        tsImport.Name = oneSeriesXmlReader.ReadElementContentAsString();
                                        break;

                                    case "StartDate":
                                        // TimeSeriesLibrary will store <StartDate> to the data table
                                        s = oneSeriesXmlReader.ReadElementContentAsString();
                                        if (!TimeExtensions.TryParse(s, out StartDate, _defaultTime))
                                        {
                                            throw new TSLibraryException(ErrCode.Enum.Xml_File_StartDate_Unreadable,
                                                                         ReportedFileName
                                                                         + "contains unreadable StartDate element value " + s);
                                        }
                                        foundStartDate = true;
                                        break;

                                    case "TimeStepUnit":
                                        // TimeSeriesLibrary will store <TimeStepUnit> to the data table
                                        s                 = oneSeriesXmlReader.ReadElementContentAsString();
                                        TimeStepUnit      = ParseTimeStepUnit(s);
                                        foundTimeStepUnit = true;
                                        // If it is an irregular time series
                                        if (TimeStepUnit == TSDateCalculator.TimeStepUnitCode.Irregular)
                                        {
                                            // <TimeStepQuantity> and <StartDate> are unnecessary
                                            // and irrelevant to irregular time series
                                            foundTimeStepQuantity = true;
                                            foundStartDate        = true;
                                        }
                                        break;

                                    case "TimeStepQuantity":
                                        // TimeSeriesLibrary will store <TimeStepQuantity> to the data table
                                        s = oneSeriesXmlReader.ReadElementContentAsString();
                                        TimeStepQuantity      = ParseTimeStepQuantity(s);
                                        foundTimeStepQuantity = true;
                                        break;

                                    case "Data":
                                        // <Data> may have a TraceNumber attribute
                                        int traceNumber = 0;
                                        s = oneSeriesXmlReader.GetAttribute("Trace");
                                        if (int.TryParse(s, out traceNumber) == false)
                                        {
                                            traceNumber = 0;
                                        }
                                        if (DataStrings.ContainsKey(traceNumber))
                                        {
                                            throw new TSLibraryException(ErrCode.Enum.Xml_File_Inconsistent,
                                                                         ReportedFileName + "contains a time series with more than "
                                                                         + "one trace number " + traceNumber.ToString());
                                        }
                                        // <Data> contains a whitespace-deliminted string of values
                                        // that comprise the time series
                                        s = oneSeriesXmlReader.ReadElementContentAsString();
                                        // add the unparsed string to a dictionary
                                        // where the trace number is the dictionary key
                                        DataStrings.Add(traceNumber, s);
                                        foundValueArray = true;
                                        break;

                                    case "Encoding":
                                        // The default is that <Data> contains decimal text.
                                        // However, the <Encoding> element may specify that it is
                                        // Base64 encoded.
                                        s = oneSeriesXmlReader.ReadElementContentAsString();
                                        if (s == "Base64" || s == "base64")
                                        {
                                            binaryEncoded = true;
                                        }
                                        break;

                                    case "Apart":     // <Apart> contains the A part of record name from a HECDSS file
                                        tsImport.SetAPart(oneSeriesXmlReader); break;

                                    case "Bpart":     // <Bpart> contains the B part of record name from a HECDSS file
                                        tsImport.SetBPart(oneSeriesXmlReader); break;

                                    case "Cpart":     // <Cpart> contains the C part of record name from a HECDSS file
                                        tsImport.SetCPart(oneSeriesXmlReader); break;

                                    case "Epart":     // <Epart> contains the E part of record name from a HECDSS file
                                        tsImport.SetEPart(oneSeriesXmlReader); break;

                                    case "Units":     // <Units> contains the name of the units of measurement for the time series values
                                        tsImport.SetUnits(oneSeriesXmlReader); break;

                                    case "TimeSeriesType":
                                        // <TimeSeriesType> contains the text name of the time series type,
                                        // [PER-AVER | PER-CUM | INST-VAL | INST-CUM]
                                        tsImport.SetTimeSeriesType(oneSeriesXmlReader); break;

                                    case "TraceNumber":     // <TraceNumber> contains the trace number for an ensemble
                                        defaultTraceNumber = tsImport.GetTraceNumber(oneSeriesXmlReader); break;

                                    case "MultiplicationFactor":
                                        tsImport.SetMultiplicationFactor(oneSeriesXmlReader); break;

                                    default:
                                        // Any other tags are simply copied to the String object
                                        // 'UnprocessedElements'. Here they are stored with
                                        // the enclosing tags (e.g. "<Units>CFS</Units>").
                                        tsImport.AddUnprocessedElement(oneSeriesXmlReader.ReadOuterXml());
                                        break;
                                    }
                                }
                            }
                            // This XmlReader object was created with the ReadSubtree() method so that it would only
                            // be able to read the current time series element.  We have now reached the end of the
                            // time series element, so the XmlReader should be closed.
                            oneSeriesXmlReader.Close();
                            // The record can not be saved to the table if information for some of the fields is missing.
                            // These flags indicate whether each of the required fields was found in the XML file.
                            if (!(foundTimeStepUnit && foundTimeStepQuantity && foundStartDate && foundValueArray))
                            {
                                // One or more required fields were missing, so we'll throw an exception.
                                String errorList, nameString;
                                if (tsImport.Name == "")
                                {
                                    nameString = "unnamed time series";
                                }
                                else
                                {
                                    nameString = "time series named '" + tsImport.Name + "'";
                                }
                                errorList = "Some required subelements were missing from " + nameString
                                            + " in " + ReportedFileName + "\n";
                                if (!foundStartDate)
                                {
                                    errorList += "\n<StartDate> was not found";
                                }
                                if (!foundTimeStepUnit)
                                {
                                    errorList += "\n<TimeStepUnit> was not found";
                                }
                                if (!foundTimeStepQuantity)
                                {
                                    errorList += "\n<TimeStepQuantity> was not found";
                                }
                                if (!foundValueArray)
                                {
                                    errorList += "\n<Data> was not found";
                                }
                                throw new TSLibraryException(ErrCode.Enum.Xml_File_Incomplete, errorList);
                            }
                            // Now that we've established that all fields have been read, we can parse the
                            // string of timeseries values into an array, and save the array to the database.
                            if (TimeStepUnit == TSDateCalculator.TimeStepUnitCode.Irregular)
                            {
                                // IRREGULAR TIME SERIES

                                // The TS object is used to save one record to the database table
                                TS ts = new TS(TSConnection, TableName, TraceTableName);
                                foreach (KeyValuePair <int, String> keyValuePair in DataStrings)
                                {
                                    int traceNumber = keyValuePair.Key;
                                    if (traceNumber == 0)
                                    {
                                        traceNumber = defaultTraceNumber;
                                    }
                                    // Split the big data string into an array of strings.
                                    // The date/time/value triplets will be all collated together.
                                    String[] stringArray = keyValuePair.Value
                                                           .Split(new char[] { }, StringSplitOptions.RemoveEmptyEntries);
                                    // We'll use this date/value structure to build each item of the date/value array
                                    TSDateValueStruct tsv = new TSDateValueStruct();
                                    // allocate the array of date/value pairs
                                    TSDateValueStruct[] dateValueArray = new TSDateValueStruct[stringArray.Length / 3];
                                    // Loop through the array of strings, 3 elements at a time
                                    for (int i = 2; i < stringArray.Length; i += 3)
                                    {
                                        s                     = stringArray[i - 2] + " " + stringArray[i - 1];
                                        tsv.Date              = DateTime.Parse(s);
                                        tsv.Value             = double.Parse(stringArray[i]);
                                        dateValueArray[i / 3] = tsv;
                                    }
                                    if (tsImport.TraceList.Count == 0)
                                    {
                                        // Ignore whatever was entered in the StartDate element, since it
                                        // might conflict with the date/value entries
                                        StartDate = dateValueArray[0].Date;
                                        // Write parameters to the database and record values in the TSImport object
                                        ts.WriteParametersIrregular(shouldStoreToDatabase, tsImport,
                                                                    dateValueArray.Count(), StartDate, dateValueArray.Last().Date,
                                                                    null, null);
                                    }
                                    else
                                    {
                                        if (StartDate != ts.BlobStartDate)
                                        {
                                            throw new TSLibraryException(ErrCode.Enum.Xml_File_Inconsistent,
                                                                         ReportedFileName + "contains a time series "
                                                                         + "with traces that do not overlay each other.");
                                        }
                                    }
                                    ts.WriteTraceIrregular(0, shouldStoreToDatabase, tsImport,
                                                           traceNumber, dateValueArray);
                                }
                                tsImport.RecordFromTS(ts);
                                // Done with the TS object.
                                ts = null;
                            }
                            else
                            {
                                // REGULAR TIME SERIES

                                // The TS object is used to save one record to the database table
                                TS ts = new TS(TSConnection, TableName, TraceTableName);
                                foreach (KeyValuePair <int, String> keyValuePair in DataStrings)
                                {
                                    int traceNumber = keyValuePair.Key;
                                    if (traceNumber == 0)
                                    {
                                        traceNumber = defaultTraceNumber;
                                    }
                                    // Fancy LINQ statement turns the String object into an array of double[]
                                    valueArray = keyValuePair.Value
                                                 .Split(new char[] { }, StringSplitOptions.RemoveEmptyEntries)
                                                 .Select(z => double.Parse(z)).ToArray();
                                    if (tsImport.TraceList.Count == 0)
                                    {
                                        // Write to the database and record values in the TSImport object
                                        ts.WriteParametersRegular(shouldStoreToDatabase, tsImport,
                                                                  (short)TimeStepUnit, TimeStepQuantity, valueArray.Count(),
                                                                  StartDate, null, null);
                                    }
                                    ts.WriteTraceRegular(0, shouldStoreToDatabase, tsImport,
                                                         traceNumber, valueArray);
                                }
                                tsImport.RecordFromTS(ts);
                                // Done with the TS object.
                                ts = null;
                            }

                            // the TSImport object contains data for this timeseries that TSLibrary does not process.
                            // Add the TSImport object to a list that the calling process can read and use.
                            tsImportList.Add(tsImport);
                            numTs++;
                        } while (xmlReader.ReadToNextSibling(elementName));
                    }
                }
                if (numTs == 0)
                {
                    throw new TSLibraryException(ErrCode.Enum.Xml_File_Empty,
                                                 ReportedFileName + " does not contain any "
                                                 + elementNames.Select(ss => "<" + ss + ">").ToStringWithConjunc("or")
                                                 + " element".Pluralize(elementNames.Count) + ".");
                }
            }
            catch (XmlException e)
            {
                // An XmlException was caught somewhere in the lifetime of the object xmlReader,
                // so we can presumably say there was an error in how the XML file was formatted.
                // The information from the XmlException object is included in the error message
                // that we throw here, and the XmlException is included as an inner exception.
                throw new TSLibraryException(ErrCode.Enum.Xml_File_Malformed,
                                             ReportedFileName + "is malformed.\n\n" + e.Message, e);
            }
            finally
            {
                // Disposing the Stream object ensures that the file is closed, if applicable.
                // This is put into the 'finally' clause so that we can ensure that the Stream
                // is closed no matter how we exit this method.
                xmlStream.Dispose();
            }

            return(numTs);
        }