使用按位运算从整数日期 (yyyyMMdd) 中提取月份
本文关键字:yyyyMMdd 取月份 提取 日期 整数 运算 | 更新日期: 2023-09-27 18:37:01
是否可以使用一些按位运算符提取表示为int
的月份(格式为 YYYYMMDD,例如 20110401)?
如果是这样,怎么能做到?
编辑:我目前正在使用 20110401% 10000/100。我认为按位可以更快。DateTime.Parse等对于我正在尝试做的事情来说太慢了。
否,因为按位运算符使用数字的二进制表示形式。您的日期使用十进制表示形式进行编码。
不过,您可以使用算术运算符来做到这一点:
int date = 20110401;
int day = date % 100;
int month = (date / 100) % 100;
int year = date / 10000;
20110301
(基数 10)作为整数在位级别表示的方式将大不相同,实际上表示为1001100101101101111011101
(基数 2)。使用位级操作从此位字符串中提取月份不会是直截了当的。
选择:
做一些基本的数学运算,涉及整数上的mod
将
int
转换为字符串,然后提取相关数字并将其转换回整数。或者更好的是,为此使用一些已经测试过的库函数。
位级操作不是解决此问题的好方法。
使用按位运算可能容易出错,如果你能做到的话。您可以通过使用除法和模运算操作数字来做到这一点。
您还可以将其转换为字符串,解析月份字符,然后转换回 int。
下面是 C# 中的一些示例代码
int date = 20119420;
int month = 0;
// using good old math
month = (date / 100) % 100;
// using string parsing
month = int.Parse(date.ToString().Substring(4, 2));
如果您以二进制格式表示日期,则可以使用按位运算有效地提取月份,例如,5 位表示月份中的某天,4 位表示月份编号,其余表示年份,而不是十进制数字。例如,日期为 (2011 <<9) + (4 <<5) + 1(当然不等于 20110401)。使用按位运算从此类表示形式中提取字段:
int year = date >> 9;
int month = (date >> 5) & 0xF;
int day = date & 0x1F;
正如Mark Byers所提到的,另一种方法是使用结构体,例如:
typedef struct {
short year;
char month;
char day;
} Date;
您可以在堆栈上传递这些字段,按名称提取字段,并将它们初始化为
Date d = { 2011, 4, 1};
或者,在 C99 中,
Date d = { .year = 2011, .month = 4, .day = 1 };
所以我知道这是一个非常古老的帖子,但这实际上是我们类的作业,我有一个压缩日期和一个仅使用按位运算的提取日期函数:
//Compress Date
int compressDate(int month, int day, int year)
{
int date = year;
date <<= 4;
date |= month;
date <<= 6;
date |= day;
return date;
}
//Extract Date
void extractDate(int date, int& month, int& day, int& year)
{
int dayMask = 63;
int monthMask = 15;
int yearMask = 4095;
day = date & dayMask;
date >>= 6;
month = date & monthMask;
date >>= 4;
year = date & yearMask;
}
当您使用 compileDate(1, 25, 2019) 之类的内容执行压缩日期函数时,它会返回数字:2067545 并且 extractDate 函数以相反的顺序工作。这样做的原因是按位运算符比使用数学运算符更快。