Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中人类可读格式的SNMP事件时间_Java_Snmp_Snmp4j - Fatal编程技术网

Java中人类可读格式的SNMP事件时间

Java中人类可读格式的SNMP事件时间,java,snmp,snmp4j,Java,Snmp,Snmp4j,我有一个独立的java应用程序,它通过SNMP陷阱接收SNMP消息。我在应用程序中使用SNMP4J库。在收到的SNMP消息中,我需要将事件时间字段(十六进制格式)转换为人类可读的格式。接收到的事件时间字段通常如下所示,例如: eventTime*SNMPv2-SMI::enterprises.193.183.4.1.4.5.1.7.0 = Hex-STRING: 07 DC 03 0C 12 15 2C 1F 2B 01 00 有人能告诉我如何在SNMP4J库的帮助下或不帮助下

我有一个独立的java应用程序,它通过SNMP陷阱接收SNMP消息。我在应用程序中使用SNMP4J库。在收到的SNMP消息中,我需要将事件时间字段(十六进制格式)转换为人类可读的格式。接收到的事件时间字段通常如下所示,例如:

      eventTime*SNMPv2-SMI::enterprises.193.183.4.1.4.5.1.7.0 = Hex-STRING: 
07 DC 03 0C 12 15 2C 1F 2B 01 00 

有人能告诉我如何在SNMP4J库的帮助下或不帮助下将文本“07 DC 03 0C 12 15 2C 1F 2B 01 00”转换为人类可读的日期时间值吗?谢谢。

你可以使用Integer.parseInt(“07dc”,16)和out 2012 pops,所以这应该能给你一个关于这一年的暗示,剩下的我相信你会自己弄清楚这是否真的是这一年。

可能有点晚了(你在6年前发布了你的问题)但我最近遇到了同样的问题,并找到了一个考虑到以下因素的通用解决方案:
1.SNMP回复可能报告也可能不报告与GMT的偏移量
2.如果报告时区,它可能与我们的本地时区不同

/**********************************************************************************************************************
 * Import definitions
 *********************************************************************************************************************/
import java.text.SimpleDateFormat;
import java.util.*;

/**********************************************************************************************************************
 * Class converting an SNMP DateAndTime into something readable.
 *********************************************************************************************************************/
public class ConvertDateAndTime
{
  /********************************************************************************************************************
   * This method converts the specified octet string into an array of bytes.
   * <br>The string should be a number of 2-char hexadecimal bytes values separated by any non-hexadecimal character.
   *
   * @param  value_ipar The value returned by the equipment.
   * @return            The value as an array of bytes.
   * @throws Exception  Thrown in case of an error
   *******************************************************************************************************************/
  public static int[] octetStringToBytes(String value_ipar)
  {
    // ---------------------------
    // Split string into its parts
    // ---------------------------
    String[] bytes;
    bytes = value_ipar.split("[^0-9A-Fa-f]");

    // -----------------
    // Initialize result
    // -----------------
    int[] result;
    result = new int[bytes.length];

    // -------------
    // Convert bytes
    // -------------
    int counter;
    for (counter = 0; counter < bytes.length; counter++)
      result[counter] = Integer.parseInt(bytes[counter], 16);

    // ----
    // Done
    // ----
    return (result);

  } // octetStringToBytes

  /********************************************************************************************************************
   * This method converts the 'DateAndTime' value as returned by the device into internal format.
   * <br>It returns <code>null</code> in case the reported year equals 0.
   * <br>It throws an exception in case of an error.
   *******************************************************************************************************************/
  public static Date octetStringToDate(String value_ipar)
    throws Exception
  {
    // ---------------------------
    // Convert into array of bytes
    // ---------------------------
    int[] bytes;
    bytes = octetStringToBytes(value_ipar);

    // -----------------------
    // Maybe nothing specified
    // -----------------------
    if (bytes[0] == 0)
      return (null);

    // ------------------
    // Extract parameters
    // ------------------
    int year;
    int month;
    int day;
    int hour;
    int minute;
    int second;
    int deci_sec = 0;
    int offset = 0;
    year = (bytes[0] * 256) + bytes[1];
    month = bytes[2];
    day = bytes[3];
    hour = bytes[4];
    minute = bytes[5];
    second = bytes[6];
    if (bytes.length >= 8)
      deci_sec = bytes[7];
    if (bytes.length >= 10)
    {
      offset = bytes[9] * 60;
      if (bytes.length >= 11)
        offset += bytes[10];
      if (bytes[8] == '-')
        offset = -offset;
      offset *= 60 * 1000;
    }

    // ------------------------------------
    // Get current DST and time zone offset
    // ------------------------------------
    Calendar calendar;
    int      my_dst;
    int      my_zone;
    calendar = Calendar.getInstance();
    my_dst = calendar.get(Calendar.DST_OFFSET);
    my_zone = calendar.get(Calendar.ZONE_OFFSET);

    // ----------------------------------
    // Compose result
    // Month to be converted into 0-based
    // ----------------------------------
    calendar.clear();
    calendar.set(Calendar.YEAR, year);
    calendar.set(Calendar.MONTH, month - 1);
    calendar.set(Calendar.DAY_OF_MONTH, day);
    calendar.set(Calendar.HOUR_OF_DAY, hour);
    calendar.set(Calendar.MINUTE, minute);
    calendar.set(Calendar.SECOND, second);
    calendar.set(Calendar.MILLISECOND, deci_sec * 100);

    // ---------
    // Reset DST
    // ---------
    calendar.add(Calendar.MILLISECOND, my_dst);

    // -----------------------------------------------------------------------------------
    // If the offset is set, we have to convert the time using the offset of our time zone
    // -----------------------------------------------------------------------------------
    if (offset != 0)
    {
      int delta;
      delta = my_zone - offset;
      calendar.add(Calendar.MILLISECOND, delta);
    }

    // -------------
    // Return result
    // -------------
    return (calendar.getTime());

  } // octetStringToDate

  /********************************************************************************************************************
   *                                               M A I N
   *******************************************************************************************************************/
  public static void main(String[] args)
  {
    try
    {
      SimpleDateFormat format;
      format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz");

      Date result;
      result = octetStringToDate("07 E2 02 02 12 0C 27 00"); // 18:12 in local time zone
      System.out.println(format.format(result)); // "2018-02-02 18:12:39 CET"

      result = octetStringToDate("07 E2 02 02 12 0C 27 00 2B 08 00"); // 18:12+08:00
      System.out.println(format.format(result)); // "2018-02-02 11:12:39 CET"

      result = octetStringToDate("07 E2 02 02 12 0C 27 00 2D 04 00"); // 18:12-04:00
      System.out.println(format.format(result)); // "2018-02-02 23:12:39 CET"

    }
    catch (Exception exception_ipar)
    {
      exception_ipar.printStackTrace();
    }

  } // main

} // class ConvertDateAndTime

我使用java.time(现代java日期和时间API)提供现代答案

十六进制字符串由以下字段组成:

Field  Octets  Contents                          Range
------------------------------------------------------
  1     1-2    year                           0..65536
  2      3     month                             1..12
  3      4     day                               1..31
  4      5     hour                              0..23
  5      6     minutes                           0..59
  6      7     seconds (use 60 for leap-second)  0..60
  7      8     deci-seconds                       0..9
  8      9     direction from UTC            '+' / '-'
  9     10     hours from UTC                    0..13
 10     11     minutes from UTC                  0..59
我在回答一个重复的问题时写了这个答案,其中示例SNMP事件时间字符串是
07e4070e04032b
。所以我假设一个十六进制字符串,字节之间没有空格。从Robert Koch的回答和重复的问题来看,似乎并非所有11个字节都需要存在(示例字符串为7个字节长)。所以我的转换需要考虑长度6,7,8,10和11

public static Temporal decodeSnmpEventTime(String snmpEventTimeString) {
    if (snmpEventTimeString.length() % 2 != 0) {
        throw new IllegalArgumentException("Not a valid byte string, must have even length");
    }
    if (snmpEventTimeString.startsWith("00")
            || snmpEventTimeString.charAt(0) > '7') {
        throw new IllegalArgumentException(
                "This simple implementation cannot handle years before year 256 nor after 32767;"
                            + " we need a different conversion to bytes"); 
    }
    
    byte[] bytes = new BigInteger(snmpEventTimeString, 16).toByteArray();
    
    int year = (bytes[0] & 0xFF) * 0x100 + (bytes[1] & 0xFF);
    int month = bytes[2] & 0xFF;
    checkRange(month, 1, 12);
    int dayOfMonth = bytes[3] & 0xFF;
    checkRange(dayOfMonth, 1, 31);
    int hour = bytes[4] & 0xFF;
    checkRange(hour, 0, 23);
    int minute = bytes[5] & 0xFF;
    checkRange(minute, 0, 59);
    int second = 0;
    int deciseconds = 0;
    if (bytes.length >= 7) {
        second = bytes[6] & 0xFF;
        checkRange(second, 0, 60); // 60 will cause conversion to fail, though 
        
        if (bytes.length >= 8) {
            deciseconds = bytes[7] & 0xFF;
            checkRange(deciseconds, 0, 9);
        }
    }

    LocalDateTime ldt = LocalDateTime.of(year, month, dayOfMonth,
            hour, minute, second, deciseconds * 100_000_000);

    if (bytes.length >= 9) { // there’s an offset
        char offsetSign = (char) (bytes[8] & 0xFF);
        int offsetHours = bytes[9] & 0xFF;
        checkRange(offsetHours, 0, 13); // allow 14 for all modern offsets
        int offsetMinutes = 0;
        if (bytes.length >= 11) {
            offsetMinutes = bytes[10] & 0xFF;
            checkRange(offsetMinutes, 0, 59);
        }
        
        ZoneOffset offset;
        if (offsetSign == '+') {
            offset = ZoneOffset.ofHoursMinutes(offsetHours, offsetMinutes);
        } else if (offsetSign == '-') {
            offset = ZoneOffset.ofHoursMinutes(-offsetHours, -offsetMinutes);
        } else {
            throw new IllegalArgumentException("Offset sign must be + or -, was " + offsetSign);
        }
        
        return ldt.atOffset(offset);
    } else {
        return ldt;
    }
}

private static void checkRange(int value, int min, int max) {
    if (value < min || value > max) {
        throw new IllegalArgumentException("Value " + value + " out of range " + min + ".." + max);
    }
}
输出为:

2020-07-14T04:03:43

链接
  • 重复问题:
  • 解释如何使用java.time

更准确地说,我需要从这个十六进制数字序列中获取java.util.Date对象。我想知道是否有办法做到这一点;字符串eventTime=gettimestampassext(tmp);私有同步字符串gettimestampassext(String[]strArray){String hyear,hmonth,hday,hhour,hmin,hmil;int-dyear,dmonth,dday,dhour,dmin,dmil;hyear=strArray[0]+strArray[1];hmonth=strArray[2];hday=strArray[3];hhour=strArray[4];hmin=strArray[5];hmil=strArray[5][6] ;dyear=Integer.parseInt(hyear,16);dmmonth=Integer.parseInt(hmmonth,16);dday=Integer.parseInt(hday,16);dhour=Integer.parseInt(hhour,16);dmin=Integer.parseInt(hmin,16);返回dyear+“-”+dmmonth+“-”+dday+“”+dhour+”:“+dmin+”:“+dmil;}@Fardaarda为什么不创建一篇新文章,而不是将代码作为注释键入?
    String snmpEventTimeString = "07e4070e04032b";
    Temporal dateTime = decodeSnmpEventTime(snmpEventTimeString);
    System.out.println(dateTime);