如何确定给定日期的季度?

54
下面是财政年度的季度。
April to June          - Q1
July to Sep            - Q2
Oct to Dec             - Q3
Jan to March           - Q4

如果输入日期的月份符合上述条件,我需要输出季度号。

例如,

如果我输入一个日期(比如1月2日),我需要输出Q4

如果我输入一个日期(比如6月5日),输出应该为Q1

根据输入日期,我需要获取季度号。


你能否从零开始完成这个任务,无论是否存在内置库? - Shamim Hafiz - MSFT
相关讨论 - https://dev59.com/vnI-5IYBdhLWcg3wQV4Z - KV Prajapati
@AVD:上述线程的结果与我预期的输入日期所对应的季度数字不同。 - venkat
为什么一年的前三个月会是第四季度? - Aaron Franke
15个回答

97
如果您喜欢简短、简洁的解决方案,而不需要使用 branching 和 arrays,那么这是我偏爱的解决方案。
常规季度:
public static int GetQuarter(this DateTime date)
{
    return (date.Month + 2)/3;
}

财政年度季度:

public static int GetFinancialQuarter(this DateTime date)
{
    return (date.AddMonths(-3).Month + 2)/3;
}

整数除法会将小数截断,给出整数结果。将方法放入静态类中,您将拥有一个扩展方法,可按如下方式使用:

整数除法会将小数截断,给出整数结果。将方法放入静态类中,您将拥有一个扩展方法,可按如下方式使用:

date.GetQuarter()
date.GetFinancialQuarter()

请看 dotnetfiddle


非常优雅的解决方案。 - undefined

32

你可以简单地编写一个扩展方法给DateTime

public static int GetQuarter(this DateTime date)
{
    if (date.Month >= 4 && date.Month <= 6)
        return 1;
    else if (date.Month >= 7 && date.Month <= 9)
        return 2;
    else if (date.Month >= 10 && date.Month <= 12)
        return 3;
    else 
        return 4;
}

并将其用作

DateTime dt = DateTime.Now;
dt.GetQuarter();

感谢您的方法。如果上述方法在一月份的输出结果为“4”,那么我需要进行额外的努力来获得Q4、Q1、Q2、Q3的输出。只需按照日期时间的月份顺序旋转这些季度即可。我该如何实现? - venkat
你的要求对我来说不够清晰,请问能否解释一下或者在另一个问题中提出?上面的代码片段回答了你当前的问题。 - Haris Hasan

22
最简单和一致的实现方法是:

定期的

Math.Ceiling(date.Month / 3.0)

财政(通过对2+1个季度进行模运算来刚好提前)


Math.Ceiling(date.Month / 3.0 + 2) % 4 + 1

01.01.2016 00:00:00 -> Q1 -> FQ4
01.02.2016 00:00:00 -> Q1 -> FQ4
01.03.2016 00:00:00 -> Q1 -> FQ4
01.04.2016 00:00:00 -> Q2 -> FQ1
01.05.2016 00:00:00 -> Q2 -> FQ1
01.06.2016 00:00:00 -> Q2 -> FQ1
01.07.2016 00:00:00 -> Q3 -> FQ2
01.08.2016 00:00:00 -> Q3 -> FQ2
01.09.2016 00:00:00 -> Q3 -> FQ2
01.10.2016 00:00:00 -> Q4 -> FQ3
01.11.2016 00:00:00 -> Q4 -> FQ3
01.12.2016 00:00:00 -> Q4 -> FQ3

结果是1到4之间的值。几乎任何环境都有CEIL函数,所以它在任何语言上也应该可以工作。


这看起来不错!但是假设我想要一个不同的开始日期。比如说,我想要八月份而不是四月份?我应该改变哪个值?谢谢! - tastebuds

19

这是“平年”的情况。我认为你可以根据示例进行调整:

string.Format("Q{0}", (date.Month + 2)/3);

它没有满足问题的要求。 - Maitrey684

13
public static int GetQuarter(DateTime date)
{
    int[] quarters = new int[] { 4,4,4,1,1,1,2,2,2,3,3,3 };
    return quarters[date.Month-1];
}

请详细解释您的答案,以便其他人在查看您的代码(通过谷歌搜索后)时能够理解。 - Our Man in Bananas
1
最有效的答案+1(如果数组声明为静态) - JanW

8

扩展方法和更少的比较:

public static class DateTimeExtension
{
    public static int GetQuarter(this DateTime dateTime)
    {
        if (dateTime.Month <= 3)
            return 1;

        if (dateTime.Month <= 6)
            return 2;

        if (dateTime.Month <= 9)
            return 3;

        return 4;
    }
}

6
int CurrentQuarter = (int)Math.Floor(((decimal)DateTime.Today.Month + 2) / 3);

或者将 DateTime.Today 更改为所需日期。


4
在SQL中,它很简单。
((((month(@mydate)-1)/3)+3) % 4) + 1

用以下方式进行检查:

declare @mydate datetime
set @mydate = '2011-01-01'
while @mydate <= '2011-12-31'
    begin
    print ((((month(@mydate)-1)/3)+3) % 4) + 1
    set @mydate = dateadd(month, 1, @mydate)
    end

如果你希望在.NET中完成此操作,可以使用以下代码:

String.Format("Q{0}", ((((date.Month-1)/3)+3) % 4) + 1);

2

现在您可以使用C#中的关系模式来轻松地编写单个switch表达式

public static string FiscalQuarter(this DateTime date)
{
    var qtr = date.Month switch
    {
        < 4 => 4,
        < 7 => 1,
        < 10 => 2,
        _ => 3
    };
    return $"Q{qtr}";
}

2
我们一年有以下四个季度:
1季度 = (0或1或2)/3 + 1
2季度 = (3或4或5)/3 + 1
3季度 = (6或7或8)/3 + 1
4季度 = (9或10或11)/3 + 1
public static int GetQuarter(this DateTime source)
{
   return (source.Month - 1) / 3 + 1;
}

编程相关的内容翻译成中文。快速简洁地返回翻译后的文本。 - lnaie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接