private void SetTimerStart(TimerCounter timerCounter, DateTimeOffset localClientTime) { timerCounter.TimerStartLocal = localClientTime; timerCounter.TimerStartLocalTime = localClientTime.TimeOfDay; timerCounter.TimerStart = localClientTime.UtcDateTime; timerCounter.TimerStartUtc = localClientTime.ToUniversalTime(); }
private async Task CreateTimerResults(TimerCounter timerCounter) { var userId = await GetUserId(); if (timerCounter == null) return; try { // remove previous results, if any var results = await _context.TimerResults.Where(e => e.TimerCounterId == timerCounter.TimerCounterId && e.DiteUserId == userId).ToListAsync(); if (results != null) _context.TimerResults.RemoveRange(results); } catch (Exception ex) { // required connection string parameter - MultipleActiveResultSets=True throw new Exception("error removing old results", ex); } DateTimeOffset localStart = timerCounter.TimerStartLocal; DateTimeOffset localEnd = timerCounter.TimerEndLocal; // first end var nextEnd = new DateTimeOffset(localStart.Year, localStart.Month, localStart.Day, localStart.Hour, 0, 0, localStart.Offset); nextEnd = nextEnd.AddHours(1); if(nextEnd>localEnd) { // within same hour; only result TimerResult result = NewTimerResult(timerCounter, userId, localStart, localEnd); _context.TimerResults.Add(result); return; } else { // first hour; first result TimerResult result = NewTimerResult(timerCounter, userId, localStart, nextEnd); _context.TimerResults.Add(result); // sequence var nextStart = new DateTimeOffset(localStart.Year, localStart.Month, localStart.Day, localStart.Hour, 0, 0, localStart.Offset); while ((nextStart = nextStart.AddHours(1)) < localEnd && ((nextEnd = nextEnd.AddHours(1)) < localEnd)) { var seqResult = NewTimerResult(timerCounter, userId, nextStart, nextEnd); _context.TimerResults.Add(seqResult); } // last hour; last result TimerResult resultLast = NewTimerResult(timerCounter, userId, nextStart, localEnd); _context.TimerResults.Add(resultLast); } }
private static TimerResult NewTimerResult(TimerCounter timerCounter, Guid userId, DateTimeOffset localStart, DateTimeOffset localEnd) { var seconds = (localEnd - localStart).TotalSeconds; var result = new TimerResult { TimerResultId = Guid.NewGuid(), DiteUserId = userId, Seconds = seconds, TimerCounterId = timerCounter.TimerCounterId, Name = timerCounter.TimerHandler.Name, TimerHandlerId = timerCounter.TimerHandlerId, /* hour */ MinuteOfHour = 0, //localStart.Minute, HourOfDay = localStart.Hour, /* day */ DayOfYear = localStart.DayOfYear, DayOfMonth = localStart.Day, DayOfWeek = localStart.DayOfWeek.ToString(), /* week */ WeekOfYear = localStart.LocalDateTime.GetWeekOfYear(), WeekOfMonth = localStart.LocalDateTime.GetWeekOfMonth(), /* month */ MonthOfYear = localStart.Month, /* year */ Year = localStart.Year }; return result; }
public async Task<IActionResult> PostTimerCounter([FromRoute] Guid timerId, [FromQuery] DateTimeOffset clientLocalTime) { var userId = await GetUserId(); if (!ModelState.IsValid) { return HttpBadRequest(ModelState); } var timerCounter = new TimerCounter(); timerCounter.DiteUserId = userId; timerCounter.TimerCounterId = Guid.NewGuid(); SetTimerStart(timerCounter, clientLocalTime); SetTimerEnd(timerCounter, clientLocalTime); timerCounter.IsRunning = true; timerCounter.TimerHandlerId = timerId; timerCounter.Seconds = 0; var currentList = _context.TimerCounters .Include(e => e.TimerHandler) .Where(e => e.IsRunning && e.DiteUserId == userId).ToList(); foreach(var current in currentList) { current.IsRunning = false; current.TimerHandler.IsRunning = false; SetTimerEnd(current, timerCounter.TimerStartLocal); current.Seconds = (current.TimerEndUtc - current.TimerStartUtc).TotalSeconds; await CreateTimerResults(current); } _context.TimerCounters.Add(timerCounter); // reset isrunning await _context.TimerHandlers .Where(e => e.IsRunning && e.DiteUserId == userId) .ForEachAsync(e => e.IsRunning = false); // set new is running await _context.TimerHandlers .Where(e => e.TimerHandlerId == timerId && e.DiteUserId == userId) .ForEachAsync(e => e.IsRunning = true); try { await _context.SaveChangesAsync(); } catch (DbUpdateException) { var exists = await TimerCounterExists(timerCounter.TimerCounterId); if (exists) { return new HttpStatusCodeResult(StatusCodes.Status409Conflict); } else { throw; } } return CreatedAtRoute("GetTimerCounter", new { id = timerCounter.TimerCounterId }, timerCounter); }