例如,无论是否有夏令时,每周六欧洲中部时间08:00(或夏令时08:00 CEST)都会发生反复发生的事件。我如何提出代表此事件的DateTime
列表?
答案 0 :(得分:0)
你在找这个吗?
List<DateTime> Schedule = new List<DateTime>();
DateTime Base = new DateTime(2013, 11, 9, 8, 0, 0);
for (int i = 0; i < 365; i++)
Schedule.Add(Base.AddDays(i));
答案 1 :(得分:0)
这是一种获取DateTimeOffset
值列表的方法,可以准确地表示您的要求。如果您愿意,可以使用DateTime
或result.DateTime
转换为result.UtcDateTime
,具体取决于您要查找的内容。这将在今天的下一个N天返回,在提供的时区中,占DST。
public static IEnumerable<DateTimeOffset> GetNextDaysInZone(int count, DayOfWeek dayOfWeek, TimeSpan localTimeOfDay, string timeZoneId)
{
// get today in the time zone specified
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
DateTime today = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tz).Date;
// figure out how many days we are away from the target day of week
int adjustment = dayOfWeek - today.DayOfWeek + (dayOfWeek < today.DayOfWeek ? 7 : 0);
// calculate and return the results
return Enumerable.Range(0, count)
.Select(x =>
{
DateTime dt = today.AddDays(x * 7 + adjustment).Add(localTimeOfDay);
TimeSpan offset = tz.GetUtcOffset(dt);
return new DateTimeOffset(dt, offset);
});
}
使用示例:
DayOfWeek dayOfWeek = DayOfWeek.Saturday;
TimeSpan localTimeOfDay = new TimeSpan(8, 0, 0);
// Note: Despite the name, this represents Central European Time, including both CET and CEST.
string tzid = "Central Europe Standard Time";
var results = GetNextDaysInZone(5, dayOfWeek, localTimeOfDay, tzid);
foreach (var result in results)
{
Console.WriteLine("{0:yyyy-MM-dd HH:mm:ss zzz} ({1:yyyy-MM-dd HH:mm:ss} UTC)", result, result.UtcDateTime);
}
结果:
2013-11-16 08:00:00 +01:00 (2013-11-16 07:00:00 UTC)
2013-11-23 08:00:00 +01:00 (2013-11-23 07:00:00 UTC)
2013-11-30 08:00:00 +01:00 (2013-11-30 07:00:00 UTC)
2013-12-07 08:00:00 +01:00 (2013-12-07 07:00:00 UTC)
2013-12-14 08:00:00 +01:00 (2013-12-14 07:00:00 UTC)
如果您想放弃内置日期/时间api并使用更强大可靠的内容,我建议您尝试Noda Time。以下是使用Noda Time进行上述操作的方法。
public static IEnumerable<ZonedDateTime> GetNextDaysInZone(int count, IsoDayOfWeek dayOfWeek, LocalTime localTimeOfDay, string timeZoneId)
{
// get today in the time zone specified
DateTimeZone tz = DateTimeZoneProviders.Tzdb[timeZoneId];
Instant now = SystemClock.Instance.Now;
LocalDate today = now.InZone(tz).Date;
// figure out how many days we are away from the target day of week
int adjustment = dayOfWeek - today.IsoDayOfWeek + (dayOfWeek < today.IsoDayOfWeek ? 7 : 0);
// calculate and return the results
return Enumerable.Range(0, count)
.Select(x => (today.PlusDays(x * 7 + adjustment) + localTimeOfDay).InZoneLeniently(tz));
}
示例用法:
IsoDayOfWeek dayOfWeek = IsoDayOfWeek.Saturday;
LocalTime localTimeOfDay = new LocalTime(8, 0, 0);
// This is just one of the zones that follows CET/CEST
string tzid = "Europe/Berlin";
var results = GetNextDaysInZone(5, dayOfWeek, localTimeOfDay, tzid);
LocalDateTimePattern localPattern = LocalDateTimePattern.CreateWithInvariantCulture("yyyy-MM-dd HH:mm:ss");
OffsetPattern offsetPattern = OffsetPattern.CreateWithInvariantCulture("m");
foreach (var result in results)
{
Console.WriteLine("{0} {1} ({2} UTC)",
localPattern.Format(result.LocalDateTime),
offsetPattern.Format(result.Offset),
localPattern.Format(result.WithZone(DateTimeZone.Utc).LocalDateTime));
}
结果:
2013-11-16 08:00:00 +01:00 (2013-11-16 07:00:00 UTC)
2013-11-23 08:00:00 +01:00 (2013-11-23 07:00:00 UTC)
2013-11-30 08:00:00 +01:00 (2013-11-30 07:00:00 UTC)
2013-12-07 08:00:00 +01:00 (2013-12-07 07:00:00 UTC)
2013-12-14 08:00:00 +01:00 (2013-12-14 07:00:00 UTC)
这两种方法都采用了在夏令时转换日期间不存在或存在两次的宽松转换路径。如果你不喜欢它,那么你还有更多的工作要做。但我认为这超出了你所要求的范围。