如果我有一个gettimeofday()的time_t值,或者在Unix环境下(例如Linux,BSD)兼容,是否有一个紧凑的算法可以告诉我一个月内相应的星期数?
理想情况下,返回值的作用方式类似于%W在strftime()中的行为,除了给出月份中的星期而不是年份中的星期。
我认为Java具有W格式化令牌,该令牌执行的功能或多或少类似于我的要求。
[答案由David Nehme,Branan和Sparr发表后,下面的所有内容。]
我意识到,要以与%W类似的方式返回此结果,我们想计算到目前为止该月中的星期一数量。如果该数字为零,则应返回0。
尤其要感谢David Nehme和Branan提供的解决方案,这些解决方案使事情步入了正确的Rails。返回的代码位(使用Branan的变量名)((ts->mday - 1) / 7)表示当前日期之前已完成的完整周数。
但是,如果我们要计算到目前为止已经发生的星期一的数量,那么我们要计算包括今天在内的整数周的数量,然后考虑剩余的小数周是否也包含任何星期一。
要弄清整周后剩余的小数周是否包含星期一,我们需要考虑ts->mday % 7并将其与一周中的某天ts->wday进行比较。如果您写出组合,很容易看出来,但是如果我们确保日期不是星期日(wday > 0),那么在任何时候ts->wday <= (ts->mday % 7),我们都需要将星期一的计数增加1。这是因为考虑了自该月初以来的天数,以及是否基于第一个小数周内的一周中的当日,该小数周是否包含星期一。
因此,我将重写Branan的return语句,如下所示:
return (ts->tm_mday / 7) + ((ts->tm_wday > 0) && (ts->tm_wday <= (ts->tm_mday % 7)));
如果您将第一周定义为每月的1-7天,第二周定义为8-14,...,则以下代码将起作用。
1 2 3 4 5 6 7 8
| int week_of_month( const time_t *my_time)
{
struct tm *timeinfo;
timeinfo =localtime(my_time);
return 1 + (timeinfo->tm_mday-1) / 7;
} |
假设您的第一周是第1周:
1 2 3 4 5 6 7 8 9 10
| int getWeekOfMonth()
{
time_t my_time;
struct tm *ts;
my_time = time(NULL);
ts = localtime(&my_time);
return ((ts->tm_mday -1) / 7) + 1;
} |
对于0索引,将+1放在return语句中。
考虑一下此伪代码,因为我主要使用C语法编写它,但假装我可以借用其他语言的功能(字符串-> int赋值,字符串->时间转换)。适应或扩展您选择的语言。
1 2 3 4 5 6
| int week_num_in_month(time_t timestamp) {
int first_weekday_of_month, day_of_month;
day_of_month = strftime(timestamp,"%d");
first_weekday_of_month = strftime(timefstr(strftime(timestamp,"%d/%m/01")),"%w");
return (day_of_month + first_weekday_of_month - 1 ) / 7 + 1;
} |
很显然,我假设您要按照标准时间函数处理一年中几周的方式来处理一个月中的几周,而不是仅仅1-7天,8-13天等。