使用按位运算从 int 日期中提取月份 (yyyyMMdd)
Posted
技术标签:
【中文标题】使用按位运算从 int 日期中提取月份 (yyyyMMdd)【英文标题】:using bitwise operation to extract month from int date (yyyyMMdd) 【发布时间】:2012-06-13 21:41:55 【问题描述】:是否可以使用一些位运算符从表示为 int
(格式 YYYYMMDD,例如 20110401)的日期中提取月份?
如果可以,怎么办?
编辑: 我目前正在使用 20110401 % 10000 / 100。我认为按位可能会更快。 DateTime.Parse 等对于我想要做的事情来说太慢了。
【问题讨论】:
虽然您可以使用按位运算来完成,但为此使用数学运算更容易。 仅有的两个可能答案是“是”或“否”。这真的是您想要的吗? 为什么必须使用按位运算?对于您要访问的内容,这似乎过于复杂且不必要。您似乎还列出了三种不同的语言标签,您使用的是什么语言?例如,C# 已经为此内置了方法。 答案是是的,虽然并不直截了当。所有算术运算都可以通过位运算来实现。 我目前正在使用 20110401 % 10000 / 100。认为按位可能会更快。没有? 【参考方案1】:不,因为位运算符使用数字的 二进制 表示。您的日期使用 十进制 表示进行编码。
您可以使用算术运算符来做到这一点:
int date = 20110401;
int day = date % 100;
int month = (date / 100) % 100;
int year = date / 10000;
【讨论】:
如果使用 C#,则解析为DateTime
;)
当然有可能,因为计算机是在电路级别进行按位运算,但在软件中尝试模拟这些是没有意义的。
"您的日期使用十进制表示。" ——但有必要吗?请参阅下面的答案。
或者你可以使用一个包含一个短字节和两个字节的结构。
可以,但将日期编码为 int 可能更容易一些。【参考方案2】:
20110301
(以 10 为基数)作为整数在位级别的表示方式完全不同,实际上是 1001100101101101111011101
(以 2 为基数)。使用位级操作从这个位串中提取月份并不是一件容易的事。
替代方案:
对整数做一些涉及 mod 的基本数学运算
将int
转换为字符串,然后提取相关数字并将它们转换回整数。
或者更好的是,为此使用一些已经测试过的库函数。
位级操作不是解决这个问题的好方法。
【讨论】:
【参考方案3】:如果你能做到的话,使用按位运算可能很容易出错。您可以通过除法和模运算来处理数字。
您也可以将其转换为字符串,解析月份字符,然后再转换回 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));
【讨论】:
【参考方案4】:如果您以二进制格式表示日期,则可以通过按位运算有效地提取月份,例如,5 位表示月份的日期,4 位表示月份编号,其余部分年份,而不是十进制数字。对于您的示例,日期将是 (2011
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 ;
【讨论】:
【参考方案5】:所以我知道这是一篇非常古老的帖子,但这实际上是我们班的作业,我有一个压缩日期和一个仅使用按位运算的提取日期函数:
//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;
当您使用 compressDate(1, 25, 2019) 之类的函数执行压缩日期函数时,它会返回数字:2067545,而 extractDate 函数的工作顺序正好相反。这样做的原因是位运算符比使用数学运算符更快。
【讨论】:
以上是关于使用按位运算从 int 日期中提取月份 (yyyyMMdd)的主要内容,如果未能解决你的问题,请参考以下文章
网络套件!使用 freemarker 从日期 DD/MM/YYYY 获取月份名称不起作用