java - 将日期打包到一个 int 变量中 (Java)

标签 java algorithm

<分区>

我有一个问题要求我在 int 变量 中打包和解包日历日期。例如,2007 年 2 月 20 日将表示为以下内容:

  • 5 位 将保留给当天
  • 接下来的 4 位 将保留当月
  • 最后一点将保留到当年

不幸的是,这是我所有的信息。有什么建议吗?

最佳答案

假设您使用的是 32 位有符号整数并且您忽略了符号位,并且“calendaristic”是指它属于 Calendar 类型,那么以下方法应该可以解决问题:

public static int calToInt(Calendar cal) {
    int date = cal.get(Calendar.DAY_OF_MONTH) << 26;
    date |= cal.get(Calendar.MONTH) << 22;
    date |= cal.get(Calendar.YEAR);
    return date;
}

注意在Calendar的实现中,January是0,如果要January用1表示,那么一定要给month加1。另请注意,根据我的假设,您的年份有 22 位可供使用,因此将一直工作到 2^22 年。即年份 4194304,这应该绰绰有余。

解释

您可能对其余部分不感兴趣,但我喜欢解释事情是如何工作的,即使我只提供一个粗略的概述:

它的工作方式是获取日历对象,获取日期并将其向左移动 26 位(这就是 << 26 所做的),这意味着月份中的日期最多为 5 位, day 实际上将从 32 位 int 的第二位开始。这是为了避免表示 int 是否为负数的第一位。如果你想填充完整的整数,然后将 22 更改为 23,将 26 更改为 27,这将为你的年份增加一点(实际上是两倍)。与年中的月份类似,它向左移动 22 位,以便它位于月份中的第几天之后,最多消耗 4 位。

|=运算符是按位或赋值运算符。它所做的是按位或左边的东西,右边的东西分配给左边的东西。您可以在一行中执行此操作,但在我看来这要清楚得多,并且就字节码而言将导致相同的结果。 OR 的意思是,如果左边或右边的任何一位为 1,则输出将在该位置包含 1。这就是各个部分的组合方式。

如果年份确实大于规定的最大值,它就会把事情搞砸。

反转:

为了将此 int 返回到 Calendar 对象中,可以使用以下方法:

private static Calendar intToCal(int date) {
    int day = date >> 26;
    int month = (date & 0b00000011110000000000000000000000) >> 22;
    int year = date & 0b00000000001111111111111111111111;
    return new GregorianCalendar(year, month, day);
}

这可以使用位掩码和位移位。所以第一个只移动了 26 位(所有其他向右的位都丢失了,我们只剩下这一天了。 使用月份和日期位掩码。我用二进制格式写了这些,以便更清楚地说明它的作用。我正在使用逻辑和只从我想要的 int 中获取位。在月份中,只会保留位掩码中标有 1 的位(这会在我们移动之前删除月份中的第几天)。我也去掉了月份右边的位,但这不是必需的,当执行右移位时,它们将像第一个一样被切断。年份只需要掩码,因为最后 22 位只是二进制形式的年份。同样,我忽略了符号位,但是这在第一个中并不明确,如果传递了一个负数,它就会把它搞砸。要解决此问题,必须对日期应用掩码以屏蔽符号位。

关于java - 将日期打包到一个 int 变量中 (Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23067421/

相关文章:

java - Calendar.HOUR 和 Calendar.HOUR_OF_DAY 之间的区别?

javascript - 通过某种合并算法从数组中删除重复对象

algorithm - +1 在硬币找零问题(动态规划方法)的递归关系中意味着什么?

Java - Jackcess API,采用 .accde(MS Access) 格式

java - 基于刻度值的颜色java JSlider

algorithm - n^(-1/3) 对 (n!) ^ 2 对 2 ^ (n^2)。具有指数(n^2)的阶乘平方或指数?

algorithm - 覆盖目标的传感器的最小成本子集

algorithm - 直线上给出的点的最短距离对?

c# - c#中的java静态操作

java - 在 Java 和 ANTLRWorks 调试器中捕获 ANTLR 的 NoViableAltException