c# - “获取一个地方的开放和关闭时间,如果 DateTime.Now 介于标记为开放之间”在本地工作,但在发布后不在服务器上
问题描述
我在本地调试与在服务器上发布时遇到问题。
我需要知道一家商店是否在 2 次之间营业,例如:
if ((timeNow >= openHour) && (timeNow <= closeHour))
如果是,请告诉用户商店是关闭还是营业。
编辑
我的问题基本上是: 每分钟更新商店状态的 Cron 作业会查询商店的时区,并且每个商店都会将其 DateTime.UtcNow 调整到该时区,它在本地调试时有效,但在我发布代码和查询时无效商店的状态。
这是我正在尝试做的事情:
StoreHours.cs
public class StoreHour : AuditableEntities
{
public StoreHour()
{
}
public Guid StoreHourId { get; set; }
public Guid DayOfTheWeekId { get; set; }
public virtual DayOfTheWeek DayOfTheWeek { get; set; }
public DateTime OpenHour { get; set; }
public DateTime CloseHour { get; set; }
public Guid PlaceId { get; set; }
public virtual Place Place { get; set; }
}
AppDbContext.cs(种子数据)
// Hours for the first store
var cscOpeningHour = DateTime.ParseExact("11:30:00 AM", "hh:mm:ss tt", CultureInfo.InvariantCulture);
cscOpeningHour = DateTime.SpecifyKind(cscOpeningHour, DateTimeKind.Utc);
var cscClosingHour = DateTime.ParseExact("10:00:00 PM", "hh:mm:ss tt", CultureInfo.InvariantCulture);
cscClosingHour = DateTime.SpecifyKind(cscClosingHour, DateTimeKind.Utc);
// Hours for the second store ( have multiple because closing time is the next day ( 02:00:00 AM )
var jOpeningHour1 = DateTime.ParseExact("12:00:00 AM", "hh:mm:ss tt", CultureInfo.InvariantCulture);
jOpeningHour1 = DateTime.SpecifyKind(jOpeningHour1, DateTimeKind.Utc);
var jClosingHour1 = DateTime.ParseExact("02:00:00 AM", "hh:mm:ss tt", CultureInfo.InvariantCulture);
jClosingHour1 = DateTime.SpecifyKind(jClosingHour1, DateTimeKind.Utc);
var jOpeningHour2 = DateTime.ParseExact("05:00:00 PM", "hh:mm:ss tt", CultureInfo.InvariantCulture);
jOpeningHour2 = DateTime.SpecifyKind(jOpeningHour2, DateTimeKind.Utc);
var jClosingHour2 = DateTime.ParseExact("11:59:59 PM", "hh:mm:ss tt", CultureInfo.InvariantCulture);
jClosingHour2 = DateTime.SpecifyKind(jClosingHour2, DateTimeKind.Utc);
// Seed data
modelBuilder.Entity<StoreHour>().HasData(new StoreHour
{
StoreHourId = Guid.NewGuid(),
DayOfTheWeekId = mondayDayOfTheWeekId,
OpenHour = cscOpeningHour,
CloseHour = cscClosingHour,
PlaceId = cscPlaceId
});
更新DeviceCommandHandler.cs
public async Task<Unit> Handle(UpdateDeviceCommand request, CancellationToken cancellationToken)
{
var devices = await repository.GetAllDevicesWithRelatedData();
foreach (var device in devices)
{
var count = await repository.GetNumber(device.DeviceId);
var thePlace = await placeRepository.GetPlaceByIdWithRelatedData(device.Place.PlaceId);
var timeNow = TimeZoneInfo.ConvertTime(
DateTime.Now,
TimeZoneInfo.FindSystemTimeZoneById(thePlace.Timezone.Name));
var day = DateTime.UtcNow.DayOfWeek.ToString();
if (thePlace.StoreHours.Count() > 7)
{
// OpenHour and CloseHour are DateTime properties
// returns "12:00:00 AM"
var openHour1 = thePlace.StoreHours.OrderBy(d => d.OpenHour).Select(d => d.OpenHour).First().ToString("hh:mm:ss tt");
// returns "2:00:00 AM"
var closeHour1 = thePlace.StoreHours.OrderBy(d => d.CloseHour).Select(d => d.CloseHour).First().ToString("hh:mm:ss tt");
// returns "05:00:00 PM"
var openHour2 = thePlace.StoreHours.OrderByDescending(d => d.OpenHour).Select(d => d.OpenHour).First().ToString("hh:mm:ss tt");
// returns "11:59:59 PM"
var closeHour2 = thePlace.StoreHours.OrderByDescending(d => d.CloseHour).Select(d => d.CloseHour).First().ToString("hh:mm:ss tt");
// returns today's date and time: mm/dd/yyyy - 12:00:00 AM
// Which is the right time converted to the place's timezone
var theOpenHour1 = DateTime.Parse(openHour1);
theOpenHour1 = TimeZoneInfo.ConvertTime(
theOpenHour1,
TimeZoneInfo.FindSystemTimeZoneById(thePlace.Timezone.Name));
var theCloseHour1 = DateTime.Parse(closeHour1);
theCloseHour1 = TimeZoneInfo.ConvertTime(
theCloseHour1,
TimeZoneInfo.FindSystemTimeZoneById(thePlace.Timezone.Name));
var theOpenHour2 = DateTime.Parse(openHour2);
theOpenHour2 = TimeZoneInfo.ConvertTime(
theOpenHour2,
TimeZoneInfo.FindSystemTimeZoneById(thePlace.Timezone.Name));
var theCloseHour2 = DateTime.Parse(closeHour2);
theCloseHour2 = TimeZoneInfo.ConvertTime(
theCloseHour2,
TimeZoneInfo.FindSystemTimeZoneById(thePlace.Timezone.Name));
if ((timeNow >= theOpenHour1) && (timeNow <= theCloseHour1)
|| (timeNow >= theOpenHour2) && (timeNow <= theCloseHour2))
{
if (count != 0)
{
device.Ratio = (double)device.Count / (double)count;
}
else
{
count += 1;
device.Ratio = (double)device.Count / (double)count;
}
if (device.Ratio == 2)
{
//
}
if (...)
{
//
}
repository.Update(device);
}
else
{
//
repository.Update(device);
}
}
else
{
var openHour = thePlace.StoreHours.Select(d => d.OpenHour).First().ToString("hh:mm:ss tt");
var closeHour = thePlace.StoreHours.Select(d => d.CloseHour).First().ToString("hh:mm:ss tt");
DateTime dtOpen = DateTime.Parse(openHour);
dtOpen = TimeZoneInfo.ConvertTime(
dtOpen,
TimeZoneInfo.FindSystemTimeZoneById(thePlace.Timezone.Name));
DateTime dtClose = DateTime.Parse(closeHour);
dtClose = TimeZoneInfo.ConvertTime(
dtClose,
TimeZoneInfo.FindSystemTimeZoneById(thePlace.Timezone.Name));
if ((timeNow >= dtOpen) && (timeNow <= dtClose))
{
if (count != 0)
{
device.Ratio = (double)device.Count/ (double)count;
}
else
{
count += 1;
device.Ratio = (double)device.Count/ (double)count;
}
if (device.Ratio == 2)
{
//
}
if (...)
{
//
}
repository.Update(device);
}
else
{
//
repository.Update(device);
}
}
await repository.SaveChanges();
return Unit.Value;
}
正如@JonasH 所说,我应该使用 TimeSpan 但在此之前,我真的很想了解它为什么在本地而不是远程工作。我正在将无效日期的时间“12:00:00 AM”转换为有效的 DateTime,并转换为该地点的 TimeZone(就在 if 语句之前)。当我调试它时它可以工作,因为比较的时间是同一天和正确的时间,让我困惑的是为什么不在服务器上,是什么我没有转换或不做这使得服务器不做。
我确定它与时间转换有关,因为我的计算机获取本地时间,但我不知道服务器在转换代码中的时间值后如何出错。
非常感谢你的帮助 !
解决方案
我需要知道一家商店是否在 2 次之间营业。
我建议将开/关时间存储为代表一天中的时间(即从一天开始的时间)和商店的时区的 TimeSpan。
.Net 6 正在引入一种TimeOnly类型,它提供了比时间跨度更好的“一天中的时间”表示。还有更完整的日期/时间相关类型集的NodaTime。
然后,您可以使用 TimeZoneInfo 获取特定时区的当前时间:
var timeOfDayForStore = TimeZoneInfo.ConvertTime(
DateTime.Now,
TimeZoneInfo.FindSystemTimeZoneById(myStoreTimeZone))
.TimeOfDay;
if(myStoreOpenTime < timeOfDayForStore && myStoreCloseTime > timeOfDayForStore){
...
}
请注意,这是假设商店在午夜不营业。
推荐阅读
- go - 无法命名包“文档”
- c - getopt 忽略命令行参数
- javascript - 什么是“导入为”?
- python - while 循环在列表达到一定长度后中断
- anaconda - Anaconda-navigator 有许多未知的奇怪绿色圆圈
- c - 排序结构
- python - 你如何修复 numpy 和 pandas 的“runtimeError: package failed to pass a sanity check”?
- python - 将 Pandas DF 绘制为堆积条形图,同时忽略缺失值
- node.js - 未在 nodejs express 中使用 PUT 编辑数据
- html - 在引导代码中转换 html 和 css 代码