GRC
HR
SCM
CRM
BI


Article

 

Once Upon a Time in Java

by Thomas G. Schuessler | SAPinsider

April 1, 2002

by Thomas G. Schuessler, ARAsoft SAPinsider - 2002 (Volume 3), April (Issue 2)
 

In this article, I would like to discuss the use of BAPI date and time fields in Java using the SAP Java Connector (JCo).

SAP has two distinct data types to deal with date/time information:

  • Date: ABAP data type T is a 6-byte string with format HHMMSS.
  • Time: ABAP data type D is an 8-byte string with format YYYYMMDD.

Both data types are used in RFC-enabled Function Modules (RFMs), including the BAPIs. If a BAPI deals with a timestamp, then two fields, one of type D and one of type T, will be used.

Java, on the other hand, uses one class, Date, to represent both date and time information. Thus a timestamp can be represented in one variable.

JCo automatically converts between the ABAP and Java data types. Fields of ABAP data types D and T are represented as Java Date objects, leaving the unused portion of the Date object at its default value. It is up to the Java developer to know (by looking it up in SAP at design time or using a metadata server at runtime) whether a given field holds an SAP date or time value and to act accordingly.

Utility Methods

What if SAP sends a date and a time that belong together (a timestamp) and we want to combine the two fields into one Java Date object? When faced with this task for the first time, I found out that this takes a little more effort than I would have cared for1, so I decided to share the resulting code in Listing 1 with you (below).


import java.util.Date;
import com.sap.mw.jco.*;
import com.sap.mw.jco.util.SyncDateFormat;

  private static final SyncDateFormat dateISO =
    new SyncDateFormat("yyyy-MM-dd");
  private static final SyncDateFormat timeISO =
    new SyncDateFormat("HH:mm:ss");
  private static final SyncDateFormat dateTimeISO =
    new SyncDateFormat("yyyy-MM-ddHH:mm:ss");

  public static Date combineDateAndTime(Date date, Date time) {
    try {
      return dateTimeISO.parse(dateISO.format(date) +
                               timeISO.format(time));
    }
    catch (Exception ex) { return null; }
  }
  public static Date combineDateAndTime(JCO.Field date,
                                        JCO.Field time) {
    try {
      return combineDateAndTime(date.getDate(), time.getDate());
    }
    catch (Exception ex) { return null; }
  }
Listing 1 combineDateAndTime() Method

The reason we are using JCo’s own SyncDateFormat class here is that the standard java.text.SimpleDateFormat class (from which SyncDateFormat is derived) is not thread-safe, as SAP found out when doing massive parallel tests for JCo. We provide two flavors of combineDateAndTime() to make life more convenient for the developer.

There are several alternatives to the shown implementation, but be forewarned that the following code, tempting though it is due to its conciseness, actually returns incorrect values2:


    public static Date
        incorrectCombineDateAndTime
        (Date date, Date time) {
      return new Date(	
        date.getTime() + time.getTime());
}

Some readers have asked about a simple way of finding out the date and time in an SAP system. This can be quite different from the local time. Recently, I discovered a useful RFM in SAP that returns exactly the required information, called MSS_GET_SY_DATE_TIME. This RFM has no import parameters and returns a type D and a type T parameter, called SAPDATE and SAPTIME, respectively. The following source code encapsulates access to this RFM and makes use of the combineDateAndTime() method introduced above:


public static Date getSapDateAndTime
(JCO.Client connection,
IRepository repository)
throws Exception {
JCO.Function function =
repository.getFunctionTemplate
("MSS_GET_SY_DATE_TIME")
.getFunction();
connection.execute(function);
return
combineDateAndTime(
function.getExportParameterList()
.getField("SAPDATE"),
function.getExportParameterList()
.getField("SAPTIME"));
}

A related topic concerns finding the date format defined for a given userid in SAP. Using RFM RFC_GET_SAP_ SYSTEM_PARAMETERS allows you to find out this information, as well as other useful stuff (the decimal separator defined for the user, for example). Here is a method that you can use to retrieve the date format:


public static String getSapDateFormat
(JCO.Client connection,
IRepository repository)
throws Exception {
JCO.Function function =
repository.getFunctionTemplate
("RFC_GET_SAP_SYSTEM_PARAMETERS")
.getFunction();
connection.execute(function);
return
function.getExportParameterList()
.getString("DATE_FORMAT");
}

The resulting sample output for a user in Germany would look like this:

DD.MM.YYYY

The Throes of Conversion

The ABAP types D and T are somewhat lenient about what kinds of values they allow. While there are no dates 00000000 or 99999999 in the real world, ABAP accepts these values for type D fields. And some BAPIs return these values. Making them illegal in JCo in order to conform to Java’s more stringent requirements for Date objects would have prevented developers from using BAPIs that use strange dates.

Here are the details of how JCo deals with these special values: You can assign “00000000” and “99999999” (or “0000-00-00” and “9999-99-99”, if you prefer the ISO format) to a JCO.Field object using the setString() method. The getString() method will return “0000-00-00” or “9999-99-99”, respectively. The getDate() method will return null for “00000000” (there is no suitable date that Java would support) and 9999-12-31 for “99999999”.

More recently, several developers have registered complaints that JCo does not allow a time of “240000”. Our first reaction was that there is no such time. Java, for instance, will barf if you feed it that value. Then we learned that some BAPIs return or expect “240000” in a time (type T) field in certain cases. JCo uses standard date parsing functionality in Java and hence did not allow the use of “240000”. In order to support this special requirement, SAP decided to make the following changes in JCo 1.1.03 (available from http://service.sap.com/connectors):

  • The setValue() method now allows the strings “240000” as well as “24:00:00” for fields of ABAP type T.
  • The getString() method for type T fields will return this value as “24:00:00”.
  • The getDate() method will return a Date object with the time set to 23:59:59 instead, since Java will not accept 24:00:00.

Obviously, this is not a perfect solution, but the best we could come up with in order to avoid having to change all relevant BAPIs. (Unless you are using BAPIs with this special behavior, the change will not affect you.) The following sample code


JCO.Field f = 
function.getExportParameterList()
.getField("SAPTIME");
f.setValue("240000");
// or f.setValue("24:00:00");
System.out.println(f.getString());
System.out.println(f.getDate());

produces this output:

24:00:00
Thu Jan 01 23:59:59 GMT+01:00 1970

Have a good time!


1 Sun deprecated all the “nice” methods of class Date in JDK 1.1.

2 Unless you only use the GMT time zone.



Thomas G. Schuessler is the founder of ARAsoft (www.arasoft.de), a company offering products, consulting, custom development, and training to a worldwide base of customers. The company specializes in integration between SAP and non-SAP components and applications. ARAsoft offers various products for BAPI-enabled programs on the Windows and Java platforms. These products facilitate the development of desktop and Internet applications that communicate with R/3. Thomas is the author of SAP’s BIT525 “Developing BAPI-enabled Web Applications with Visual Basic” and BIT526 “Developing BAPI-enabled Web Applications with Java” classes, which he teaches in Germany and in English-speaking countries. Thomas is a regularly featured speaker at SAP TechEd and SAPPHIRE conferences. Prior to founding ARAsoft in 1993, he worked with SAP AG and SAP America for seven years. Thomas can be contacted at thomas.schuessler@sap.com or at tgs@arasoft.de.

An email has been sent to:






More from SAPinsider



COMMENTS

Please log in to post a comment.

No comments have been submitted on this article. Be the first to comment!


SAPinsider
FAQ