Java 如何把一个8位的时间类型字符串(“20150608”)存进一个定长为3的byte数组中?

「已注销」 2017-08-03 09:13:11
Java 如何把一个8位的时间类型字符串(“20150608”)存进一个定长为3的byte数组中?
...全文
352 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
混沌鳄鱼 2017-08-04
  • 打赏
  • 举报
回复
引用 7 楼 sinat_30931009 的回复:
个人想法,把日常这个字符串看成数字,把20150608转成ox16进制 1337950 分成133,79,50,在人类消失之前这个方法都是没问题的。
133 超过一个byte 上限了, 一个byte最大127 人家出这个题目的就是因为 3个字节24位最大表示到2^24=16777216个整数,20150608是超过范围的。
sinat_30931009 2017-08-04
  • 打赏
  • 举报
回复
个人想法,把日常这个字符串看成数字,把20150608转成ox16进制 1337950 分成133,79,50,在人类消失之前这个方法都是没问题的。
「已注销」 2017-08-04
  • 打赏
  • 举报
回复
引用 5 楼 xpresslink 的回复:
大概的思路是这样的 3个byte共24bit 日期 1-31,用 5 bit 月 1-12 用 4 bit 年 0000-9999 用剩下 15 bit 因为java写起来有点繁琐,我用python写了一个演示
一开始我也是和你一样,准备用 15、4、5 这样的组合。但是考虑到 5、9 是奇数,对齐还是不够工整,因此都改为偶数 6。使用 12、6、6 保存年月日,12 bit 最大表示 4095 年,目前来说已经够用了。
混沌鳄鱼 2017-08-04
  • 打赏
  • 举报
回复
大概的思路是这样的
3个byte共24bit
日期 1-31,用 5 bit
月 1-12 用 4 bit
年 0000-9999 用剩下 15 bit

因为java写起来有点繁琐,我用python写了一个演示
「已注销」 2017-08-03
  • 打赏
  • 举报
回复
// 这里 (byte) 忘删了
int nDay = (byte)cal.get(Calendar.DAY_OF_MONTH);
「已注销」 2017-08-03
  • 打赏
  • 举报
回复
用二进制位运算的方式把年月日硬塞到 3 个 byte 里面,也是可行的。用 12 bit 保存年份,两个 6 bit 保存月日,足够了。一个 int 的最高 8 bit 不使用,剩余的 24 bit 保存到 3 个 byte 里面。这里提供一个思路:
package com.java.test;

import java.nio.ByteBuffer;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class DummyMethod {
    private static final Map<Integer, Integer> monthMap = new HashMap<>();
    static {
    	monthMap.put(Calendar.JANUARY,   1);
    	monthMap.put(Calendar.FEBRUARY,  2);
    	monthMap.put(Calendar.MARCH,     3);
    	monthMap.put(Calendar.APRIL,     4);
    	monthMap.put(Calendar.MAY,       5);
    	monthMap.put(Calendar.JUNE,      6);
    	monthMap.put(Calendar.JULY,      7);
    	monthMap.put(Calendar.AUGUST,    8);
    	monthMap.put(Calendar.SEPTEMBER, 9);
    	monthMap.put(Calendar.OCTOBER,   10);
    	monthMap.put(Calendar.NOVEMBER,  11);
    	monthMap.put(Calendar.DECEMBER,  12);
    }
    private static final Calendar cal = Calendar.getInstance();
    private static final DateFormat df = new SimpleDateFormat("yyyyMMdd");
 
    public static String getDateFromByteArray(byte[] arr) {
    	int nDate = 0;
    	if ((arr != null) && (arr.length >= 3)) {
    		int size = Integer.SIZE / Byte.SIZE;
	    	ByteBuffer bb = ByteBuffer.allocate(size);
	    	bb.put((byte)0);
	    	bb.put(arr[0]);
	    	bb.put(arr[1]);
	    	bb.put(arr[2]);
	    	bb.rewind();
	    	nDate = bb.getInt();
    	}
    	int nYear = (nDate >>> 12) & 0xFFF;
    	int nMonth = (nDate >>> 6) & 0x3F;
    	int nDay = (nDate & 0x3F);
    	String fmt = "%04d%02d%02d";
    	String res = String.format(fmt, nYear, nMonth, nDay);
    	return res;
    }
    
    public static byte[] parseDateAsByteArray(String s) {
        byte[] arr = new byte[3];
        try {
            Date dt = df.parse(s);
            cal.setTime(dt);
            int nYear = cal.get(Calendar.YEAR);
            int nMonth = monthMap.get(cal.get(Calendar.MONTH)).intValue();
            int nDay = (byte)cal.get(Calendar.DAY_OF_MONTH);
            int nDate = (nYear << 12) | (nMonth << 6) | nDay;
            int size = Integer.SIZE / Byte.SIZE;
            ByteBuffer bb = ByteBuffer.allocate(size);
            bb.asIntBuffer().put(nDate);
            arr[0] = bb.get(1);
            arr[1] = bb.get(2);
            arr[2] = bb.get(3);
        } catch (ParseException e) {
            arr[0] = 0;
            arr[1] = 0;
            arr[2] = 0;
        }
        return arr;
    }
 
    public static void main(String[] args) {
        String s1 = "20150608";
        byte[] r = parseDateAsByteArray(s1);
        String s2 = getDateFromByteArray(r);
        System.out.println(s2);
    }
}
wenchi2018 2017-08-03
  • 打赏
  • 举报
回复
转化成数字后 用进制转化成2个数再塞进数组
「已注销」 2017-08-03
  • 打赏
  • 举报
回复
如果你是想说把年月日分别放到三个 byte,那不行,一个 byte 表示的最大正数是 127,装不下年份那么大的数字。当然,不考虑这个的话,代码也很简单的,最最基础的:
package com.java.test;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class DummyMethod {
	
	private static final Map<Integer, Integer> monthMap = new HashMap<>();
	static {
		monthMap.put(Calendar.JANUARY,   1);
		monthMap.put(Calendar.FEBRUARY,  2);
		monthMap.put(Calendar.MARCH,     3);
		monthMap.put(Calendar.APRIL,     4);
		monthMap.put(Calendar.MAY,       5);
		monthMap.put(Calendar.JUNE,      6);
		monthMap.put(Calendar.JULY,      7);
		monthMap.put(Calendar.AUGUST,    8);
		monthMap.put(Calendar.SEPTEMBER, 9);
		monthMap.put(Calendar.OCTOBER,   10);
		monthMap.put(Calendar.NOVEMBER,  11);
		monthMap.put(Calendar.DECEMBER,  12);
	}
	private static final Calendar cal = Calendar.getInstance();
	private static final DateFormat df = new SimpleDateFormat("yyyyMMdd");

	public static byte[] parseDateAsByteArray(String s) {
		byte[] arr = new byte[3];
		try {
			Date dt = df.parse(s);
			cal.setTime(dt);
			arr[0] = (byte)cal.get(Calendar.YEAR);
			arr[1] = (byte)monthMap.get(cal.get(Calendar.MONTH)).intValue();
			arr[2] = (byte)cal.get(Calendar.DAY_OF_MONTH);		
		} catch (ParseException e) {
			arr[0] = 0;
			arr[1] = 0;
			arr[2] = 0;
		}
		return arr;
	}

	public static void main(String[] args) {
		String s = "20150608";
		byte[] r = parseDateAsByteArray(s);
		for (byte b : r) {
			System.out.println(b);
		}
	}
}

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧