Как получить 29 февраля, используя метод AddYears в c # - PullRequest
1 голос
/ 05 марта 2019

Мы используем работу, которая выполняется каждый день, и выполняем некоторые действия на день вперед на год.На самом деле мы просто используем что-то вроде: DateTime.UtcNow.AddYears(1).Но, кажется, невозможно получить 29 февраля (например, на 2020 год), используя эту технику:

var target = new DateTime(2020, 2, 29);
bool result = (target == target.AddYears(-1).AddYears(1));//false

Так можно ли как-то нацелиться на 29 февраля в будущем?

Ответы [ 5 ]

4 голосов
/ 05 марта 2019

Нет, это дизайн .

Если текущий экземпляр представляет високосный день в високосном году, возвращаемое значение зависит от целевой даты :

  • Если value + DateTime.Year также является високосным годом, возвращаемое значение представляет високосный день в этом году.Например, если к 29 февраля 2012 года добавлено четыре года, возвращаемая дата - 29 февраля 2016 года.

  • Если value + DateTime.Year не является високосным годом,возвращаемое значение представляет день до високосного дня в этом году.Например, если к 29 февраля 2012 года добавлен один год, возвращаемая дата будет 28 февраля 2013 года.

1 год после 29 февраля 2020 года должно быть 28 февраля 2021 года, поскольку не високосный год.Но в таком случае все годы после 2021 года будут работать как 28 февраля.

Кроме этого, спросите себя, что для вас означает "год"?Сколько дней в месяце?Сколько дней в году?Это 365?366?Или как Википедия указала 365.2425?Кроме того, о каком календаре идет речь?

Каркасы, библиотеки и т. Д. не работает так, как думают люди.Они работают на основе набора правил, определенных ранее..NET Framework определил это правило как таковое.Поэтому, когда вы добавляете год к экземпляру DateTime, они решают, что часть месяца должна оставаться неизменной, часть года будет меняться в зависимости от того, сколько лет будет добавлено, а часть дня должна быть действительной * 1041.* один.

4 голосов
/ 05 марта 2019

Нет. Документация гласит:

  • Если значение + DateTime.Year также является високосным годом, возвращаемое значение представляет високосный день в этом году. Например, если к 29 февраля 2012 года добавлено четыре года, возвращаемая дата - 29 февраля 2016 года.

  • Если значение + DateTime.Year не является високосным годом, возвращаемое значение представляет день, предшествующий високосному дню в этом году. Например, если к 29 февраля 2012 года добавлен один год, возвращаемая дата будет 28 февраля 2013 года.

Это означает, что если вы добавите год, вы всегда получите 28 февраля. Единственный способ получить 29-е число через AddYears - добавить кратное 4.

0 голосов
/ 05 марта 2019

Функция, которая возвращает следующие 29. фев.Может быть, это поможет.использование системы;

public class Program
{
    public static DateTime NextTwentyNineFeb()
    {
        int year = DateTime.Now.Year;
        while(true){            
            try{
                var target = new DateTime(year, 2, 29);
                Console.WriteLine(target);
                return target;
            }
            catch
            {
                year++;
            }
        }
    }
}
0 голосов
/ 05 марта 2019

Вы могли бы немного обмануть систему, взяв вместо этого «день до 1 марта».

заглушка:

DateTime today = DateTime.UtcNow
if (today.month == 2)
{
  if(today.day == 28 || today.day == 29)
  {
    today.AddDays(1).AddYears(1).AddDays(-1)
   }
}

это конвертирует ваш фев 28 в не-високосные годы 1 марта, добавляет год и уходит на день раньше.Если следующий год также не будет високосным, вы все равно получите 28 февраля, но если следующий год будет високосным, результат будет 29 февраля.

это еще не относится к ситуации, которая наступит в этом году.високосный год, так как вместо этого код вернет 27 февраля, хотя

0 голосов
/ 05 марта 2019

Как заявил NibblyPig, это невозможно.Однако, если вы на самом деле ищете конец месяца, вы можете использовать new DateTime(year, month + 1, 0).AddDays(-1)

...