public class SortMaoPao { /**
 * @param b
 * @return 
 * 网络字节转换成主机字节
 */
private static long ByteArraytoLong(byte[] b)  {
        long iOutcome = 0;
        byte bLoop;
        for (int i = 0; i < 8; i++)  {
                bLoop = b[i];
                iOutcome += (bLoop & 0xff) << (8 * i);
        }
        return iOutcome;
    }

public static void main(String[] args){
byte[] b=new byte[8];
b[0]=22;
b[1]=-126;
b[2]=67;
b[3]=26;
b[4]=109;
b[5]=125;
b[6]=-29;
b[7]=64;
 
Date mydate=new Date(ByteArraytoLong(b)); 
SimpleDateFormat format =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String etime=format.format(mydate); 
System.out.println(etime);

}
 
}

得到时间为:1970-01-19 00:48:02,时间是错误的,时间应该是2009-04-12 09:XX:XX请教下,代码哪里有问题?

解决方案 »

  1.   

    加上
     System.out.println(System.currentTimeMillis());
        SimpleDateFormat format =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
        System.out.println(format.format(new Date()));看下当前的时间就知道你的ByteArraytoLong函数的返回值不行
      

  2.   

    Date mydate=new Date(ByteArraytoLong(b)); 你这句得不到当前的系统时间啊
      

  3.   

    如果 ByteArraytoLong 函数写对的话就可以
    但是看起来好像是写错了
      

  4.   

    这个事可以的,转换完了之后是一个long型的数,也就是系统时间的毫秒数。但是楼主的字节数组对吗?你的那个byte数组转换成long型数算法是对的,但取决于你的字节数组是不是高位和低位没有搞错。
      

  5.   

    Delphi 和 Java 进行Socket通讯
    传输的网络字节,数值是:22,-126,67,26,109,125,-29,64
    那么我就需要将网络字节转换成主机字节这个时候得到的时间值是:1970-01-19 00:48:02 显然这是错误的2边传输的字节数组值是对的,所以我就不明白问题出在哪了?
      

  6.   

    有一个办法去排查看你截取的时间是不是对的。你比较下这个t和t1是不是相等,就知道到底是方法错了,还是你的数据错了。
    public static void main(String[] args){ 
    long t = System.currentTimeMillis(); //得出当前系统时间的long值,并打印
    System.out.println(t);

    byteArray[0]=22; 
    byteArray[1]=-126; 
    byteArray[2]=67; 
    byteArray[3]=26; 
    byteArray[4]=109; 
    byteArray[5]=125; 
    byteArray[6]=-29; 
    byteArray[7]=64;  long t1 = ByteArraytoLong(byteArray);
    System.out.println(t1);
      

  7.   


    这样看来long肯定不是一样的,只有明天问问Delphi的那个人,
    它的八个字节是什么,是不是和我的一样?如果他的字节和我接收的一样,但是他能得到正确的时间类型
    而我不能的话,这个时候该如何处理呢?
      

  8.   

    我搞错了,应该用这句:
    iOutcome += ((long)(bLoop & 0xff)) << (8 * i);
    那个long的强制转换不能少。
      

  9.   

    然后你的那个字符数组可以确定是错误的了。你可以看看我的测试代码和输出。结果是没有问题的。因为我时区的问题,比北京时间晚一点。但是你会发现那个字符数组的高位应该有0的,而你的字符数组高位没有0,那么输出肯定很夸张,估计人类都灭绝了。哈哈哈。
    import java.text.*;
    import java.util.*;public class Time {
    static byte[] byteArray = new byte[8];

    private static long ByteArraytoLong(byte[] b)  { 
            long iOutcome = 0; 
            byte bLoop; 
            for (int i = 0; i <b.length; i++)  { 
             bLoop = b[i];
                iOutcome += ((long)(bLoop & 0x000000ff)) << (8 * i); 
            } 
            return iOutcome; 
        } 

    private static byte[] LongtoByte(long l){
    for (int i=0; i<8; i++){
    byteArray[i] = new Long(l & 0xFF).byteValue();
    l >>= 8;
    System.out.print(byteArray[i] +" ");
    }
    System.out.println();
    return byteArray;
    } public static void main(String[] args){ 
    long t = System.currentTimeMillis(); //得出当前系统时间的long值,并打印
    System.out.println(t);
    LongtoByte(t); //转换成字符数组,数组的低位对应着long的低位 String str = Long.toBinaryString(t);
    System.out.println(str);

    long t1 = ByteArraytoLong(byteArray);
    System.out.println(t1);

    Date mydate=new Date(1239506503788l); 
    SimpleDateFormat format =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
    String etime=format.format(mydate); 
    System.out.println(etime);  

    }
    结果:
    1239508726819
    35 52 122 -104 32 1 0 0 
    10010000010011000011110100011010000100011
    1239508726819
    2009-04-11 21:21:43
      

  10.   

    对了  补充一下  代码有一个地方改一下。把那个long型数改成这个t1,我当时是为了测试用的,所以替换成了一个long型的数。
    Date mydate=new Date(t1); 
    SimpleDateFormat format =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
    String etime=format.format(mydate); 
    System.out.println(etime); 
      

  11.   

    Date mydate=new Date(t1);
      

  12.   

    justinavril:
     所以按照你的意思来说,是我接收的数组错误,但是我是按照协议来的,
     
     那到底是不是我的接收错误,只有明天才能知道,在这里先谢谢你
      

  13.   

    恩,那个long和byte数组来回转换都是没问题的。只有可能是你的字符数组出错了,你要是把你的字符数组转换成long型,再换算成date,结果明显的是有问题的。148169598-08-30 20:37:25
      

  14.   

    答:很明显,你写的那个
    网络字节转换成主机字节 ByteArraytoLong(byte[] b) ,代码是错误的。 
      

  15.   

    确实是错误的,justinavril有指出错误在哪里
    iOutcome += ((long)(bLoop & 0x000000ff)) << (8 * i); 
    需要强制转换成long类型,这样就对了justinavril:
    接收过来的数组没有问题,我觉得问题可能是处在Delphi和Java的时间类型不一样
    2009-04-13 09:06:09   
    Delphi 好像是Double类型的,转换后是: 39916.3792726389
    Java   可以转换成long      转换后是:1239584802062所以觉得这里才是问题的所在
     
      

  16.   


    Delphi:
    2009-04-13 09:16:35 转换成字节数组:
    41
    178
    96
    94
    140
    125
    227
    64
    明显和Java的不一样
      

  17.   

    1:&运算符默认返回是int的,不会因为你多加0而变成其他的类型。既然是int的,4个字节那么你移位的时候最多可能要左移56字节,这时编译器因为发现大于了int的4个字节的长度会-32来移位,楼主不信可以去测试。
    2:既然要转换成long的,那么你接受的数据的高低位就要弄清楚,我的意思是说你的b[0]是最高为还是最低位,这样移位运算出来以后就不会有问题了。
      

  18.   

    改一下是56。不是字节。
    1:&运算符默认返回是int的,不会因为你多加0而变成其他的类型。既然是int的,4个字节。那么你移位的时候最多可能要左移56字节
      

  19.   

    iOutcome += ((long) (bLoop & 0xff)) << (8 * i);写成它也是一样的
      

  20.   

    1:把int赋值给long应改是没有问题的。不用强制转换。
    2:你这样移位大于32字节的时候是错误的,用Math.pow()吧。
    3:就像楼上所说的应该最后有几字节是0的,但你的数据转换以后是很大很大很大的年份。
    4:我猜delphi和java可能得出的时间不是一个单位(delphi是微秒?java是毫秒),要不怎么会差这么多呢?要么就是数据错误?
      

  21.   

    数据肯定不会错的,问题的所在是因为: 通过查阅资料,发现两者对日期类型的定义略有不同。Java中日期使用的是长整型进行存储的,它表示距“1970-1-1”的毫秒数。如 “1970-1-2”是在“1970-1-1”后的86400000毫秒,所以Java中就使用86400000表示“1970-1-2”这个日期。由于长整型是带符号的,所以我们可以使用负的毫秒数来表示在“1970-1-1”之前的日期。而Delphi中的日期则是使用双精度类型进行存储的,整数部分表示距“1899-12-30”的天数,小数部分表示小时。如“2.75”这个数值则表示“1900-1-1 6:00PM”,“-1.25”则表示“1899-12-29 6:00 AM”。 
        由于两者的日期类型的起始日期不一样,即相同的“0”值在两者中表示不同的日期。那么在Java与Delphi之间进行日期值的通信时就需要进行一个转换。 -25,-43,-60,51,-114,125,-29,64 
    Delphi转换成double 是 39916.4438194444那么现在我只要把这个数组也转换成double得到 39916.4438194444然后在按照Delphi的时间方式解析
    就可以得到正确的时间了帖子刚加了100分,希望大家在帮帮忙
      

  22.   

    我就不写代码了,给你提供个思路吧。还是利用现成的,就是想办法把这个double变成long。怎么变呢?你既然知道这个double (39916.4438194444 )的意思,设他为d,那么你肯定能算出来d是多少毫秒,对不对?因为d代表的是天数和小时嘛,对吧?
    然后这个毫秒数设为t1,那么现在的问题就是把1970-1-2和1899-12-30这两个时间段的毫秒数算出来,那么设为t2.这样我们需要的long型整数就是t1+t2.
      

  23.   

    -25,-43,-60,51,-114,125,-29,64 
    Delphi转换成double 是 39916.4438194444 那么现在我只要把这个数组也转换成double得到 39916.4438194444然后在按照Delphi的时间方式解析 
    就可以得到正确的时间了 
    大家在帮帮忙
    答:将字节数组在JAVA中转成Double,这很方便。如:楼主的数据:
    -25,-43,-60,51,-114,125,-29,64 在JAVA中转成Double代码://按LITTLE-ENDIAN 方式读取b[],返回long
    public static long htol(byte[] b)
    { long l=
      (long)b[7]<<56L & 0xff00000000000000L |
      (long)b[6]<<48L & 0x00ff000000000000L |
      (long)b[5]<<40L & 0x0000ff0000000000L |
      (long)b[4]<<32L & 0x000000ff00000000L |
      (long)b[3]<<24L & 0x00000000ff000000L |
      (long)b[2]<<16L & 0x0000000000ff0000L |
      (long)b[1]<< 8L & 0x000000000000ff00L |
      (long)b[0]<< 0L & 0x00000000000000ffL ;
        return l;
    }
    //-25,-43,-60,51,-114,125,-29,64 
    byte[] bb1=new byte[8];
    bb1[0]=(byte)-25;
    bb1[1]=(byte)-43;
    bb1[2]=(byte)-60;
    bb1[3]=(byte)51;
    bb1[4]=(byte)-114;
    bb1[5]=(byte)125;
    bb1[6]=(byte)-29;
    bb1[7]=(byte)64; long ll=htol(bb1);
    System.out.println("JAVA double:"+Double.longBitsToDouble(ll));
    程序运行结果:
    JAVA double:39916.443819444445
      

  24.   

    答:上述 long htol(byte[] b)方法 就是网络字节次序转成小头的主机字节次序方法。
      

  25.   

    因为我不知道你的double小数部分具体是什么意思,所以在代码里注释掉了,你高清错加上就好了。所以这个程序是不精确的,当时基本已经没问题了,看输出,基本你的那个时间和应该输出的long型是一致的,所以完善下就好了。import java.util.*;
    import java.text.*;public class TimeExchange {
    final static long DAY_MILLS = 24*60*60*1000;
    final static long HOUR_MILLS = 60*60*1000;

    public static GregorianCalendar setTime(String str){
    try{
    SimpleDateFormat timeFormat = new SimpleDateFormat( "yyyy-MM-dd hh:mm:ss");
    Date date = timeFormat.parse(str);        
                
            date = new Date(date.getTime());
            GregorianCalendar calendar = new GregorianCalendar();      
            calendar.setTime(date);     
            return calendar;
    }catch (Exception e){
    System.err.println("Error!");
    }
    return new GregorianCalendar(Locale.CHINA);     
    }
    public static void main(String args[]){
    double t1 = 39916.4438194444;
    String str2 = "1899-12-30 00:00:00"; GregorianCalendar g2 = setTime(str2);

    long l = g2.getTimeInMillis();

    System.out.println(l);

    String[] time = (t1+"").split("\\."); long day = new Long(time[0]);
    long hour = new Long(time[1]);

    long t2 = day*DAY_MILLS;// + hour*HOUR_MILLS;

    System.out.println(t2);

    long t = (long)(l + t2);

    System.out.println(t);

    System.out.println(System.currentTimeMillis());
    }
    }
    结果:
    -2209136400000
    3448742400000
    1239606000000
    1239596141544
      

  26.   


    private static long ByteArraytoLong(byte[] b) {
    long iOutcome = 0;
    byte bLoop;
    for (int i = 0; i < 8; i++) {
    bLoop = b[i];
    iOutcome += ((long) (bLoop & 0xff)) << (8 * i);
    }
    return iOutcome;
    }

    public static void main(String[] args) {
     
    byte[] b=new byte[8];
    b[0]=-25;
    b[1]=-43;
    b[2]=-60;
    b[3]=51;
    b[4]=-114;
    b[5]=125;
    b[6]=-29;
    b[7]=64;

    Long lon=ByteArraytoLong(b);
    System.out.println(lon.doubleValue());
    System.out.println(Double.longBitsToDouble(lon));
    }
    输出:
    4.6757188878480722E18
    39916.443819444445这样更是方便一点,让我惭愧的是,我开始是用lon.doubleValue()来转成double,
    而不是用Double.longBitsToDouble()谢谢justinavril,jiangnaisong还有其他的热心帮助的人结贴去了