Tìm những records nào liên quan tới ngày đã chọn (Local to UTC)
Bài toán:
- Tôi muốn lấy dữ liệu hoạt động của 1 user cụ thể trong ngày 12/08/2025 (GMT +8).
- Giả sử table Logs có các cột như sau “UserId, Data, CreatedOn (UTC)”
Cách thực hiện:
- Chuyển từ giờ local sang UTC.
- Cài đặt thời gian bắt đầu 1 ngày và kết thúc của 1 ngày
- Truy vấn theo khoảng thời gian bắt đầu và kết thúc của ngày đã chọn ở UTC
// Ngày truyền từ Front-end
DateTime localDate = new DateTime(2025, 8, 12);
// Múi giờ UTC+8
TimeZoneInfo utcPlus8 = TimeZoneInfo.FindSystemTimeZoneById("Singapore Standard Time");
// Đầu ngày (00:00:00.000)
DateTime startOfDayLocal = localDate.Date;
DateTime startOfDayUtc = TimeZoneInfo.ConvertTimeToUtc(startOfDayLocal, utcPlus8);
// Cuối ngày (23:59:59.999)
DateTime endOfDayLocal = localDate.Date.AddDays(1).AddMilliseconds(-1);
DateTime endOfDayUtc = TimeZoneInfo.ConvertTimeToUtc(endOfDayLocal, utcPlus8);
// In kết quả
Console.WriteLine("Start of day UTC: " + startOfDayUtc.ToString("yyyy-MM-dd HH:mm:ss.fff") + "Z");
Console.WriteLine("End of day UTC: " + endOfDayUtc.ToString("yyyy-MM-dd HH:mm:ss.fff") + "Z");
// Truy vấn
var checkInLogs = _context.Logs.Where(p => p.CreatedOn >= startOfDayUtc && p.CreatedOn <= endOfDayUtc).ToList();
Xây dựng phân đoạn Active của users.
Bài toán:
- Có 1 table UserActivities (ShiftId, UserId, Type, ActionDateTime)
- Type: Add, Remove (User được thêm hoặc xóa ra khỏi Shift theo thời gian nhất định)
- Yêu cầu in ra danh sách khoản thời gian nào user được thêm vào và cho đến khi bị xóa ra khỏi shift.
Cách thực hiện:
- Chia phân đoạn cho user đó
var data = new List<UserHistory>
{
new UserHistory
{
Name = "A",
CreatedOn = DateTime.Parse("08/10/2025 07:06:13"),
Type = "Add"
},
new UserHistory
{
Name = "A",
CreatedOn = DateTime.Parse("08/12/2025 07:06:13"),
Type = "Remove"
},
new UserHistory
{
Name = "A",
CreatedOn = DateTime.Parse("08/13/2025 07:06:13"),
Type = "Add"
},
new UserHistory
{
Name = "A",
CreatedOn = DateTime.Parse("08/13/2025 08:06:13"),
Type = "Remove"
},
new UserHistory
{
Name = "A",
CreatedOn = DateTime.Parse("08/13/2025 09:06:13"),
Type = "Add"
},
new UserHistory
{
Name = "A",
CreatedOn = DateTime.Parse("08/14/2025 07:06:13"),
Type = "Add"
}
};
var selectedDate = DateTime.Parse("08/13/2025 23:59:59");
var activeSegments = new List<ActiveSegment>();
var currentSegment = new Dictionary<string, DateTime>();
var filteredData = data.Where(p => p.CreatedOn <= selectedDate).OrderBy(p => p.CreatedOn);
foreach (var segment in filteredData)
{
var userName = segment.Name;
DateTime startTime;
var currentItem = currentSegment.TryGetValue(segment.Name, out startTime);
if(currentItem == false)
{
// Create new segment
currentSegment[userName] = segment.CreatedOn;
}
else
{
if(segment.Type == "Remove")
{
activeSegments.Add(new ActiveSegment
{
Name = userName,
Start = startTime,
End = segment.CreatedOn
});
currentSegment.Remove(userName);
}
}
}
// Acc to active segment if user is dont have End
var dontRemoved = currentSegment;
foreach (var item in dontRemoved)
{
activeSegments.Add(new ActiveSegment
{
Name = item.Key,
Start = item.Value
});
}
foreach (var item in activeSegments)
{
Console.WriteLine($"{item.Name}, {item.Start}, {item.End}");
}
To be continue……