1

たとえば、DST があるかどうかに関係なく、中央ヨーロッパ時間の毎週土曜日の 08:00 (夏の間は 08:00 CEST) に定期的なイベントが発生します。DateTimeこのイベントを表すのリストを作成するにはどうすればよいですか?

4

2 に答える 2

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));
于 2013-11-11T03:04:09.010 に答える
0

DateTimeOffset質問した内容を正確に表す値のリストを取得する方法を次に示します。必要に応じて、探しているものに応じてDateTimeまたは で変換できます。これは、指定されたタイムゾーンで、DST を考慮して、今日から次の N 日を返します。result.DateTimeresult.UtcDateTime

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)

これらのアプローチはどちらも、夏時間への移行日に存在しないか 2 回存在する時間に対して、緩やかな変換を想定する道をたどります。寛大になりたくない場合は、さらに作業が必要です。しかし、それはあなたが要求した範囲を超えていると思います。

于 2013-11-11T05:08:35.557 に答える